[comp.sources.x] v03i077: Xcu -- widget set from Cornell University, Part01/12

argv@island.uu.net (Dan Heller) (04/25/89)

Submitted-by: Gene Dykes <sun!tcgould.tn.cornell.edu!gdykes>
Posting-number: Volume 3, Issue 77
Archive-name: xcu/part01

[ Due to lack of time and resources, I have not had a chance to compile
  and run this.  However, I have had a close communication with Gene on 
  Sun-specific issues and other X-related topics, so I have faith that
  it should check out ok.  Two files in the src tree were too big to fit
  into an archive, so I had to split them up.  You'll need to push them
  back together.  The files are src/CuTbl.c and src/CuWlm.c (they will
  unpack as src/CuTbl.c.aa, CuTbl.c.ab, etc...)  Just type:
    % cd src
    % cat CuTbl.c.a? > CuTbl.c
    % cat CuWlm.c.a? > CuWlm.c
  The rest of the text before the first shar is the introductory notes
  provided by Gene.  There were some ^G's in the man pages so beware of
  that for sites which don't allow such chars thru their mailers. --argv ]

-----Introductory notes-----

This posting contains version 1.0 of the Cornell University Widget Set, Xcu.

Xcu contains the following:

    two geometry manager widgets, one of which, tbl, is a very
    powerful method of laying out a fixed number of widgets according to
    'tbl' formats (the troff preprocessor).

    a rework of the Xaw Simple/Label/Command widgets.  New features include
    3D picture frames and shadows and multiple lines of text permitted.

    a button manager widget that handles the semantics of groups of buttons,
    but leaves the layout to a separate geometry manager.  This permits
    one geometry manager to govern the layout of multiple groups of buttons,
    or, conversely, one group of buttons to be under the control of multiple
    geometry managers.

    a widget layout manager widget.  This widget reads a layout description
    language and automatically constructs a widget tree.  The description
    language also contains many useful notations for inter-widget
    communication and handling of many activities normally requiring
    callbacks.  With this widget and the previewer contained in one of the
    examples, complex menus can be designed and debugged without writing,
    compiling, or linking a line of application code.

    lots of documentation, lots of examples, and an as yet unreleased
    intrinsics bug fix
#! /bin/sh
# This is a shell archive.  Remove anything before this line, then feed it
# into a shell via "sh file" or similar.  To overwrite existing files,
# type "sh file -c".
# The tool that generated this appeared in the comp.sources.unix newsgroup;
# send mail to comp-sources-unix@uunet.uu.net if you want that tool.
# If this archive is complete, you will see the following message at the end:
#		"End of archive 1 (of 12)."
# Contents:  Geometry Imakefile README.bugs README.make README.tbl
#   README.widgets bin doc examples examples/xcursors examples/xlayout
#   examples/xtbl examples/xwlm examples/xworld man src src/CuDeck.c
#   src/CuTbl.c.ac wlmCompiler
# Wrapped by argv@island on Mon Apr 24 15:41:19 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test ! -d 'Geometry' ; then
    echo shar: Creating directory \"'Geometry'\"
    mkdir 'Geometry'
fi
if test -f 'Imakefile' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'Imakefile'\"
else
echo shar: Extracting \"'Imakefile'\" \(161 characters\)
sed "s/^X//" >'Imakefile' <<'END_OF_FILE'
X#define IHaveSubdirs
X#define PassCDebugFlags 'CDEBUGFLAGS=$(CDEBUGFLAGS)'
X
XSUBDIRS = src wlmCompiler examples
X
XMakeSubdirs($(SUBDIRS))
XDependSubdirs($(SUBDIRS))

END_OF_FILE
echo shar: NEWLINE appended to \"'Imakefile'\"
if test 162 -ne `wc -c <'Imakefile'`; then
    echo shar: \"'Imakefile'\" unpacked with wrong size!
fi
# end of 'Imakefile'
fi
if test -f 'README.bugs' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README.bugs'\"
else
echo shar: Extracting \"'README.bugs'\" \(323 characters\)
sed "s/^X//" >'README.bugs' <<'END_OF_FILE'
XIf you encounter bugs, please mail me a bug-report on one of the X bug
Xreport forms.  Make sure you mail it to me, not to MIT!
X
XNot only bugs, of course, but any suggestions you might have for
Xnew features, better documentation, error messages, etc., would
Xbe greatly appreciated.
X
X	gwd@freedom.tn.cornell.edu (Gene Dykes)

END_OF_FILE
echo shar: NEWLINE appended to \"'README.bugs'\"
if test 324 -ne `wc -c <'README.bugs'`; then
    echo shar: \"'README.bugs'\" unpacked with wrong size!
fi
# end of 'README.bugs'
fi
if test -f 'README.make' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README.make'\"
else
echo shar: Extracting \"'README.make'\" \(1606 characters\)
sed "s/^X//" >'README.make' <<'END_OF_FILE'
XThis is Version 1.0 of the Xcu Widget Set.
XThe Xcu Widget Set is based on the R3 intrinsics.
X
XThis distribution should make easily within the X source tree.
XFor those of you without that luxury, you probably are familiar
Xwith the difficulties involved.  I'm not :-)
X
XTo Make:
X   1) need to make a top level Makefile from the Imakefile.
X   2) make Makefiles
X   3) make 
X
XTo help struggling beginners,
Xfor what it's worth, I would do it this way:
X
X    Untar the distribution into the directory $(TOP)/lib/Xcu.
X
X    Then to make the Makefile from Imakefile, use the command:
X	../../util/imake/imake -DTOPDIR=../.. \
X	-T ../../util/imake.includes/Imake.tmpl -s Makefile
X
XAfter making, see the README's in examples/* to run the test programs.
X
XThere are seven subdirectories in this directory: man, src, bin, doc,
Xexamples, wlmCompiler, and Geometry.
X
X    Subdirectory "examples" contains test program subdirectories.
X
X    Subdirectory "src" contains widgets, resource converters,
X    and utility routines.
X
X    Subdirectory "man" contains manuals in troff format.
X
X    Subdirectory "doc" contains a tutorial and a "hello, world" example
X    for the CuWlm Widget Layout Manager widget.
X
X    Subdirectory "wlmCompiler" contains the Widget Layout Description Language
X    Compiler required for using the CuWlm widget.
X
X    Subdirectory "bin" contains some executable scripts useful for Makefiles
X    that use the CuWlm widget.
X
X    Subdirectory "Geometry" contains a bug fix for the intrinsics routine,
X    XtMakeGeometryRequest().  The xtbl demonstrations will not work
X    properly without patching this bug.
X
X

END_OF_FILE
echo shar: NEWLINE appended to \"'README.make'\"
if test 1607 -ne `wc -c <'README.make'`; then
    echo shar: \"'README.make'\" unpacked with wrong size!
fi
# end of 'README.make'
fi
if test -f 'README.tbl' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README.tbl'\"
else
echo shar: Extracting \"'README.tbl'\" \(2249 characters\)
sed "s/^X//" >'README.tbl' <<'END_OF_FILE'
XCuTbl is a geometry manager that lays out a fixed number of widgets
Xaccording to a specification patterned after the "tbl" preprocessor
Xfor creating tables in documents.  Thus, to get a bunch of widgets
Xto look like this:
X
X                     --------------------- ----------
X                    |                     |          |
X                    |                     |          |
X                    |                     |          |
X                    |---------- ----------|          |
X                    |          |          |          |
X                    |          |          |          |
X                    |          |          |          |
X                     ---------- ---------- ----------
X
XThe "tbl" input specification would look like this:
X
X                                   c s c
X                                   c c ^.
X
XThis is just a very simple example.  Actually, the widget is loaded up
Xwith lots of bells and whistles, such as the ability to specify
Xequal sized columns and/or rows, left, right, or center justify the strings
Xof the children widgets when they contain newlines (assuming the children can
Xhandle such a request, which the accompanying label widget, "CuLabel", does),
Xand certain widgets can be marked to "take up the slack" when adjusting the
Xchildren to fit into the layout. The widget resizes elegantly (it allows
Xresize requests from the children), looking at resources to determine whether
Xthe widgets, the internal padding, or the inter-child padding (or any
Xcombination of the three) adjust to fit the layout into the new size.
X
XSince an "m by n" layout array of widgets is a simple subset of this widget's
Xcapabilities, I have made it easy to subclass a widget that accepts a different
Xinput specification and merely transforms it into a tbl specification.  For
Xexample, the derived widget "CuRc" transforms "2 x 2" into "c c\nc c.".
X
XCuRc is a geometry manager subclassed from CuTbl.  It is a trivial example
Xof a CuTbl subclass and is not meant to do anything very useful.
X
XWarning: CuTbl will often produce funny results because of a bug in the
XXtMakeGeometryRequest() routine in the intrinsics file Geometry.c.
XA fix can be found in the "Geometry" subdirectory of this distribution.
X

END_OF_FILE
echo shar: NEWLINE appended to \"'README.tbl'\"
if test 2250 -ne `wc -c <'README.tbl'`; then
    echo shar: \"'README.tbl'\" unpacked with wrong size!
fi
# end of 'README.tbl'
fi
if test -f 'README.widgets' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'README.widgets'\"
else
echo shar: Extracting \"'README.widgets'\" \(2598 characters\)
sed "s/^X//" >'README.widgets' <<'END_OF_FILE'
XThe Xcu widget set contains the following widgets:
X
X
XTwo Geometry Manager Widgets :
X
X  CuTbl
X
X    Layout according to "tbl" formats (the troff preprocessor).
X    It is very effective for laying out a fixed number of widgets
X    in a rectangular area.  Simple row/column matrices
X    are a small subset of its capabilities.
X    Handles resizes (from above and below) very elegantly.
X
X  CuDeck
X
X    Maintain widgets one on top of the other, so that they are all the
X    same size and only one is visible at a time.  Useful for "pages"
X    of a menu.
X
X
XA rework of the Xaw Simple/Label/Command widgets :
X
X  CuSimple
X    
X    Puts very nice looking picture frames around widgets subclassed from it.
X    Alternately, puts a shadow behind derived widgets.
X    Permits cursor color control.
X
X  CuLabel
X    
X    Permits multiple lines of text with left, center, or right justification.
X    Has a "biggestLabel" resource that lets it be initially sized large
X    enough to encompass any reasonable text changes without annoying resizes.
X    Has a gravity resource.
X
X  CuCommand
X    
X    No new features -- just rederived from the above.
X
X
XA button manager widget :
X
X  CuBmgr
X    
X    This button manager divorces layout semantics from the button
X    semantics.  It is not a geometry manager.  CuButton widgets are
X    registered with it via public routines.  This is a big win when
X    semantically associated buttons must be spread out among a variety
X    of geometry managers, or, conversely, there must be a number of
X    different kinds of buttons under the layout control of a single
X    geometry manager.  It understands single and double button toggles, 
X    one of many, any of many, etc.
X
X  CuButton
X    
X    Similar to the Command widget, but it is tailored for use with
X    the CuBmgr widget.  The primary difference is that it relies on
X    the CuBmgr widget to inform it of its state.
X
X
XAnd last, but definitely not least (more than 5500 lines of source code) :
X
X  CuWlm
X
X    This is a widget that builds a widget tree from a layout description
X    language and mediates many of the widget/client communications.
X    Once you get used to it you'll never want to live without it.
X    Menus can be designed, tested, and modified without writing a
X    single line of client code.  The description language has
X    notations for inter-widget communications that permit complex
X    menu semantics to be implemented completely ouside of the client.
X
X    Do not dismiss this just because it sounds
X    something like what DEC is doing with UIL -
X    CuWlm does lots of useful things that UIL doesn't.

END_OF_FILE
echo shar: NEWLINE appended to \"'README.widgets'\"
if test 2599 -ne `wc -c <'README.widgets'`; then
    echo shar: \"'README.widgets'\" unpacked with wrong size!
fi
# end of 'README.widgets'
fi
if test ! -d 'bin' ; then
    echo shar: Creating directory \"'bin'\"
    mkdir 'bin'
fi
if test ! -d 'doc' ; then
    echo shar: Creating directory \"'doc'\"
    mkdir 'doc'
fi
if test ! -d 'examples' ; then
    echo shar: Creating directory \"'examples'\"
    mkdir 'examples'
fi
if test ! -d 'examples/xcursors' ; then
    echo shar: Creating directory \"'examples/xcursors'\"
    mkdir 'examples/xcursors'
fi
if test ! -d 'examples/xlayout' ; then
    echo shar: Creating directory \"'examples/xlayout'\"
    mkdir 'examples/xlayout'
fi
if test ! -d 'examples/xtbl' ; then
    echo shar: Creating directory \"'examples/xtbl'\"
    mkdir 'examples/xtbl'
fi
if test ! -d 'examples/xwlm' ; then
    echo shar: Creating directory \"'examples/xwlm'\"
    mkdir 'examples/xwlm'
fi
if test ! -d 'examples/xworld' ; then
    echo shar: Creating directory \"'examples/xworld'\"
    mkdir 'examples/xworld'
fi
if test ! -d 'man' ; then
    echo shar: Creating directory \"'man'\"
    mkdir 'man'
fi
if test ! -d 'src' ; then
    echo shar: Creating directory \"'src'\"
    mkdir 'src'
fi
if test -f 'src/CuDeck.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/CuDeck.c'\"
else
echo shar: Extracting \"'src/CuDeck.c'\" \(26966 characters\)
sed "s/^X//" >'src/CuDeck.c' <<'END_OF_FILE'
X/* *
X * * This code is completely original.  Permission is granted to do with
X * * it as one wishes.  I disclaim any responsibility whatsoever for
X * * any bad things that may happen because of using it.
X * */
X
X/*
X * CuDeck widget
X */
X
X#include <X11/Xos.h>
X#include <sys/stat.h>
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X#include <X11/Cardinals.h>
X#include "CuDeckP.h"
X
X/* Private Definitions */
X
X/*
X * defaults for resources
X */
X
Xstatic int     def_zero =  0 ;
X
X/*
X * resource declarations
X */
X
X#define offset(field) XtOffset(CuDeckWidget, field)
X#define Offset(field) XtOffset(CuDeckWidget, deck.field)
X
Xstatic CuResizeParticipants def_participants =
X       CuResizeInters | CuResizeChildren ;
X
Xstatic XtResource resources[] =
X{
X     {XtNinternalWidth,      XtCWidth,   XtRInt,  sizeof(int),
X      Offset(internal_width),XtRInt,	(caddr_t) &def_zero}
X
X    ,{XtNinternalHeight,     XtCHeight,  XtRInt, sizeof(int),
X      Offset(internal_height),XtRInt,	(caddr_t) &def_zero}
X
X    ,{XtNresizeParticipants, XtCHeight,  XtRInt, sizeof(CuResizeParticipants),
X      Offset(resize_participants),XtRInt, (caddr_t) &def_participants}
X
X    ,{XtNcallback, XtCCallback, XtRCallback, sizeof(caddr_t), 
X      Offset(callbacks), XtRCallback, (caddr_t)NULL}
X
X    /* UNDOCUMENTED FEATURE
X       procedureList is not documented in the manual because it is probably
X       only useful to the CuWlm widget! */
X
X    ,{XtNprocedureList, XtCProcedureList,
X      XtRProcedureList, sizeof(XtProcedureList *),
X      Offset(procedure_list), XtRProcedureList, (caddr_t)NULL}
X} ;
X
X#undef Offset
X#undef offset
X
X/* Declarations of "toolkit" calls */
X
Xstatic void		ChangeManaged () ;
Xstatic void		ClassInitialize () ;
Xstatic void		Initialize () ;
Xstatic void		Resize () ;
Xstatic Boolean		SetValues () ;
Xstatic XtGeometryResult	GeometryManager () ;
Xstatic XtGeometryResult QueryGeometry () ;
Xstatic void		Destroy () ;
X
X/* Declarations of "private" calls */
X
Xstatic void		Trial_STS() ;
Xstatic void		Trial_ETS () ;
Xstatic void		DoLayout () ;
Xstatic void		alloc_wh () ;
Xstatic void		free_wh () ;
Xstatic void		init_order () ;
Xstatic int		child_to_i () ;
X
X/* Declarations of "public" calls */
X
Xvoid CuDeckRaiseLowest () ;
Xvoid CuDeckLowerHighest () ;
Xvoid CuDeckRaiseWidget () ;
X
X/*
X * Class Record Constant
X */
X
XCuDeckClassRec cuDeckClassRec =
X{
X  { /* core_class fields */
X    /* superclass         */    (WidgetClass) &compositeClassRec,
X    /* class_name         */    "CuDeck",
X    /* widget_size        */    sizeof(CuDeckRec),
X    /* class_initialize   */    ClassInitialize,
X    /* class_part_init    */    NULL,
X    /* class_inited       */    False,
X    /* initialize         */    Initialize,
X    /* initialize_hook    */    NULL,
X    /* realize            */    XtInheritRealize,
X    /* actions            */    NULL,
X    /* num_actions        */    0,
X    /* resources          */    resources,
X    /* num_resources      */    XtNumber(resources),
X    /* xrm_class          */    NULLQUARK,
X    /* compress_motion    */    True,
X    /* compress_exposure  */    True,
X    /* compress_enterleave*/    True,
X    /* visible_interest   */    False,
X    /* destroy            */    Destroy,
X    /* resize             */    Resize,
X    /* expose             */    NULL,
X    /* set_values         */    SetValues,
X    /* set_values_hook    */    NULL,
X    /* set_values_almost  */    XtInheritSetValuesAlmost,
X    /* get_values_hook    */    NULL,
X    /* accept_focus       */    NULL,
X    /* version            */    XtVersion,
X    /* callback_private   */    NULL,
X    /* tm_table           */    NULL,
X    /* query_geometry	  */	QueryGeometry,
X    /* display_accelerator*/	XtInheritDisplayAccelerator,
X    /* extension	  */	NULL,
X  },
X  { /* composite_class fields */
X    /* geometry_manager   */   GeometryManager,
X    /* change_managed     */   ChangeManaged,
X    /* insert_child       */   XtInheritInsertChild,
X    /* delete_child       */   XtInheritDeleteChild,
X    /* extension 	  */   NULL,
X  },
X  { /* deck_class fields   */
X    /* no entries   */   NULL
X  }
X} ;
X
X/*
X * Class Record Pointer
X */
X
XWidgetClass cuDeckWidgetClass = (WidgetClass) &cuDeckClassRec ;
X
X/**
X ***
X **** Toolkit Callable Procedures
X ***
X **/
X
X/***** **** *** ** * ClassInitialize * ** *** **** *****/
X
Xstatic void
XClassInitialize ()
X{
X/*
X * Register converters that might be needed
X */
X
XCuAddStringToResizeParticipantsConverter () ;
X
Xreturn ;
X}
X
X/***** **** *** ** * Initialize * ** *** **** *****/
X
Xstatic void
XInitialize (request, new)
X    Widget request, new ;
X{
XCuDeckWidget dw = (CuDeckWidget) new ;
Xstatic String CuDeckRaiseWidgetText = "RaiseWidget" ;
Xstatic String CuDeckRaiseLowestText = "RaiseLowest" ;
Xstatic String CuDeckLowerHighestText = "LowerHighest" ;
X
X/*
X * allocate space for and copy resources specified by address
X * (none for deck)
X */
X
X
X/*
X * Initialize some non-resource fields
X */
X
Xdw->deck.order = NULL ;
Xdw->deck.width = NULL ;
Xdw->deck.height = NULL ;
Xdw->deck.procedure_list = (XtProcedureList *)
X			   XtMalloc (4 * sizeof (XtProcedureList)) ;
Xdw->deck.procedure_list[0].name = CuDeckRaiseLowestText ;
Xdw->deck.procedure_list[0].procedure = CuDeckRaiseLowest ;
Xdw->deck.procedure_list[1].name = CuDeckLowerHighestText ;
Xdw->deck.procedure_list[1].procedure = CuDeckLowerHighest ;
Xdw->deck.procedure_list[2].name = CuDeckRaiseWidgetText ;
Xdw->deck.procedure_list[2].procedure = CuDeckRaiseWidget ;
Xdw->deck.procedure_list[3].name = NULL ;
Xdw->deck.procedure_list[3].procedure = NULL ;
X
Xreturn ;
X}
X
X/***** **** *** ** * Destroy * ** *** **** *****/
X
Xstatic void
XDestroy (widget)
X    Widget widget ;
X{
XCuDeckWidget dw = (CuDeckWidget) widget ;
X
X/*
X * free dynamically allocated data
X */
X
Xfree_wh (dw) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * Resize * ** *** **** *****/
X
Xstatic void
XResize (w)
X    Widget w ;
X{
X/*
X * Determine the new sizes and positions imposed by the resize
X */
X
XTrial_STS ((CuDeckWidget) w, (Widget) NULL) ;
XTrial_ETS ((CuDeckWidget) w) ;
XDoLayout ((CuDeckWidget) w, (Widget) NULL) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * GeometryManager * ** *** **** *****/
X
Xstatic
XXtGeometryResult
XGeometryManager (w, request, reply)
X    Widget w ;
X    XtWidgetGeometry *request ;
X    XtWidgetGeometry *reply;	/* RETURN */
X{
XCardinal i ;
XXtGeometryResult parent_result;
XXtWidgetGeometry allowed ;
XCuDeckWidget dw = (CuDeckWidget) w->core.parent ;
XDimension save_child_width = w->core.width ;
XDimension save_child_height = w->core.height ;
XDimension compromise_width, compromise_height ;
X
X/*
X * Look for identical request to a prior XtGeometryAlmost -- we have to grant
X */
X
Xif (
X   dw->deck.almost_status == True
X
X   &&
X
X   dw->deck.almost_widget == w
X   
X    &&
X
X   (((dw->deck.almost_mode & CWWidth) && 
X    (request->request_mode & CWWidth) && 
X    (dw->deck.almost_width == request->width))
X    ||
X    ((dw->deck.almost_mode & CWWidth) ==
X     (request->request_mode & CWWidth)))
X
X    &&
X
X   (((dw->deck.almost_mode & CWHeight) && 
X    (request->request_mode & CWHeight) && 
X    (dw->deck.almost_height == request->height))
X    ||
X    ((dw->deck.almost_mode & CWHeight) ==
X     (request->request_mode & CWHeight)))
X   )
X    {
X    /*
X     * Granting a request identical to my last Almost reply
X     */
X    w->core.x = dw->deck.almost_x ;
X    w->core.y = dw->deck.almost_y ;
X    w->core.width = request->width ;
X    w->core.height = request->height ;
X    w->core.border_width = request->border_width ;
X
X    Trial_STS ( dw, w ) ;
X    Trial_ETS ( dw ) ;
X    DoLayout  ( dw, w ) ;
X
X    dw->deck.almost_status = False ;
X    return XtGeometryYes ;
X    }
X
Xdw->deck.almost_status = False ;
X
X/*
X * Disallow only location requests from the children
X */
X
Xif ((request->request_mode & (CWWidth | CWHeight | CWStackMode | CWBorderWidth))
X    == 0)
X    {
X    return XtGeometryNo ;
X    }
X
X/*
X * See if anything is different
X */
X
Xif (request->request_mode & CWWidth)
X    allowed.width = request->width ;
Xelse
X    allowed.width = w->core.width ;
X
Xif (request->request_mode & CWHeight)
X    allowed.height = request->height ;
Xelse
X    allowed.height = w->core.height ;
X
Xif (request->request_mode & CWBorderWidth)
X    allowed.border_width = request->border_width ;
Xelse
X    allowed.border_width = w->core.border_width ;
X
X/*
X * If there really isn't anything to change, just say no
X */
X
Xif (allowed.width == w->core.width &&
X    allowed.height == w->core.height &&
X    allowed.border_width == w->core.border_width &&
X    (request->request_mode & CWStackMode) == 0)
X    {
X    return XtGeometryNo ;
X    }
X
Xif (request->request_mode & CWStackMode)
X    {
X    /* allow any stacking order request */
X    reply->request_mode = (CWStackMode | CWSibling) ;
X    reply->stack_mode = request->stack_mode ;
X    reply->sibling = request->sibling ;
X    }
X
Xif ((request->request_mode & (CWWidth | CWHeight | CWBorderWidth)) == 0)
X    {
X    return XtGeometryYes ;
X    }
X
X/*
X/*
X * We'll have to do a Trial_STS to see what the effects of the change are
X */
X
Xif (request->request_mode & CWWidth)
X    w->core.width = request->width ;
Xif (request->request_mode & CWHeight)
X    w->core.height = request->height ;
Xif (request->request_mode & CWBorderWidth)
X    w->core.border_width = request->border_width ;
XTrial_STS ( dw, w ) ;
X
X/*
X * Run this layout by my parent
X */
X
Xparent_result = XtMakeResizeRequest ((Widget)dw,
X			  (Dimension)dw->deck.standalone_width,
X			  (Dimension)dw->deck.standalone_height,
X			  &compromise_width,
X			  &compromise_height) ;
X
Xif (parent_result == XtGeometryAlmost)
X    {
X    /* We'll accept whatever compromise is offered */
X    XtMakeResizeRequest ((Widget)dw,
X		         compromise_width, compromise_height, NULL, NULL) ;
X    }
Xelse
Xif (parent_result == XtGeometryYes)
X    {
X    }
Xelse
X    {
X    w->core.width = save_child_width ;
X    w->core.height = save_child_height ;
X    return XtGeometryNo ;
X    }
X
X/*
X * Now we have to do a trial enclosed layout on the approved size
X */
X
XTrial_ETS ( dw ) ;
X
Xi = child_to_i (dw, w) ;
Xif ( /* checking for nothing changed */
X     (
X     save_child_width == dw->deck.width[i] &&
X     (request->request_mode & CWWidth)
X     )
X     &&
X     (
X     save_child_height == dw->deck.height[i] &&
X     (request->request_mode & CWHeight)
X     )
X   )
X    {
X    w->core.width = save_child_width ;
X    w->core.height = save_child_height ;
X    return XtGeometryNo ;
X    }
X
Xreply->request_mode = 0 ;
X
Xif (w->core.width != dw->deck.width[i] &&
X    !(request->request_mode & CWWidth))
X    {
X    /* Need to change width even though it wasn't requested */
X    reply->request_mode |= CWWidth ;
X    }
X
Xif (w->core.height != dw->deck.height[i] &&
X    !(request->request_mode & CWWidth))
X    {
X    /* Need to change height even though it wasn't requested */
X    reply->request_mode |= CWHeight ;
X    }
X
Xif (
X   /* checking for changing width not as much as requested */
X     (request->request_mode & CWWidth)
X		   &&
X     (
X     request->width < dw->deck.width[i] &&
X		      dw->deck.width[i] < save_child_width ||
X     request->width > dw->deck.width[i] &&
X		      dw->deck.width[i] > save_child_width
X     )
X   )
X    {
X    /* Need to change width less than requested */
X    reply->request_mode |= CWWidth ;
X    }
X
Xif (
X   /* checking for changing height not as much as requested */
X     (request->request_mode & CWHeight)
X		   &&
X     (
X     request->height < dw->deck.height[i] &&
X		      dw->deck.height[i] < save_child_height ||
X     request->height > dw->deck.height[i] &&
X		      dw->deck.height[i] > save_child_height
X     )
X   )
X    {
X    /* Need to change height less than requested */
X    reply->request_mode |= CWHeight ;
X    }
X
Xif (reply->request_mode)
X    {
X    /*
X     * we'll return Almost.
X     */
X    w->core.width = save_child_width ;
X    w->core.height = save_child_height ;
X    dw->deck.almost_status = True ;
X    dw->deck.almost_width = reply->width = dw->deck.width[i] ;
X    dw->deck.almost_height = reply->height = dw->deck.height[i] ;
X    dw->deck.almost_x = reply->x = dw->deck.x[i] ;
X    dw->deck.almost_y = reply->y = dw->deck.y[i] ;
X    reply->border_width = dw->deck.border_width[i] ;
X
X    if (reply->x != w->core.x)
X	reply->request_mode |= CWX ;
X    if (reply->y != w->core.y)
X	reply->request_mode |= CWY ;
X    if (reply->border_width != w->core.border_width)
X	reply->request_mode |= CWBorderWidth ;
X
X    dw->deck.almost_widget = w ;
X    dw->deck.almost_mode = reply->request_mode ;
X    return XtGeometryAlmost ;
X    }
X
X/*
X * Actually do the layout
X */
X
Xif (!(request->request_mode & XtCWQueryOnly))
X    DoLayout ( dw, w ) ;
X
Xreturn XtGeometryYes ;
X}
X
X/***** **** *** ** * SetValues * ** *** **** *****/
X
Xstatic Boolean
XSetValues (current, request, new)
X    Widget current, request, new ;
X{
XCuDeckWidget cw = (CuDeckWidget) current ;
XCuDeckWidget nw = (CuDeckWidget) new ;
X
X/* Check for new border color */
X
Xif (cw->core.border_pixel != nw->core.border_pixel)
X    {
X    Mask changes_mask ;
X    XSetWindowAttributes changes ;
X
X    changes_mask = CWBorderPixel ;
X    changes.border_pixel = nw->core.border_pixel ;
X    if (XtIsRealized(current))
X	{
X	XChangeWindowAttributes (XtDisplay(current), XtWindow(current),
X				 changes_mask, &changes) ;
X	}
X    }
X
Xif (
X      cw->deck.internal_width != nw->deck.internal_width
X   || cw->deck.internal_height != nw->deck.internal_height
X   || cw->deck.resize_participants != nw->deck.resize_participants
X   )	
X	{
X	/*
X	 * If any of these has changed, need to relayout (if realized)
X	 */
X	if (XtIsRealized (current))
X	    {
X	    nw->core.width = 0 ;
X	    nw->core.height = 0 ;
X	    Trial_STS (nw, (Widget) NULL) ;
X	    Trial_ETS (nw) ;
X	    DoLayout (nw, (Widget) NULL) ;
X	    }
X	}
X
Xreturn False ;
X}
X
X/***** **** *** ** * ChangeManaged * ** *** **** *****/
X
X/*
X * ChangeManaged is called when there is a change in the set of children
X */
X
Xstatic void
XChangeManaged (w)
X    Widget w ;
X{
X/*
X *
X */
XCuDeckWidget dw = (CuDeckWidget) w ;
X
X/*
X * Need to maintain an ordered list of the children.
X * We'll have to do it ourselves.
X * X Doesn't seem to want to let us peek at the stacking order.
X */
X
Xinit_order (dw) ;
Xfree_wh (dw) ;
Xalloc_wh (dw) ;
XTrial_STS (dw, (Widget) NULL) ;
XTrial_ETS (dw) ;
XDoLayout (dw, (Widget) NULL) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * QueryGeometry * ** *** **** *****/
X
Xstatic
XXtGeometryResult
XQueryGeometry (widget, requested, preferred)
X    Widget widget;
X    XtWidgetGeometry *requested ;
X    XtWidgetGeometry *preferred ;
X{
X/*
X * Examine bits in requested->request_mode
X * Evaluate preferred geometry of the widget
X * Store the result in preferred, setting bits cared about in request_mode
X *  (CWX, CWY,  CWWidth, CWHeight,  CWBorderWidth,  CWSibling,  CWStackMode)
X *
X * acceptable without modification				XtGeometryYes
X *
X * one field in requested != one field in preferred ||
X * one bit set in preferred that is not set in requested	XtGeometryAlmost
X *
X * if preferred == current					XtGeometryNo
X */
X
XXtGeometryResult return_mode ;
XCuDeckWidget w = (CuDeckWidget) widget ;
Xpreferred->width = w->deck.standalone_width ;
Xpreferred->height = w->deck.standalone_height ;
Xpreferred->request_mode = (CWWidth | CWHeight) ;
X
Xif ((requested->request_mode & (CWWidth | CWHeight)) == 0)
X    {
X    /* parent isn't interested in anything we're interested in */
X    return XtGeometryYes;
X    }
X
Xif (
X    (
X     ((requested->request_mode & CWWidth) != 0 &&
X      preferred->width == requested->width)
X		    ||
X     ((requested->request_mode & CWWidth) == 0)
X    )
X		    &&
X    (
X     ((requested->request_mode & CWHeight) != 0 &&
X      preferred->height == requested->height)
X		    ||
X     ((requested->request_mode & CWHeight) == 0)
X    )
X   )
X    {
X    /* Our values already identical to those the parent is interested in */
X    return XtGeometryNo ;
X    }
X
X/*
X * That takes care of the simple cases, now we have to take a closer look...
X * I don't mind getting bigger than the smallest possible size.
X */
X
Xreturn_mode = XtGeometryYes ;
Xif (
X    (requested->request_mode & CWHeight) &&
X    (requested->height < preferred->height)
X   )
X    {
X    return_mode = XtGeometryAlmost ;
X    }
X
Xif (
X    (requested->request_mode & CWWidth) &&
X    (requested->width < preferred->width)
X   )
X    {
X    return_mode = XtGeometryAlmost ;
X    }
X
Xreturn return_mode ;
X}
X
X/**
X ***
X **** Private Procedures
X ***
X **/
X
X/***** **** *** ** * Trial_STS * ** *** **** *****/
X
X/*
X * The purpose of this function is to calculate the mimimum size of the deck
X */
X
Xstatic void
XTrial_STS (dw, w_requester)
X    CuDeckWidget dw ;
X    Widget w_requester ;
X{
XDimension deck_width ;
XDimension deck_height ;
Xint num_children = dw->composite.num_children;
XWidgetList children = dw->composite.children;
XCardinal i ;
X
X/*
X * Step 0 : Collect the widths and heights of each item
X */
X
Xdw->deck.standalone_width = 0 ;
Xdw->deck.standalone_height = 0 ;
X
Xfor (i=0;  i < num_children; i++)
X    {
X    Widget child = children[i] ;
X    if (!XtIsManaged(child))
X	continue ;
X    /*
X     * This is a bit tricky...
X     * (Supposedly a lot easier in R3)
X     * If the child has a new width and height because of a change in
X     * text, its parent widget's GeometryManager is called, and
X     * that's why we're here, now.  But, a call to QueryGeometry
X     * at this point will result in the child returning its OLD preferred
X     * geometry, since this Geometry manager was called with the old
X     * widget, with only the new x,y,width,height copied in.  So,
X     * I have to check for this situation and just grab the current width
X     * and height in this situation.
X     */
X    if (child == w_requester)
X	{
X	dw->deck.width[i] = child->core.width ;
X	dw->deck.height[i] = child->core.height ;
X	dw->deck.border_width[i] = child->core.border_width ;
X	}
X    else
X	{
X	XtWidgetGeometry preferred ;
X	XtQueryGeometry (child, NULL, &preferred) ;
X	dw->deck.width[i] = preferred.width ;
X	dw->deck.height[i] = preferred.height ;
X	dw->deck.border_width[i] = preferred.border_width ;
X	}
X
X    dw->deck.x[i] = dw->deck.internal_width ;
X    dw->deck.y[i] = dw->deck.internal_height ;
X    deck_width = dw->deck.width[i] + 2*dw->deck.border_width[i] +
X				     2*dw->deck.internal_width ;
X    deck_height = dw->deck.height[i] + 2*dw->deck.border_width[i] +
X				       2*dw->deck.internal_height ;
X
X    if (deck_width > dw->deck.standalone_width)
X	dw->deck.standalone_width = deck_width ;
X    if (deck_height > dw->deck.standalone_height)
X	dw->deck.standalone_height = deck_height ;
X    }
X
Xreturn ;
X}
X
X/***** **** *** ** * Trial_ETS * ** *** **** *****/
X
Xstatic void
XTrial_ETS (dw)
X    CuDeckWidget dw ;
X{
Xint c_slack ;  /* Can't be "Dimension" */
Xint r_slack ;
Xfloat c_expansion ;
Xfloat r_expansion ;
Xint internal_width = dw->deck.internal_width ;
Xint internal_height = dw->deck.internal_height ;
X
X/*
X * Given an enclosing box, figure out how to parcel the additional
X * padding among the children.   If there is instead a loss of padding,
X * things would look awful, so things are laid out in the smallest way that
X * I would like, and the parent will have to settle for us being clipped.
X *
X * Theoretically, I could reduce the padding to zero, and that might be
X * a good idea.
X * If more space is needed, make the children's fonts smaller, but that is
X *  carrying things just a bit too far.
X */
X
X/*
X * What are the possibilities for the proper effect of fitting within
X * a window that is larger than needed?
X *  1) Expand the children to take up the excess
X *  2) Expand the internalWidth,Height (centers the deck)
X *
X *  This code allows any combination of the above possibilities.
X *  (If no bits are set, the default is to expand the widgets)
X */
X
X/*
X * Compute how much bigger (the slack) than the minimum we are.
X */
X
X/* height */
X
Xif (dw->core.height == 0)
X    dw->core.height = dw->deck.standalone_height ;
X
Xdw->deck.new_height = (dw->core.height < dw->deck.standalone_height) ?
X	dw->deck.standalone_height : dw->core.height ;
X
Xr_expansion = (float) dw->deck.new_height / dw->deck.standalone_height ;
Xr_slack = dw->deck.new_height - dw->deck.standalone_height ;
X
X/* width */
X
Xif (dw->core.width == 0)
X    dw->core.width = dw->deck.standalone_width ;
X
Xdw->deck.new_width = (dw->core.width < dw->deck.standalone_width) ?
X	dw->deck.standalone_width : dw->core.width ;
X
Xc_expansion = (float) dw->deck.new_width / dw->deck.standalone_width ;
Xc_slack = dw->deck.new_width - dw->deck.standalone_width ;
X
X/*
X * Depending on what is allowed to change,
X * compute new padding parameters
X */
X
Xif ((int)dw->deck.resize_participants & (int)CuResizeInternals)
X    {
X    if (((int)dw->deck.resize_participants & (int)CuResizeChildren))
X	{
X	/* internal padding and children just expand proportionately */
X	internal_height = dw->deck.internal_height * r_expansion ;
X	r_slack -= 2 * (internal_height - dw->deck.internal_height) ;
X
X	internal_width = dw->deck.internal_width * c_expansion ;
X	c_slack -= 2 * (internal_width - dw->deck.internal_width) ;
X	}
X    else
X	{
X	/* internal padding takes up all the slack */
X	internal_height = dw->deck.internal_height + r_slack/2 ;
X	r_slack -= 2 * (internal_height - dw->deck.internal_height) ;
X
X	internal_width = dw->deck.internal_width + c_slack/2 ;
X	c_slack -= 2 * (internal_width - dw->deck.internal_width) ;
X	}
X    dw->deck.internal_width = internal_width ;
X    dw->deck.internal_height = internal_height ;
X    }
X
Xdw->deck.r_slack = r_slack ;
Xdw->deck.c_slack = c_slack ;
X
X/* all have x,y at internal_width,height... */
X
Xreturn ;
X}
X
X/***** **** *** ** * DoLayout * ** *** **** *****/
X
Xstatic void
XDoLayout (dw, requesting_widget)
X    CuDeckWidget dw ;
X    Widget requesting_widget ;
X{
XCardinal i ;
Xint num_children = dw->composite.num_children;
XWidgetList children = dw->composite.children;
X
X/* Use ConfigureWidget on siblings, modify requester directly */
X
Xfor (i=0; i < num_children; i++)
X    {
X    Widget child = children[i] ;
X
X    if (!XtIsManaged(child))
X	continue ;
X
X    if (child != requesting_widget)
X	{
X	XtConfigureWidget (child,
X		dw->deck.internal_width,
X		dw->deck.internal_height,
X		(Dimension)
X		    (dw->deck.new_width -
X		     2*dw->deck.internal_width -
X		     2*dw->deck.border_width[i]),
X		(Dimension)
X		    (dw->deck.new_height -
X		     2*dw->deck.internal_height -
X		     2*dw->deck.border_width[i]),
X		(Dimension) dw->deck.border_width[i]) ;
X	}
X    else
X	{
X	child->core.x = dw->deck.internal_width ;
X	child->core.y = dw->deck.internal_height ;
X	child->core.width = dw->deck.new_width - 2*dw->deck.internal_width -
X			    2*dw->deck.border_width[i] ;
X	child->core.height = dw->deck.new_height - 2*dw->deck.internal_height -
X			     2*dw->deck.border_width[i] ;
X	/*
X	 * Well, this (XtConfigureWidget) isn't supposed to be here, but
X	 * without it, the child's x & y never seem to be paid attention
X	 * to.  Width and height change, but the widget stays right where
X	 * it was...
X	 */
X	XtConfigureWidget (child, child->core.x, child->core.y,
X				    (Dimension) child->core.width,
X				    (Dimension) child->core.height,
X				    (Dimension) child->core.border_width) ;
X	}
X    }
X
Xdw->core.width = dw->deck.new_width ;
Xdw->core.height = dw->deck.new_height ;
X
Xreturn ;
X}
X
X/***** **** *** ** * alloc_wh * ** *** **** *****/
X
Xstatic void
Xalloc_wh (dw)
X    CuDeckWidget dw ;
X{
Xint num_children = dw->composite.num_children ;
Xdw->deck.x = (Position *) XtMalloc (num_children * sizeof (Position)) ;
Xdw->deck.y = (Position *) XtMalloc (num_children * sizeof (Position)) ;
Xdw->deck.width = (Dimension *) XtMalloc (num_children * sizeof (Dimension)) ;
Xdw->deck.height = (Dimension *) XtMalloc (num_children * sizeof (Dimension)) ;
Xdw->deck.border_width = (Dimension *) XtMalloc (num_children * sizeof (Dimension)) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * free_wh * ** *** **** *****/
X
Xstatic void
Xfree_wh (dw)
X    CuDeckWidget dw ;
X{
Xif (dw->deck.width) XtFree ((char *)dw->deck.width) ;
Xif (dw->deck.height) XtFree ((char *)dw->deck.height) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * child_to_i * ** *** **** *****/
X
X/*
X * Well, I guess this should have been a constrained widget !
X */
X
Xstatic int
Xchild_to_i (dw, w)
X    CuDeckWidget dw ;
X    Widget w ;
X{
XCardinal i ;
Xint num_children = dw->composite.num_children;
XWidgetList children = dw->composite.children;
X
Xfor (i=0;  i < num_children; i++)
X    {
X    Widget child = children[i] ;
X    if (child == w)
X	return i ;
X    }
Xreturn ; /* should never reach here... */
X}
X
X/***** **** *** ** * init_order * ** *** **** *****/
X
Xstatic void
Xinit_order (dw)
X    CuDeckWidget dw ;
X{
XCardinal i ;
Xif (dw->deck.order)
X    XtFree ((char *)dw->deck.order) ;
Xdw->deck.order = (Widget *)
X		 XtMalloc (dw->composite.num_children * sizeof (Widget)) ;
Xfor (i=0;  i < dw->composite.num_children;  i++)
X    {
X    dw->deck.order[i] = dw->composite.children[i] ;
X    }
Xreturn ;
X}
X
X/**
X ***
X **** Public Procedures
X ***
X **/
X
X/***** **** *** ** * CuDeckRaiseLowest * ** *** **** *****/
X
Xvoid
XCuDeckRaiseLowest (dw)
X    CuDeckWidget dw ;
X{
Xint i ; /* Must not be Cardinal */
XCardinal n = dw->composite.num_children ;
XWidget save ;
X
Xif (!XtIsSubclass ((Widget)dw, (WidgetClass)cuDeckWidgetClass)) {
X    XtError("CuDeckRaiseLowest requires a subclass of cuDeckWidgetClass");
X    }
XXCirculateSubwindows (XtDisplay((Widget)dw), XtWindow((Widget)dw),
X			RaiseLowest) ;
X
Xsave = dw->deck.order[n-1] ;
Xfor (i=n-1;  i >= 1;  i--)
X    dw->deck.order[i] = dw->deck.order[i-1] ;
Xdw->deck.order[0] = save ;
X
XXtCallCallbacks((Widget)dw, XtNcallback, dw->deck.order);
X
Xreturn ;
X}
X
X/***** **** *** ** * CuDeckLowerHighest * ** *** **** *****/
X
Xvoid
XCuDeckLowerHighest (dw)
X    CuDeckWidget dw ;
X{
XCardinal i ;
XCardinal n = dw->composite.num_children ;
XWidget save ;
X
Xif (!XtIsSubclass ((Widget)dw, (WidgetClass)cuDeckWidgetClass)) {
X    XtError("CuDeckLowerHighest requires a subclass of cuDeckWidgetClass");
X    }
XXCirculateSubwindows (XtDisplay((Widget)dw), XtWindow((Widget)dw),
X			LowerHighest) ;
X
Xsave = dw->deck.order[0] ;
Xfor (i=0;  i < n-1;  i++)
X    dw->deck.order[i] = dw->deck.order[i+1] ;
Xdw->deck.order[n-1] = save ;
X
XXtCallCallbacks((Widget)dw, XtNcallback, dw->deck.order);
X
Xreturn ;
X}
X
X/***** **** *** ** * CuDeckRaiseWidget * ** *** **** *****/
X
Xvoid
XCuDeckRaiseWidget (dw, to_be_raised)
X    CuDeckWidget dw ;
X    Widget to_be_raised ;
X{
Xint i ; /* Must not be Cardinal */
XCardinal n = dw->composite.num_children ;
XWidget save ;
X
Xif (!XtIsSubclass ((Widget)dw, (WidgetClass)cuDeckWidgetClass)) {
X    XtError("CuDeckRaiseWidget requires arg0 to be subclass of cuDeckWidgetClass");
X    }
XXRaiseWindow (XtDisplay((Widget)dw), XtWindow(to_be_raised)) ;
X
Xfor (i=0;  i < n;  i++)
X    {
X    if (dw->deck.order[i] == to_be_raised)
X	break ;
X    }
Xif (i == n)
X    {
X    char text[200] ;
X    WidgetClass class = XtClass(to_be_raised) ;
X    sprintf (text, "CuDeckRaiseWidget: Widget (%s/%s) not found in CuDeck\n",
X	     class->core_class.class_name, to_be_raised->core.name) ;
X    XtWarning (text) ;
X    }
Xelse
X    {
X    /* pull out the window, collapse part of the deck, store at top */
X    save = dw->deck.order[i] ;
X    for (  ;  i >= 1;  i--)
X	dw->deck.order[i] = dw->deck.order[i-1] ;
X    dw->deck.order[0] = save ;
X    }
X
XXtCallCallbacks((Widget)dw, XtNcallback, dw->deck.order);
X
Xreturn ;
X}
X

END_OF_FILE
echo shar: NEWLINE appended to \"'src/CuDeck.c'\"
if test 26967 -ne `wc -c <'src/CuDeck.c'`; then
    echo shar: \"'src/CuDeck.c'\" unpacked with wrong size!
fi
# end of 'src/CuDeck.c'
fi
if test -f 'src/CuTbl.c.ac' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/CuTbl.c.ac'\"
else
echo shar: Extracting \"'src/CuTbl.c.ac'\" \(14578 characters\)
sed "s/^X//" >'src/CuTbl.c.ac' <<'END_OF_FILE'
X    layout_input->string_file = (int) TBL_STRING_FORMAT ;
X    for (i=0;  i < tw->composite.num_children;  i++)
X	strcat (tw->tbl.format_string, " c") ;
X    strcat (tw->tbl.format_string, ".") ;
X    }
X
Xif (tw->tbl.format_mode != TBL_NO_FORMAT)
X    {
X    layout_input->input_buffer = 
X	(*((CuTblWidgetClass)XtClass((Widget)tw))->tbl_class.interpret_string)
X	(layout_input->input_buffer) ;
X    layout_input->input_pointer = 0 ;
X    layout_input->unput_pointer = 0 ;
X    layout_input->context_ptr = 0 ;
X    layout_input->line_number = 1 ;
X    layout_input->lnl_equivalent = -1 ;
X    layout_input->snl_equivalent = -1 ;
X    if (XtIsRealized ((Widget)tw))
X	{
X	Cardinal i ;
X	for (i=0;  i < tw->tbl.rows;  i++)
X	    {
X	    XtFree ((char *) tw->tbl.item[i]) ;
X	    tw->tbl.cols[i] = 0 ;
X	    }
X	}
X    tw->tbl.rows = 0 ;
X    tw->tbl.data_row = 0 ;
X    tw->tbl.n_cols = 0 ;
X    ParseTblLayout (tw) ;
X    tw->tbl.initting = True ;
X    InitLayout (tw) ;
X    tw->tbl.initting = False ;
X    }
X
X/*
X * We don't want to parse again unless we have to.
X */
X
XXtFree (tw->tbl.format_string) ;
Xtw->tbl.format_string = NULL ;
Xtw->tbl.format_mode = TBL_NO_FORMAT ;
X
Xreturn ;
X}
X
X/***** **** *** ** * InterpretString * ** *** **** *****/
X
Xstatic String
XInterpretString (string)
X    char *string ;
X{
Xreturn string ;
X}
X
X/***** **** *** ** * InitLayout * ** *** **** *****/
X
Xstatic void
XInitLayout (tw)
X    CuTblWidget tw ;
X{
Xstruct s_item **item = tw->tbl.item ;
Xint *cols = tw->tbl.cols ;
XWidgetList children = tw->composite.children ;
XWidget child ;
X
X/* this is for pointers from spanning entries back to the originating item */
X
Xint n_item = 0 ;
XCardinal i, j ;
XCardinal nth_child ;
X
X/*
X * Find the number of true items.
X * Also find the number of "items" in each row, where an "item" is a sequence
X * of vertical spans.
X */
X
Xif (XtIsRealized ((Widget)tw))
X    {
X    XtFree ((char *) tw->tbl.r_height) ;
X    XtFree ((char *) tw->tbl.r_item) ;
X    }
Xtw->tbl.r_height = (int *) XtMalloc (tw->tbl.rows * sizeof (int)) ;
Xtw->tbl.r_item = (int *) XtMalloc (tw->tbl.rows * sizeof (int)) ;
Xtw->tbl.max_cols = 0 ;
X
Xfor (i=0;  i < tw->tbl.rows;  i++)
X    {
X    tw->tbl.r_item[i] = 0 ;
X    if (cols[i] > tw->tbl.max_cols)
X	tw->tbl.max_cols = cols[i] ;
X    for (j=0;  j < cols[i];  j++)
X	{
X	if (item[i][j].primary == TBL_ITEM)
X	    {
X	    /*
X	     * Check for impossible situations
X	     */
X	    if (
X	       i != 0 && j != 0 &&
X	       item[i-1][j].primary == TBL_HSPAN &&
X	       item[i][j-1].primary == TBL_VSPAN
X	       )
X		{
X		char *text1 = "CuTbl: Illegal placement of tbl item:\n" ;
X		char *text2 = "     An 's' above with '^' to the left\n" ;
X		char *etext = XtMalloc (strlen(text1) + strlen(text2) + 1) ;
X		sprintf (etext, "%s%s", text1, text2) ;
X		XtError (etext) ;
X		}
X	    /*
X	     * Note this item
X	     */
X	    n_item++ ;
X	    tw->tbl.r_item[i]++ ;
X	    }
X	else
X	if (item[i][j].primary == TBL_HSPAN)
X	    {
X	    /*
X	     * Check for impossible situations
X	     */
X	    if (j == 0)
X		{
X		char *text1 = "CuTbl: Illegal placement of 's' span item:\n" ;
X		char *text2 = "     First entry in a row\n" ;
X		char *etext = XtMalloc (strlen(text1) + strlen(text2) + 1) ;
X		sprintf (etext, "%s%s", text1, text2) ;
X		XtError (etext) ;
X		}
X
X	    if (j != 0 && item[i][j-1].primary == TBL_VSPAN)
X		{
X		/*
X		 * I assume he meant this...
X		 */
X		item[i][j].primary = TBL_VSPAN ;
X		if (i != 0 && item[i-1][j].primary == TBL_ITEM)
X		    {
X		    /*
X		     * Nope, he was confused
X		     */
X		    char *text1 = "CuTbl: Illegal placement of 's' span item:\n" ;
X		    char *text2 = "     An entry above with '^' to the left\n" ;
X		    char *etext = XtMalloc (strlen(text1) + strlen(text2) + 1) ;
X		    sprintf (etext, "%s%s", text1, text2) ;
X		    XtError (etext) ;
X		    }
X		}
X	    }
X	else
X	if (item[i][j].primary == TBL_VSPAN)
X	    {
X	    if (i == 0)
X		{
X		char *text1 = "CuTbl: Illegal placement of '^' span item:\n" ;
X		char *text2 = "     Entry in first row\n" ;
X		char *etext = XtMalloc (strlen(text1) + strlen(text2) + 1) ;
X		sprintf (etext, "%s%s", text1, text2) ;
X		XtError (etext) ;
X		}
X	    else
X	    if (j != 0 && item[i][j-1].primary == TBL_HSPAN &&
X			 item[i-1][j].primary == TBL_HSPAN)
X		{
X		/* Must mean this... */
X		item[i][j].primary = TBL_HSPAN ;
X		j-- ;  /* recheck this position */
X		}
X	    else
X	    if (j == 0 || item[i][j-1].pw != item[i][j].pw)
X		tw->tbl.r_item[i]++ ;
X	    /*** TODO: Is .pw set at this point??? ***/
X	    }
X	}
X    }
X
X
Xif (n_item > tw->composite.num_children)
X    {
X    total_mismatch (n_item, tw) ;
X    }
X
Xif (n_item < tw->composite.num_children)
X    {
X    /*
X     * Check to see if it can be handled by repetitions of last line
X     */
X    int diff = tw->composite.num_children - n_item ;
X    int last_row_items = tw->tbl.r_item[tw->tbl.rows-1] ;
X
X    if ((diff % last_row_items) != 0)
X	{
X	total_mismatch (n_item, tw) ;
X	}
X
X    for (i=0;  i < diff / last_row_items;  i++)
X	{
X	int *save_r_item ;
X	int *save_r_height ;
X
X	tw->tbl.item[tw->tbl.rows] =
X	    (ElementRecord *) XtMalloc (tw->tbl.cols[tw->tbl.rows-1] *
X					sizeof (ElementRecord)) ;
X	tw->tbl.cols[tw->tbl.rows] = tw->tbl.cols[tw->tbl.rows-1] ;
X
X	/*
X	 * need to reallocate the r_item array
X	 */
X	save_r_item = tw->tbl.r_item ;
X	save_r_height = tw->tbl.r_height ;
X	tw->tbl.r_item = (int *) XtMalloc ((tw->tbl.rows+1) * sizeof (int)) ;
X	tw->tbl.r_height = (int *) XtMalloc ((tw->tbl.rows+1) * sizeof (int)) ;
X	for (j=0;  j < tw->tbl.rows;  j++)
X	    {
X	    tw->tbl.r_item[j] = save_r_item[j] ;
X	    tw->tbl.r_height[j] = save_r_height[j] ;
X	    }
X	XtFree ((char *) save_r_item) ;
X	XtFree ((char *) save_r_height) ;
X	tw->tbl.r_item[tw->tbl.rows] = tw->tbl.r_item[tw->tbl.rows-1] ;
X	tw->tbl.r_height[tw->tbl.rows] = tw->tbl.r_height[tw->tbl.rows-1] ;
X
X	for (j=0;  j < tw->tbl.cols[tw->tbl.rows];  j++)
X	    {
X	    tw->tbl.item[tw->tbl.rows][j] = tw->tbl.item[tw->tbl.rows-1][j] ;
X	    tw->tbl.item[tw->tbl.rows][j].text = NULL ;
X	    }
X	tw->tbl.rows++ ;
X	}
X    }
X
X/*
X * Find the span of each item
X */
X
Xnth_child = 0 ;
X
Xfor (i=0;  i < tw->tbl.rows;  i++)
X    {
X    for (j=0;  j < cols[i];  j++)
X	{
X	CuTblConstraints constraint ;
X	if (item[i][j].primary == TBL_ITEM)
X	    {
X	    int ii ;
X	    int jj ;
X	    Arg args[10] ;
X	    Cardinal n_args = 0 ;
X
X	    child = children[nth_child++] ;
X	    constraint = (CuTblConstraints)child->core.constraints;
X
X	    /*
X	     * Inform the child widget of tbl specifiable resources
X	     */
X
X	    XtSetArg (args[n_args], XtNjustify, (XtArgVal)item[i][j].justify) ;
X	    n_args++ ;
X
X	    if (tw->tbl.child_border_width != -1)
X		{
X		XtSetArg (args[n_args], XtNborderWidth,
X			  (XtArgVal)tw->tbl.child_border_width) ;
X		n_args++ ;
X		}
X
X	    if (tw->tbl.child_border_color != -1)
X		{
X		XtSetArg (args[n_args], XtNborderColor,
X			  (XtArgVal)tw->tbl.child_border_color) ;
X		n_args++ ;
X		}
X
X	    if (tw->tbl.child_background_color != -1)
X		{
X		XtSetArg (args[n_args], XtNbackground,
X			  (XtArgVal)tw->tbl.child_background_color) ;
X		n_args++ ;
X		}
X
X	    if (tw->tbl.child_foreground_color != -1)
X		{
X		XtSetArg (args[n_args], XtNforeground,
X			  (XtArgVal)tw->tbl.child_foreground_color) ;
X		n_args++ ;
X		}
X
X	    if (item[i][j].g != CuNoGravity)
X		{
X		XtSetArg (args[n_args], XtNgravity,
X			  (XtArgVal)item[i][j].g) ;
X		n_args++ ;
X		}
X
X	    if (item[i][j].text)
X		{
X		XtSetArg (args[n_args], XtNlabel, (XtArgVal)item[i][j].text) ;
X		n_args++ ;
X		}
X
X	    XtSetValues (child, args, n_args) ;
X
X	    constraint->tbl.fill_column = item[i][j].f ;
X	    constraint->tbl.span_width = 1 ;
X	    for (jj=j+1;  jj < cols[i];  jj++)
X		{
X		if (item[i][jj].primary != TBL_HSPAN)
X		    break ;
X		constraint->tbl.span_width++ ;
X		}
X
X	    constraint->tbl.span_height = 1 ;
X	    for (ii=i+1;  ii < tw->tbl.rows;  ii++)
X		{
X		if (item[ii][j].primary != TBL_VSPAN)
X		    break ;
X		constraint->tbl.span_height++ ;
X		}
X
X	    /* now fill the pointer array with pointers back to this item */
X	    for (ii=0;  ii < constraint->tbl.span_height;  ii++)
X		{
X		for (jj=0;  jj < constraint->tbl.span_width;  jj++)
X		    {
X		    tw->tbl.item[i+ii][j+jj].pw = child ;
X		    tw->tbl.item[i+ii][j+jj].pi = i ;
X		    tw->tbl.item[i+ii][j+jj].pj = j ;
X		    }
X		}
X	    }
X	}
X    }
X
Xtw->tbl.typical_border = item[0][0].pw->core.border_width ;
X
Xset_equal_cols (tw) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * set_equal_cols * ** *** **** *****/
X
Xstatic void
Xset_equal_cols (tw)
XCuTblWidget tw ;
X{
XCardinal  i ;
X
Xif (XtIsRealized ((Widget)tw))
X	{
X	XtFree ((char *) tw->tbl.equal_cols) ;
X	XtFree ((char *) tw->tbl.vspan_status) ;
X	}
Xtw->tbl.equal_cols = (Boolean *) XtMalloc (tw->tbl.rows * sizeof(Boolean)) ;
Xtw->tbl.vspan_status = (Boolean *) XtMalloc (tw->tbl.rows * sizeof(Boolean)) ;
X
X/*
X * If keyword "XtNequalColumns" is True, all elements set to True
X */
X
Xif (tw->tbl.equal_columns == True)
X    {
X    for (i=0;  i < tw->tbl.rows;  i++)
X	tw->tbl.equal_cols[i] = True ;
X    }
Xelse
X    {
X    for (i=0;  i < tw->tbl.rows;  i++)
X	{
X	Cardinal j ;
X	Cardinal e_count = 0 ;
X	tw->tbl.equal_cols[i] = False ;
X	for (j=0;  j < tw->tbl.cols[i];  j++)
X	    {
X	    if (tw->tbl.item[i][j].e)
X		{
X		e_count++ ;
X		}
X	    if (tw->tbl.item[i][j].primary == TBL_VSPAN)
X		{
X		/*
X		 * If the previous row had equal_columns and this one
X		 * is spanned to it, then this must be set, too.
X		 */
X		if (tw->tbl.equal_cols[i-1] == True)
X		    {
X		    tw->tbl.equal_cols[i] = True ;
X		    tw->tbl.equal_cols[tw->tbl.item[i][j].pi] = True ;
X		    }
X		break ;
X		}
X	    else
X	    if (tw->tbl.item[i][j].primary == TBL_HSPAN)
X		{
X		/* Any hz span in a row implies equal columns */
X		tw->tbl.equal_cols[i] = True ;
X		}
X	    }
X	/* if all columns were marked as equal, we'll treat it this way */
X	if (e_count == tw->tbl.cols[i])
X	    tw->tbl.equal_cols[i] = True ;
X	}
X    }
X
X/*
X * mark all rows that are spanned
X */
X
Xfor (i=0;  i < tw->tbl.rows;  i++)
X    {
X    Cardinal j ;
X
X    tw->tbl.vspan_status[i] = False ;
X    for (j=0;  j < tw->tbl.cols[i];  j++)
X	{
X	if (tw->tbl.item[i][j].primary == TBL_ITEM)
X	    {
X	    CuTblConstraints constraint =
X		    (CuTblConstraints) tw->tbl.item[i][j].pw->core.constraints ;
X	    if (constraint->tbl.span_height > 1)
X		{
X		tw->tbl.vspan_status[i] = True ;
X		}
X	    }
X	else
X	if (tw->tbl.item[i][j].primary == TBL_VSPAN)
X	    {
X	    tw->tbl.vspan_status[i] = True ;
X	    }
X	}
X    /*
X     * It is an error to have differing number of columns in spanned rows
X     * or in layouts with XtNalignedColumns set to True.
X     * (The true tbl doesn't complain, it just produces garbage)
X     */
X
X    if (i != 0 && tw->tbl.vspan_status[i] && tw->tbl.vspan_status[i-1] &&
X	tw->tbl.cols[i] != tw->tbl.cols[i-1])
X	{
X	char *my_text1 = "CuTbl: Variable number of columns in rows\n" ;
X	char *my_text2 = "     that have vertical spanning elements\n" ;
X	char *my_text3 = "     (detected in rows %d and %d)\n" ;
X	char *etext1 = XtMalloc (strlen(my_text1) + strlen(my_text2) +
X				strlen(my_text3) + 1) ;
X	char *etext2 ;
X	sprintf (etext1, "%s%s%s", my_text1, my_text2, my_text3) ;
X	etext2 = XtMalloc (strlen(etext1) + 5) ;
X	sprintf (etext2, etext1, i, i-1) ;
X	XtError (etext2) ;
X	}
X
X    if (i != 0 && tw->tbl.aligned_columns &&
X	tw->tbl.cols[i] != tw->tbl.cols[i-1])
X	{
X	char *my_text1 = "CuTbl: Variable number of columns in layout\n" ;
X	char *my_text2 = "     that has XtNalignedColumns set to True\n" ;
X	char *etext1 = XtMalloc (strlen(my_text1) + strlen(my_text2) + 1) ;
X	sprintf (etext1, "%s%s", my_text1, my_text2) ;
X	XtError (etext1) ;
X	}
X    }
X
Xreturn ;
X}
X
X/***** **** *** ** * total_mismatch * ** *** **** *****/
X
Xstatic void
Xtotal_mismatch (n_item, tw)
X    int n_item ;
X    CuTblWidget tw ;
X{
Xchar *my_text1 = "CuTbl (%s) : %d items in the format\n" ;
Xchar *my_text2 = "     %d children in the widget\n" ;
Xchar *etext1 = XtMalloc (strlen(my_text1) + 30) ;
Xchar *etext2 = XtMalloc (strlen(my_text2) + 3) ;
Xchar *etext3 ;
Xsprintf (etext1, my_text1, tw->core.name, n_item) ;
Xsprintf (etext2, my_text2, tw->composite.num_children) ;
Xetext3 = XtMalloc (strlen(etext1) + strlen(etext2) + 1) ;
Xsprintf (etext3, "%s%s", etext1, etext2) ;
XXtError (etext3) ;
X}
X
X/*
X * And, finally, the routines used to parse a tbl description
X */
X
X#define ytblparse() ParseTblLayout (tw) CuTblWidget tw ;
X
X#include "CuTbl.y.c"
X
X/***** **** *** ** * "yyerror" * ** *** **** *****/
X
Xstatic void
Xytblerror (s)
X    char *s ;
X{
XCardinal length ;
XString my_text = "CuTbl: Parsing error (%s)\nLine # %d in file '%s':\n" ;
XString etext ;
Xlength = strlen(my_text) + strlen(s) + TBL_MAX_CONTEXT + 20 ;
Xetext = XtMalloc (length) ;
Xsprintf (etext, my_text, s, layout_input->line_number, layout_input->cur_file) ;
Xstrcat (etext, layout_input->context_buffer) ;
XXtError (etext) ;
X}
X
X/***** **** *** ** * "yywrap" * ** *** **** *****/
X
Xstatic int
Xytblwrap ()
X{
Xreturn 1 ;
X}
X
X/***** **** *** ** * the lex input routine * ** *** **** *****/
X
X#define TBL_UNPUT_SOURCE 0
X#define TBL_INPUT_SOURCE 1
X
Xstatic int
Xinput ()
X{
Xint t ;
Xint t_source ;
X
Xif (layout_input->unput_pointer)
X    {
X    t = layout_input->unput_buffer[layout_input->unput_pointer-1] ;
X    layout_input->unput_pointer-- ;
X    t_source = TBL_UNPUT_SOURCE ;
X    }
Xelse
X    {
X    t = layout_input->input_buffer[layout_input->input_pointer++] ;
X    t_source = TBL_INPUT_SOURCE ;
X    }
X
Xif (layout_input->string_file == (int) TBL_STRING_FORMAT &&
X    layout_input->lnl_equivalent == -1 &&
X    t == '\\')
X    {
X    int next = input () ;
X    if (next == 'n')
X	t = '\n' ;
X    else
X	unput (next) ;
X    }
X
Xif (t == '\0' && t_source == TBL_INPUT_SOURCE)
X    {
X    unput (t) ;
X    t = '\n' ;
X    }
X
Xif (t == layout_input->lnl_equivalent)
X    {
X    t = '\n' ;
X    }
X
Xif (t == '\n')
X    {
X    layout_input->line_number++ ;
X    layout_input->context_ptr = 0 ;
X    }
Xelse
Xif (layout_input->context_ptr < TBL_MAX_CONTEXT)
X    {
X    layout_input->context_buffer[layout_input->context_ptr++] = t ;
X    layout_input->context_buffer[layout_input->context_ptr] = '\0' ;
X    }
Xelse
X    {
X    char error_text[100] ;
X    sprintf (error_text,
X	    "Insufficient context buffer space for input character (%c)\n", t) ;
X    XtWarning (error_text) ;
X    }
X
Xreturn t ;
X}
X
X/***** **** *** ** * the lex unput routine * ** *** **** *****/
X
Xstatic void
Xunput (c)
X    int c ;
X{
Xlayout_input->unput_buffer[layout_input->unput_pointer++] = c ;
X
X/*
X * Just wipe out currrent line context characters.  Don't try to retrieve those
X * already cycled out. (It seems highly unlikely that anything significant
X * will ever be lost by this.)
X */
X
Xif (layout_input->context_ptr > 0)
X    layout_input->context_ptr-- ;
X
Xif (c == '\n')
X    if (layout_input->line_number > 1)
X	layout_input->line_number-- ;
X
Xreturn ;
X}
X
X/**
X ***
X **** Public Procedures
X ***
X **/
X
X/* none */
X

END_OF_FILE
echo shar: NEWLINE appended to \"'src/CuTbl.c.ac'\"
if test 14579 -ne `wc -c <'src/CuTbl.c.ac'`; then
    echo shar: \"'src/CuTbl.c.ac'\" unpacked with wrong size!
fi
# end of 'src/CuTbl.c.ac'
fi
if test ! -d 'wlmCompiler' ; then
    echo shar: Creating directory \"'wlmCompiler'\"
    mkdir 'wlmCompiler'
fi
echo shar: End of archive 1 \(of 12\).
cp /dev/null ark1isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 10 11 12 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 12 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0