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

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

Submitted-by: Gene Dykes <gdykes@tcgould.tn.cornell.edu>
Posting-number: Volume 3, Issue 80
Archive-name: xcu/part04

#! /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 4 (of 12)."
# Contents:  src/CuTbl.c.aa src/CuWlm.c.ac
# Wrapped by argv@island on Mon Apr 24 15:41:35 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/CuTbl.c.aa' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/CuTbl.c.aa'\"
else
echo shar: Extracting \"'src/CuTbl.c.aa'\" \(26220 characters\)
sed "s/^X//" >'src/CuTbl.c.aa' <<'END_OF_FILE'
X#include "disclaimer.h"
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 "CuTblP.h"
X
Xvoid Cu_copy_ds () ;
X
X/* Private Definitions */
X
X/*
X * defaults for resources
X */
X
Xstatic Boolean def_false = False ;
Xstatic int     def_zero =  0 ;
X
Xstatic CuResizeParticipants def_participants =
X       CuResizeInters | CuResizeInternals | CuResizeChildren ;
X
X/*
X * resource declarations
X */
X
X#define offset(field) XtOffset(CuTblWidget, field)
X#define Offset(field) XtOffset(CuTblWidget, tbl.field)
X
Xstatic XtResource resources[] =
X{
X     {XtNalignedColumns,     XtCBoolean, XtRBoolean, sizeof(Boolean),
X      Offset(aligned_columns), XtRBoolean, (caddr_t) &def_false}
X
X    ,{XtNclipOnShrink,       XtCBoolean, XtRBoolean, sizeof(Boolean),
X      Offset(clip_on_shrink), XtRBoolean, (caddr_t) &def_false}
X
X    ,{XtNequalColumns,       XtCBoolean, XtRBoolean, sizeof(Boolean),
X      Offset(equal_columns), XtRBoolean, (caddr_t) &def_false}
X
X    ,{XtNequalRows,          XtCBoolean, XtRBoolean, sizeof(Boolean),
X      Offset(equal_rows),    XtRBoolean, (caddr_t) &def_false}
X
X    ,{XtNformatFile,         XtCString,  XtRString,  sizeof(String),
X      Offset(format_file),   XtRString, (caddr_t) NULL}
X
X    ,{XtNformatString,	     XtCString,  XtRString,  sizeof(String),
X      Offset(format_string), XtRString, (caddr_t) NULL}
X
X    ,{XtNinterWidth,	     XtCWidth,   XtRInt,  sizeof(int),
X      Offset(inter_width),   XtRInt,	(caddr_t) &def_zero}
X
X    ,{XtNinterHeight,  	     XtCHeight,  XtRInt,  sizeof(int),
X      Offset(inter_height),  XtRInt,	(caddr_t) &def_zero}
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, XtCResizeParticipants,
X      XtRResizeParticipants, sizeof(CuResizeParticipants),
X      Offset(resize_participants), XtRResizeParticipants,
X      (caddr_t) &def_participants}
X
X} ;
X
X#undef Offset
X#undef offset
X
X#define Offset(field) XtOffset(CuTblConstraints, tbl.field)
X
Xstatic XtResource tblConstraintResources[] =
X{
X     {XtNfillColumn,         XtCBoolean, XtRBoolean, sizeof(Boolean),
X      Offset(fill_column),   XtRBoolean, (caddr_t) &def_false}
X} ;
X
X#undef Offset
X
X/* Declarations of "toolkit" calls */
X
Xstatic void		ClassPartInitialize () ;
Xstatic void		ClassInitialize () ;
Xstatic void		ChangeManaged () ;
Xstatic void		Initialize () ;
Xstatic void		Resize () ;
Xstatic Boolean		ConstraintSetValues () ;
Xstatic Boolean		SetValues () ;
Xstatic XtGeometryResult	GeometryManager () ;
Xstatic XtGeometryResult QueryGeometry () ;
Xstatic void		Destroy () ;
X
X/* Declarations of "CuTbl Class" calls */
X
Xstatic String		InterpretString () ;
X
X/* Declarations of "private" calls */
X
Xstatic void		unput () ;
Xstatic void		DoLayout () ;
Xstatic void		Trial_STS() ;
Xstatic void		Trial_ETS () ;
Xstatic void		ytblerror () ;
Xstatic void		convert_nl () ;
Xstatic void		InitLayout () ;
Xstatic void		SetupLayout () ;
Xstatic void		set_equal_cols () ;
Xstatic void		total_mismatch () ;
Xstatic void		e_apportion_slack () ;
Xstatic void		v_apportion_slack () ;
Xstatic Boolean		adjust_aligned_columns () ;
Xstatic Boolean		adjust_equal_columns () ;
Xstatic Boolean		adjust_spanned_columns () ;
X
X/* It's not possible to get the following thing static since it's a macro */
X
X	int		ParseTblLayout () ;
X/*
X * Class Record Constant
X */
X
XCuTblClassRec cuTblClassRec =
X{
X  { /* core_class fields */
X    /* superclass         */    (WidgetClass) &constraintClassRec,
X    /* class_name         */    "CuTbl",
X    /* widget_size        */    sizeof(CuTblRec),
X    /* class_initialize   */    ClassInitialize,
X    /* class_part_init    */    ClassPartInitialize,
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  { /* constraint_class fields */
X    /* subresourses       */   tblConstraintResources,
X    /* subresource_count  */   XtNumber(tblConstraintResources),
X    /* constraint_size    */   sizeof(CuTblConstraintsRec),
X    /* initialize         */   NULL,
X    /* destroy            */   NULL,
X    /* set_values         */   ConstraintSetValues,
X    /* extension         */    NULL
X  },
X  { /* tbl_class fields   */
X    /* interpret_string   */   InterpretString
X  }
X} ;
X
X/*
X * Class Record Pointer
X */
X
XWidgetClass cuTblWidgetClass = (WidgetClass) &cuTblClassRec ;
X
X/*
X * This static record doesn't seem to be a good idea, but I can't figure out
X * another way of getting the necessary information into the lexical
X * input routine.  (It seems to me that lex and yacc have a serious design flaw:
X * it wasn't foreseen that one might want several parsers in the same module.)
X *
X * Although several instances must share these static variables, they are
X * only used during one call from the toolkit, so if it executes atomically,
X * this should be okay.
X */
X
X#define TBL_MAX_UNPUT 100
X#define TBL_MAX_CONTEXT 100
X
Xtypedef struct
X    {
X    String input_buffer ;
X    Cardinal input_pointer ;
X    char unput_buffer[TBL_MAX_UNPUT] ;
X    Cardinal unput_pointer ;
X    char context_buffer[TBL_MAX_CONTEXT] ;
X    int context_ptr ; /* must not be Cardinal */
X    Cardinal line_number ;
X    String cur_file ;
X    int snl_equivalent ;
X    int lnl_equivalent ;
X    int string_file ;
X    } TblInputRecord ;
X
Xstatic TblInputRecord _layout_input, *layout_input = &_layout_input ;
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
XCuAddStringToJustifyConverter () ;
XCuAddStringToGravityConverter () ;
XCuAddStringToResizeParticipantsConverter () ;
X
Xreturn ;
X}
X
X/***** **** *** ** * Initialize * ** *** **** *****/
X
Xstatic void
XInitialize (request, new)
X    Widget request, new ;
X{
XCuTblWidget tw = (CuTblWidget) new ;
X
X/*
X * allocate space for and copy resources specified by address
X */
X
Xif (tw->tbl.format_file != NULL) 
X    Cu_copy_ds (&tw->tbl.format_file, tw->tbl.format_file) ;
X
Xif (tw->tbl.format_string != NULL) 
X    Cu_copy_ds (&tw->tbl.format_string, tw->tbl.format_string) ;
X
X/*
X * Initialize some non-resource fields
X */
X
Xtw->tbl.child_border_width = -1 ;
Xtw->tbl.child_border_color = -1 ;
Xtw->tbl.child_background_color = -1 ;
Xtw->tbl.child_foreground_color = -1 ;
Xtw->tbl.string_breaker = '\t' ;
Xtw->tbl.format_mode = TBL_FIRST_PASS ;
Xtw->tbl.initting = False ;
Xtw->tbl.force_width = False ;
X
Xreturn ;
X}
X
X/***** **** *** ** * ClassPartInitialize * ** *** **** *****/
X
Xstatic void
XClassPartInitialize (wClass)
X    WidgetClass wClass ;
X{
XCuTblWidgetClass tw = (CuTblWidgetClass) wClass ;
X
X/*
X * provide for inheriting tbl_class procedures
X */
X
Xif (tw->tbl_class.interpret_string ==
X    (XtTblStringProc) XtInheritInterpretString)
X    {
X    tw->tbl_class.interpret_string = InterpretString ;
X    }
X
Xreturn ;
X}
X
X/***** **** *** ** * Destroy * ** *** **** *****/
X
Xstatic void
XDestroy (widget)
X    Widget widget ;
X{
XCuTblWidget tw = (CuTblWidget) widget ;
XCardinal  i ;
X
X/*
X * free dynamically allocated data
X */
X
Xif (!XtIsRealized (widget))
X    return ;
X
XXtFree ((char *) tw->tbl.r_item) ;
XXtFree ((char *) tw->tbl.equal_cols) ;
Xfor (i=0;  i < tw->tbl.rows;  i++)
X    XtFree ((char *) tw->tbl.item[i]) ;
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 ((CuTblWidget) w, (Widget) NULL) ;
XTrial_ETS ((CuTblWidget) w) ;
XDoLayout ((CuTblWidget) 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{
XXtGeometryResult parent_result;
XXtWidgetGeometry allowed ;
XCuTblWidget thisInstance = (CuTblWidget) w->core.parent ;
XCuTblConstraints constraint = (CuTblConstraints) w->core.constraints ;
XDimension save_child_width = w->core.width ;
XDimension save_child_height = w->core.height ;
XDimension compromise_width, compromise_height ;
X
X/*
X * We can't allow any requests while in init phase
X */
X
Xif (thisInstance->tbl.initting)
X    return XtGeometryNo ;
X
X/*
X * Look for identical request to a prior XtGeometryAlmost -- we have to grant
X */
X
Xif (
X   constraint->tbl.almost_status == True
X
X   &&
X
X   constraint->tbl.almost_widget == w
X   
X    &&
X
X   (((constraint->tbl.almost_mode & CWWidth) && 
X    (request->request_mode & CWWidth) && 
X    (constraint->tbl.almost_width == request->width))
X    ||
X    ((constraint->tbl.almost_mode & CWWidth) ==
X     (request->request_mode & CWWidth)))
X
X    &&
X
X   (((constraint->tbl.almost_mode & CWHeight) && 
X    (request->request_mode & CWHeight) && 
X    (constraint->tbl.almost_height == request->height))
X    ||
X    ((constraint->tbl.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 = constraint->tbl.almost_x ;
X    w->core.y = constraint->tbl.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 ( thisInstance, w ) ;
X    Trial_ETS ( thisInstance ) ;
X    if (!(request->request_mode & XtCWQueryOnly))
X	DoLayout  ( thisInstance, w ) ;
X
X    constraint->tbl.almost_status = False ;
X    return XtGeometryYes ;
X    }
X
Xconstraint->tbl.almost_status = False ;
X
X/*
X * Unfudge the width if necessary
X */
X
Xif (thisInstance->tbl.force_width)
X    request->width-- ;
X
X/*
X * Disallow anything but size requests from the children
X */
X
Xif ((request->request_mode & (CWWidth | CWHeight)) == 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
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    !thisInstance->tbl.force_width)
X    {
X    return XtGeometryNo ;
X    }
X
XthisInstance->tbl.force_width = False ;
X
X/*
X * We'll have to do a Trial_STS to see what the effects of the change are
X */
X
XthisInstance->tbl.pre_almost_width = w->core.width = allowed.width ;
XthisInstance->tbl.pre_almost_height = w->core.height = allowed.height ;
X
XTrial_STS ( thisInstance, w ) ;
X
X/*
X * Run this layout by my parent
X */
X
Xparent_result = XtMakeResizeRequest ((Widget)thisInstance,
X			  (Dimension)thisInstance->tbl.standalone_width,
X			  (Dimension)thisInstance->tbl.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)thisInstance,
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 ( thisInstance ) ;
X
Xif ( /* checking for nothing changed */
X     (
X     save_child_width == constraint->tbl.ets_width &&
X     (request->request_mode & CWWidth)
X     )
X     &&
X     (
X     save_child_height == constraint->tbl.ets_height &&
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 != constraint->tbl.ets_width &&
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 != constraint->tbl.ets_height &&
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 < constraint->tbl.ets_width &&
X		      constraint->tbl.ets_width < save_child_width ||
X     request->width > constraint->tbl.ets_width &&
X		      constraint->tbl.ets_width > 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 < constraint->tbl.ets_height &&
X		      constraint->tbl.ets_height < save_child_height ||
X     request->height > constraint->tbl.ets_height &&
X		      constraint->tbl.ets_height > 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    constraint->tbl.almost_status = True ;
X    constraint->tbl.almost_width = reply->width = constraint->tbl.ets_width ;
X    constraint->tbl.almost_height = reply->height = constraint->tbl.ets_height ;
X    constraint->tbl.almost_x = reply->x = constraint->tbl.ets_x ;
X    constraint->tbl.almost_y = reply->y = constraint->tbl.ets_y ;
X    reply->border_width = thisInstance->tbl.typical_border ;
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    constraint->tbl.almost_widget = w ;
X    constraint->tbl.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  ( thisInstance, w ) ;
X
Xreturn XtGeometryYes ;
X}
X
X/***** **** *** ** * SetValues * ** *** **** *****/
X
Xstatic Boolean
XSetValues (current, request, new)
X    Widget current, request, new ;
X{
XCuTblWidget cw = (CuTblWidget) current ;
XCuTblWidget nw = (CuTblWidget) new ;
XBoolean   string_changed = False ;
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
X/* Check for new layout (or modification of old layout) */
X
Xif (nw->tbl.format_file || nw->tbl.format_string)
X    {
X    if (XtIsRealized (current))
X	{
X	SetupLayout (nw) ;
X	string_changed = True ;
X	}
X    }
Xelse
Xif (cw->tbl.equal_columns != nw->tbl.equal_columns)
X    {
X    set_equal_cols (nw) ;
X    }
X
Xif (
X      string_changed
X   || cw->tbl.aligned_columns != nw->tbl.aligned_columns
X   || cw->tbl.clip_on_shrink != nw->tbl.clip_on_shrink
X   || cw->tbl.equal_columns != nw->tbl.equal_columns
X   || cw->tbl.equal_rows != nw->tbl.equal_rows
X   || cw->tbl.internal_width != nw->tbl.internal_width
X   || cw->tbl.internal_height != nw->tbl.internal_height
X   || cw->tbl.inter_width != nw->tbl.inter_width
X   || cw->tbl.inter_height != nw->tbl.inter_height
X   || cw->tbl.resize_participants != nw->tbl.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/***** **** *** ** * ConstraintSetValues * ** *** **** *****/
X
Xstatic Boolean
XConstraintSetValues (current, request, new)
X    Widget current, request, new ;
X{
XCuTblWidget thisInstance = (CuTblWidget) current->core.parent ;
XCuTblConstraints constraintc = (CuTblConstraints) current->core.constraints ;
XCuTblConstraints constraintn = (CuTblConstraints) new->core.constraints ;
X
X/*
X * XtSetValues looks at x,y,width,height of new widget and compares it to
X * current widget.  If different, calls geometry manager of the widget's parent.
X * So, changing fill_column here won't invoke the geometry manager, and
X * even if it did, it would get called with fill_column as it used to be.
X * I suppose I could do all the Trial_STS,ETS myself, but it would be so much
X * easier if Xt would do it for me.  Is it a bug in Xt?  Besides, it would
X * be inefficient to do all that stuff twice.  For now, I'll
X * kludge so geometry manager will get called if necessary...
X */
X
Xif (new->core.x ==	      current->core.x &&
X    new->core.y ==	      current->core.y &&
X    new->core.width ==	      current->core.width &&
X    new->core.height ==	      current->core.height &&
X    new->core.border_width == current->core.border_width)
X    {
X    if (constraintn->tbl.fill_column !=   constraintc->tbl.fill_column)
X	{
X	XtWidgetGeometry preferred ;
X	/*
X	XtWidgetGeometry intended ;
X	intended.request_mode = (CWWidth | CWHeight) ;
X	*/
X	/* put new fill_column in current widget */
X	constraintc->tbl.fill_column = constraintn->tbl.fill_column ;
X	/* force the geometry manager to get called by fudging width */
X	XtQueryGeometry (current, NULL, &preferred) ;
X	new->core.width = preferred.width + 1 ;
X	new->core.height = preferred.height ;
X	/* set a flag so geomgr will unadjust this value */
X	thisInstance->tbl.force_width = True ;
X	}
X    constraintc->tbl.differ_geometry = False ;
X    }
Xelse
X    {
X    constraintc->tbl.differ_geometry = True ;
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 * Normally this will only be called as a result of an XtRealizeWidget or
X * an XtManageWidget.
X *
X * This widget is intended to manage a fixed number of widgets in a fixed
X * layout array.  In order to change the set of managed children significantly,
X * one should probably unmanage this widget, change the children, change
X * the layout format, and then remanage the widget.
X */
X
XSetupLayout ((CuTblWidget) w) ;
XTrial_STS ((CuTblWidget) w, (Widget) NULL) ;
XTrial_ETS ((CuTblWidget) w) ;
XDoLayout ((CuTblWidget) w, (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 ;
XCuTblWidget w = (CuTblWidget) widget ;
Xpreferred->width = w->tbl.standalone_width ;
Xpreferred->height = w->tbl.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 tbl
X */
X
Xstatic void
XTrial_STS (tw, w_requester)
X    CuTblWidget tw ;
X    Widget w_requester ;
X{
Xstruct s_item **item = tw->tbl.item ;
XWidget child ;
Xint *cols = tw->tbl.cols ;
XCardinal i ;
Xint needed_width = 0 ;
Xint max_r_height = 0 ;
Xint *r_width = (int *) XtMalloc (tw->tbl.rows * sizeof(int)) ;
Xint *r_height = tw->tbl.r_height ;
X
X/*
X * The following calculations assume that all children have the same
X * border_width.  Is it okay for this not to be true?  Probably yes,
X * but probably also a pain in the neck.
X */
X
X/*
X * Start the adjustment process
X */
X
X/*
X * Step 0 : Collect the widths and heights of each item
X */
X
Xfor (i=0;  i < tw->tbl.rows;  i++)
X    {
X    Cardinal j ;
X
X    for (j=0;  j < cols[i];  j++)
X	{
X	Cardinal k ;
X	CuTblConstraints constraint = (CuTblConstraints)
X				    item[i][j].pw->core.constraints ;
X	/*
X	 * This is a bit tricky...
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	 * But, if the child has only a new fill mode, we're here, too, but
X	 * in this case we DO want to do a QueryGeometry. So, have to look
X	 * for a special flag set during ConstraintSetValues.
X	 */
X	if (item[i][j].primary != TBL_ITEM)
X	    continue ;
X	if (item[i][j].pw == w_requester && constraint->tbl.differ_geometry)
X	    {
X	    item[i][j].width = w_requester->core.width ;
X	    item[i][j].height = w_requester->core.height ;
X	    }
X	else
X	    {
X	    XtWidgetGeometry preferred ;
X	    /*
X	    XtWidgetGeometry intended ;
X	    intended.request_mode = (CWWidth | CWHeight) ;
X	    */
X	    XtQueryGeometry (item[i][j].pw, NULL, &preferred) ;
X	    item[i][j].width = preferred.width ;
X	    item[i][j].height = preferred.height ;
X	    }
X	item[i][j].adj_width = (item[i][j].width + constraint->tbl.span_width
X				- 1) / constraint->tbl.span_width ;
X	for (k=1;  k < constraint->tbl.span_height;  k++)
X	    item[i+k][j].adj_width = item[i][j].adj_width ;
X	}
X    }
X
X/*
X * Step 1a : Get all equal length columns and all spanned row columns equal
X */
X
Xfor (;;)
X    {
X    Boolean something_changed = False ;
X    something_changed = adjust_aligned_columns (tw) ;
X    something_changed |= adjust_equal_columns (tw) ;
X    something_changed |= adjust_spanned_columns (tw) ;
X    if (!something_changed)
X	break ;
X    }
X
X/*
X * Step 1b : find the min length needed for each row 
X *  Each row needs space for:
X *    TBL_ITEMS
X *    VSPAN_ITEMS (only once per item block)
X *    borders and inter-spaces
X */
X
Xfor (i=0;  i < tw->tbl.rows;  i++)
X    {
X    Cardinal j ;
X    int num_item ;
X
X    r_width[i] = 0 ;
X    for (j=0;  j < cols[i];  j++)
X	{
X	if (item[i][j].primary == TBL_ITEM)
X	    {
X	    child = item[i][j].pw ;
X
X	    if (tw->tbl.equal_cols[i])
X		{
X		/* min length is multiple of largest child */
X		if (item[i][j].adj_width > r_width[i])
X		    {
X		    r_width[i] = item[i][j].adj_width ;
X		    }
X		}
X	    else
X		{
X		/* min length is sum of children */
X		r_width[i] += item[i][j].width ;
X		}
X	    }
X	else
X	    {
X	    if (!tw->tbl.equal_cols[i])
X		{
X		/* Need to include vertically spanned items */
X		if (item[i][j].primary == TBL_VSPAN)
X		    {
X		    r_width[i] += item[i][j].adj_width ;
X		    }
X		}
X	    }
X	}
X
X    if (tw->tbl.equal_cols[i])
X	{
X	r_width[i] = cols[i] * r_width[i] ;
X	}
X
X    num_item = tw->tbl.equal_cols[i] ? cols[i] : tw->tbl.r_item[i] ;
X    r_width[i] += (num_item - 1) *
X		  (tw->tbl.inter_width + 2 * tw->tbl.typical_border) ;
X    if (r_width[i] > needed_width)
X	{
X	needed_width = r_width[i] ;
X	}
X    }
X
X/* Now adjust each row to fit within largest width */
Xfor (i=0;  i < tw->tbl.rows;  i++)
X    {
X    Cardinal last_item = 0 ;
X    int n_arbs = 0 ;
X    int *arbs ;
X    Cardinal j ;
X    int slack, *portions ;
X
X    /* First see if there are any arbs that take up all the slack */

END_OF_FILE
echo shar: NEWLINE appended to \"'src/CuTbl.c.aa'\"
if test 26221 -ne `wc -c <'src/CuTbl.c.aa'`; then
    echo shar: \"'src/CuTbl.c.aa'\" unpacked with wrong size!
fi
# end of 'src/CuTbl.c.aa'
fi
if test -f 'src/CuWlm.c.ac' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'src/CuWlm.c.ac'\"
else
echo shar: Extracting \"'src/CuWlm.c.ac'\" \(26751 characters\)
sed "s/^X//" >'src/CuWlm.c.ac' <<'END_OF_FILE'
Xif (return_status)
X    ww->wlm.event_stamp++ ;
X
Xreturn return_status ;
X}
X
X/**
X ** Association Functions
X **/
X
X/***** **** *** ** * CuWlmAddCallback * ** *** **** *****/
X
Xvoid
XCuWlmAddCallback (ww, connection_type,
X		widget_class, widget_name, callback_name, 
X		callback_proc, client_data)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    XtCallbackProc callback_proc ;
X    caddr_t client_data ;
X{
XWidget callback_widget ;
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmAddCallback requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xcallback_widget = get_callback_widget (ww, widget_class, widget_name,
X					callback_name) ;
Xif (callback_widget != NULL)
X    {
X    /* match */
X    if (!((int)connection_type & (int)CuWlmBypass))
X	{
X	CuWlmIndirectRecord *record ;
X	record = (CuWlmIndirectRecord *) XtMalloc (sizeof (CuWlmIndirectRecord)) ;
X	record->callback_proc = callback_proc ;
X	record->client_data = client_data ;
X	record->ww = ww ;
X	XtAddCallback (callback_widget, callback_name,
X		       callback_indirect, (caddr_t) record) ;
X	}
X    else
X	{
X	XtAddCallback (callback_widget, callback_name,
X		       callback_proc, client_data) ;
X	}
X
X    if ((int)connection_type & (int)CuWlmSampling)
X	{
X	add_to_sample_list (ww, widget_class, callback_widget) ;
X	}
X    }
Xelse
X    {
X    callback_not_found_warning ("CuWlmAddCallback", widget_class, widget_name,
X				callback_name) ;
X    }
X
Xreturn ;
X}
X
X/***** **** *** ** * CuWlmSetFloat, Int, String * ** *** **** *****/
X
Xvoid
XCuWlmSetFloat (ww, connection_type, widget_class, widget_name,
X		  callback_name, target, value)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    float *target ;
X    float value ;
X{
XCuWlmSetFloatRecord *record ;
XWidget callback_widget ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmSetFloat requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xcallback_widget = get_callback_widget (ww, widget_class, widget_name,
X					callback_name) ;
Xif (callback_widget != NULL)
X    {
X    record = (CuWlmSetFloatRecord *) XtMalloc (sizeof (CuWlmSetFloatRecord)) ;
X    record->value = value ;
X    record->target = target ;
X    record->ww = ww ;
X    record->wlm_type = connection_type ;
X    XtAddCallback (callback_widget, callback_name,
X		   callback_set_float, (caddr_t) record) ;
X    if ((int)connection_type & (int)CuWlmSampling)
X	{
X	add_to_sample_list (ww, widget_class, callback_widget) ;
X	}
X    }
Xelse
X    {
X    callback_not_found_warning ("CuWlmSetFloat", widget_class, widget_name,
X				callback_name) ;
X    }
X
Xreturn ;
X}
X
Xvoid
XCuWlmSetBoolean (ww, connection_type, widget_class, widget_name,
X	        callback_name, target, value)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    Boolean *target ;
X    Boolean value ;
X{
XCuWlmSetBoolRecord *record ;
XWidget callback_widget ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmSetBoolean requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xcallback_widget = get_callback_widget (ww, widget_class, widget_name,
X					callback_name) ;
Xif (callback_widget != NULL)
X    {
X    record = (CuWlmSetBoolRecord *) XtMalloc (sizeof (CuWlmSetBoolRecord)) ;
X    record->value = value ;
X    record->target = target ;
X    record->ww = ww ;
X    record->wlm_type = connection_type ;
X    XtAddCallback (callback_widget, callback_name,
X		   callback_set_bool, (caddr_t) record) ;
X    if ((int)connection_type & (int)CuWlmSampling)
X	{
X	add_to_sample_list (ww, widget_class, callback_widget) ;
X	}
X    }
Xelse
X    {
X    callback_not_found_warning ("CuWlmSetBoolean", widget_class, widget_name,
X				callback_name) ;
X    }
X
Xreturn ;
X}
X
Xvoid
XCuWlmSetInt (ww, connection_type, widget_class, widget_name,
X	        callback_name, target, value)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    int *target ;
X    int value ;
X{
XCuWlmSetIntRecord *record ;
XWidget callback_widget ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmSetInt requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xcallback_widget = get_callback_widget (ww, widget_class, widget_name,
X					callback_name) ;
Xif (callback_widget != NULL)
X    {
X    record = (CuWlmSetIntRecord *) XtMalloc (sizeof (CuWlmSetIntRecord)) ;
X    record->value = value ;
X    record->target = target ;
X    record->ww = ww ;
X    record->wlm_type = connection_type ;
X    XtAddCallback (callback_widget, callback_name,
X		   callback_set_int, (caddr_t) record) ;
X    if ((int)connection_type & (int)CuWlmSampling)
X	{
X	add_to_sample_list (ww, widget_class, callback_widget) ;
X	}
X    }
Xelse
X    {
X    callback_not_found_warning ("CuWlmSetInt", widget_class, widget_name,
X				callback_name) ;
X    }
X
Xreturn ;
X}
X
Xvoid
XCuWlmSetString (ww, connection_type, widget_class, widget_name,
X		  callback_name, target, value)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    String *target ;
X    String value ;
X
X{
XCuWlmSetStringRecord *record ;
XWidget callback_widget ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmSetString requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xcallback_widget = get_callback_widget (ww, widget_class, widget_name,
X					callback_name) ;
Xif (callback_widget != NULL)
X    {
X    record = (CuWlmSetStringRecord *) XtMalloc (sizeof (CuWlmSetStringRecord)) ;
X    Cu_copy_ds (&record->value, value) ;
X    record->target = target ;
X    record->ww = ww ;
X    record->wlm_type = connection_type ;
X    XtAddCallback (callback_widget, callback_name,
X		   callback_set_string, (caddr_t) record) ;
X    if ((int)connection_type & (int)CuWlmSampling)
X	{
X	add_to_sample_list (ww, widget_class, callback_widget) ;
X	}
X    }
Xelse
X    {
X    callback_not_found_warning ("CuWlmSetString", widget_class, widget_name,
X				callback_name) ;
X    }
X
Xreturn ;
X}
X
X/***** **** *** ** * CuWlmGetFloat, Int, String * ** *** **** *****/
X
Xvoid
XCuWlmGetFloat (ww, connection_type, widget_class, widget_name,
X		  callback_name, target)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    float *target ;
X{
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmGetFloat requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xget_int_float_string (ww, widget_class, widget_name,
X			   callback_name, (caddr_t *) target,
X			   "CuWlmGetFloat", CuWlmGetFloatType, connection_type) ;
Xreturn ;
X}
X
Xvoid
XCuWlmGetBoolean (ww, connection_type, widget_class, widget_name,
X		callback_name, target)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    Boolean *target ;
X{
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmGetBoolean requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xget_int_float_string (ww, widget_class, widget_name,
X			   callback_name, (caddr_t *) target,
X			   "CuWlmGetBoolean", CuWlmGetBoolType, connection_type) ;
X}
X
Xvoid
XCuWlmGetInt (ww, connection_type, widget_class, widget_name,
X		callback_name, target)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    int *target ;
X{
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmGetInt requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xget_int_float_string (ww, widget_class, widget_name,
X			   callback_name, (caddr_t *) target,
X			   "CuWlmGetInt", CuWlmGetIntType, connection_type) ;
X}
X
Xvoid
XCuWlmGetString (ww, connection_type, widget_class, widget_name,
X		   callback_name, target)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    String *target ;
X{
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmGetString requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xget_int_float_string (ww, widget_class, widget_name,
X			   callback_name, (caddr_t *) target,
X			   "CuWlmGetString", CuWlmGetStringType, connection_type) ;
Xreturn ;
X}
X
X/***** **** *** ** * CuWlmGetScan * ** *** **** *****/
X
Xvoid
XCuWlmGetScan (ww, connection_type,
X	widget_class, widget_name, callback_name, format,
X	t0, t1, t2, t3, t4, t5, t6, t7, t8, t9,
X	t10, t11, t12, t13, t14, t15, t16, t17, t18, t19)
X    CuWlmWidget ww ;
X    CuWlmConnectionType connection_type ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    String format ;
X    caddr_t t0,  t1,  t2,  t3,  t4,  t5,  t6,  t7,  t8,  t9,
X	    t10, t11, t12, t13, t14, t15, t16, t17, t18, t19 ;
X{
XCuWlmScanRecord *record ;
XWidget callback_widget ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmGetScan requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xcallback_widget = get_callback_widget (ww, widget_class, widget_name,
X					callback_name) ;
Xif (callback_widget != NULL)
X    {
X    record = (CuWlmScanRecord *) XtMalloc (sizeof (CuWlmScanRecord)) ;
X    Cu_copy_ds (&record->format, format) ;
X    record->t0 = t0 ; record->t1 = t1 ; record->t2 = t2 ;
X    record->t3 = t3 ; record->t4 = t4 ; record->t5 = t5 ;
X    record->t6 = t6 ; record->t7 = t7 ; record->t8 = t8 ;
X    record->t9 = t9 ; record->t10 = t10 ; record->t11 = t11 ;
X    record->t12 = t12 ; record->t13 = t13 ; record->t14 = t14 ;
X    record->t15 = t15 ; record->t16 = t16 ; record->t17 = t17 ;
X    record->t18 = t18 ; record->t19 = t19 ;
X    record->ww = ww ;
X    record->wlm_type = connection_type ;
X    XtAddCallback (callback_widget, callback_name,
X		   callback_scan, (caddr_t) record) ;
X    if ((int)connection_type & (int)CuWlmSampling)
X	{
X	add_to_sample_list (ww, widget_class, callback_widget) ;
X	}
X    }
Xelse
X    {
X    callback_not_found_warning ("CuWlmGetScan", widget_class, widget_name,
X				callback_name) ;
X    }
X
Xreturn ;
X}
X
X/**
X ** Convenience Functions
X **/
X
X/***** **** *** ** * CuWlmInquireWidget * ** *** **** *****/
X
XWidget
XCuWlmInquireWidget (ww, widget_class, widget_name)
X    CuWlmWidget ww ;
X    String widget_class ;
X    String widget_name ;
X{
XWidgetClassList *class_list ;
XWidgetNameList *name_list ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmInquireWidget requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xclass_list = get_widget_class_list (&ww->wlm.widget_class_list,
X	      XrmStringToQuark(widget_class), CuWlmNullOnNotFound) ;
Xif (class_list == NULL)
X    {
X    sprintf (error_text, "CuWlmInquireWidget: Class (%s) not found\n",
X		widget_class) ;
X    XtWarning (error_text) ;
X    return NULL ;
X    }
X
Xname_list = get_widget_name_list (class_list, widget_name, CuWlmNullOnNotFound);
Xif (name_list == NULL)
X    {
X    sprintf (error_text,
X		"CuWlmInquireWidget: Name (%s) not found in Class (%s)\n",
X		 widget_name, widget_class) ;
X    XtWarning (error_text) ;
X    return NULL ;
X    }
X
X/* TODO: for now just return the first one */
Xreturn name_list->widget_id_list->id ;
X}
X
X/***** **** *** ** * CuWlmSetValue * ** *** **** *****/
X
Xvoid
XCuWlmSetValue (ww, widget_class, widget_name, resource_name, resource_value)
X    CuWlmWidget ww ;
X    String widget_class ;
X    String widget_name ;
X    String resource_name ;
X    String resource_value ;
X{
XArg arg ;
XWidgetClassList *class_list ;
XWidgetNameList *name_list ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmSetValue requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xclass_list = get_widget_class_list (&ww->wlm.widget_class_list,
X	      XrmStringToQuark(widget_class), CuWlmNullOnNotFound) ;
Xif (class_list == NULL)
X    {
X    sprintf (error_text, "CuWlmSetValue: Class (%s) not found\n", widget_class) ;
X    XtWarning (error_text) ;
X    return ;
X    }
X
Xname_list = get_widget_name_list (class_list, widget_name, CuWlmNullOnNotFound);
Xif (name_list == NULL)
X    {
X    sprintf (error_text, "CuWlmSetValue: Name (%s) not found in Class (%s)\n",
X	     widget_name, widget_class) ;
X    XtWarning (error_text) ;
X    return ;
X    }
X
X/* TODO: for now just do it on the first one */
Xconvert_string_to_arg (ww,
X	get_resource_info (XtClass(name_list->widget_id_list->id),
X			   resource_name, CuWlmResourceInfoRepresentation),
X	resource_name, resource_value, &arg) ;
XXtSetValues (name_list->widget_id_list->id, &arg, ONE) ;
Xmy_sync() ;
Xreturn ;
X}
X
X/***** **** *** ** * CuWlmGetValue * ** *** **** *****/
X
Xvoid
XCuWlmGetValue (ww, widget_class, widget_name, resource_name, target)
X    CuWlmWidget ww ;
X    String widget_class ;
X    String widget_name ;
X    String resource_name ;
X    caddr_t target ;
X{
XArg arg ;
XWidgetClassList *class_list ;
XWidgetNameList *name_list ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X    XtError("CuWlmGetValue requires arg0 to be subclass of cuWlmWidgetClass");
X    }
Xclass_list = get_widget_class_list (&ww->wlm.widget_class_list,
X	      XrmStringToQuark(widget_class), CuWlmNullOnNotFound) ;
Xif (class_list == NULL)
X    {
X    sprintf (error_text, "CuWlmGetValue: Class (%s) not found\n", widget_class) ;
X    XtWarning (error_text) ;
X    return ;
X    }
X
Xname_list = get_widget_name_list (class_list, widget_name, CuWlmNullOnNotFound);
Xif (name_list == NULL)
X    {
X    sprintf (error_text, "CuWlmGetValue: Name (%s) not found in Class (%s)\n",
X	     widget_name, widget_class) ;
X    XtWarning (error_text) ;
X    return ;
X    }
X
Xarg.name = resource_name ;
Xarg.value = (XtArgVal) target ;
X/* TODO: for now just inquire of the first one */
XXtGetValues (name_list->widget_id_list->id, &arg, ONE) ;
X
Xreturn ;
X}
X
X/**
X ** private functions to the public functions
X **/
X
Xstatic void
Xadd_to_sample_list (ww, widget_class, callback_widget)
X    CuWlmWidget ww ;
X    String widget_class ;
X    Widget callback_widget ;
X{
XWidgetClassList *class_list ;
XXtProc procedure ;
X
X/* TODO: all strings to quarks */
X/*
X * TODO: for each widget class, have an entry for the sample procedure.
X *       no reason to do a full scale search every time
X */
Xclass_list = get_widget_class_list (&ww->wlm.widget_class_list,
X	      XrmStringToQuark(widget_class), CuWlmCroakOnNotFound) ;
Xprocedure = get_proc_list (class_list->proc_list, "Sample") ;
Xif (procedure)
X    {
X    CuWlmSampleList *sample_list ;
X    CuWlmSampleList *save ;
X
X    sample_list = (CuWlmSampleList *) XtMalloc (sizeof (CuWlmSampleList)) ;
X    sample_list->sample_proc = procedure ;
X    sample_list->id = callback_widget ;
X    save = ww->wlm.sample_list ;
X    ww->wlm.sample_list = sample_list ;
X    sample_list->next = save ;
X    }
Xelse
X    {
X    sprintf (error_text, "%s\n%s: (%s)\n",
X	"No sample routine in the widget class for which",
X	"a sample has been requested",
X	widget_class) ;
X    }
Xreturn ;
X}
X
Xstatic Widget
Xget_callback_widget (ww, widget_class, widget_name, callback_name)
X    CuWlmWidget ww ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X{
XWidget id = get_widget_id (ww, widget_class, widget_name) ;
XXtCallbackStatus status = XtHasCallbacks (id, callback_name) ;
Xif (status == XtCallbackNoList)
X    {
X    sprintf (error_text, "Widget (%s/%s) does not have a callback (%s)\n",
X    widget_class, widget_name, callback_name) ;
X    XtWarning (error_text) ;
X    return NULL ;
X    }
Xreturn id ;
X}
X
Xstatic void
Xget_int_float_string (ww, widget_class, widget_name,
X			   callback_name, target,
X			   text, get_type, wlm_type)
X    CuWlmWidget ww ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X    caddr_t *target ;
X    String text ;
X    CuWlmGetType get_type ;
X    CuWlmConnectionType wlm_type ;
X{
XCuWlmGetRecord *record ;
XWidget callback_widget ;
X
Xcallback_widget = get_callback_widget (ww, widget_class, widget_name,
X					callback_name) ;
Xif (callback_widget != NULL)
X    {
X    record = (CuWlmGetRecord *) XtMalloc (sizeof (CuWlmGetRecord)) ;
X    record->type = get_type ;
X    record->target = (caddr_t) target ;
X    record->ww = ww ;
X    record->wlm_type = wlm_type ;
X    XtAddCallback (callback_widget, callback_name,
X		   callback_get, (caddr_t) record) ;
X    if ((int)wlm_type & (int)CuWlmSampling)
X	{
X	add_to_sample_list (ww, widget_class, callback_widget) ;
X	}
X    }
Xelse
X    {
X    callback_not_found_warning (text, widget_class, widget_name,
X				callback_name) ;
X    }
X
Xreturn ;
X}
X
Xstatic void
Xcallback_indirect (w, client, call)
X    Widget w ;
X    caddr_t client ;
X    caddr_t call ;
X{
XCuWlmIndirectRecord *record = (CuWlmIndirectRecord *) client ;
Xif (record->ww->wlm.sre_status == NULL)
X    {
X    /* save this action if there are no requests oustanding */
X    enqueue_event (&record->ww->wlm.queue_ptr, CuWlmIndirectQueue,
X		   w, client, call) ;
X    }
Xelse
X    {
X    if (record->ww->wlm.history_mode == CuWlmRecordHistory)
X	enqueue_event (&record->ww->wlm.history_ptr, CuWlmIndirectQueue,
X		       w, client, call) ;
X    (*record->callback_proc) (w, record->client_data, call) ;
X    record->ww->wlm.sre_status->status = CuWlmRequestSatisfied ;
X    }
X
Xreturn ;
X}
X
Xstatic void
Xcallback_set_float (w, client, call)
X    Widget w ;
X    caddr_t client ;
X    caddr_t call ;
X{
XCuWlmSetFloatRecord *record = (CuWlmSetFloatRecord *) client ;
Xif (record->ww->wlm.sre_status == NULL)
X    {
X    /* save this action if there are no requests oustanding */
X    enqueue_event (&record->ww->wlm.queue_ptr, CuWlmSetFloatQueue,
X		   w, client, call) ;
X    }
Xelse
X    {
X    if (record->ww->wlm.history_mode == CuWlmRecordHistory)
X	enqueue_event (&record->ww->wlm.history_ptr, CuWlmSetFloatQueue,
X		       w, client, call) ;
X    *(record->target) = record->value ;
X    if (!((int)record->wlm_type & (int)CuWlmBypass))
X	record->ww->wlm.sre_status->status = CuWlmRequestSatisfied ;
X    }
X
Xreturn ;
X}
X
Xstatic void
Xcallback_set_bool (w, client, call)
X    Widget w ;
X    caddr_t client ;
X    caddr_t call ;
X{
XCuWlmSetBoolRecord *record = (CuWlmSetBoolRecord *) client ;
Xif (record->ww->wlm.sre_status == NULL)
X    {
X    /* save this action if there are no requests oustanding */
X    enqueue_event (&record->ww->wlm.queue_ptr, CuWlmSetBoolQueue,
X		   w, client, call) ;
X    }
Xelse
X    {
X    if (record->ww->wlm.history_mode == CuWlmRecordHistory)
X	enqueue_event (&record->ww->wlm.history_ptr, CuWlmSetBoolQueue,
X		       w, client, call) ;
X    *(record->target) = record->value ;
X    if (!((int)record->wlm_type & (int)CuWlmBypass))
X	record->ww->wlm.sre_status->status = CuWlmRequestSatisfied ;
X    }
X
Xreturn ;
X}
X
Xstatic void
Xcallback_set_int (w, client, call)
X    Widget w ;
X    caddr_t client ;
X    caddr_t call ;
X{
XCuWlmSetIntRecord *record = (CuWlmSetIntRecord *) client ;
Xif (record->ww->wlm.sre_status == NULL)
X    {
X    /* save this action if there are no requests oustanding */
X    enqueue_event (&record->ww->wlm.queue_ptr, CuWlmSetIntQueue, w, client, call) ;
X    }
Xelse
X    {
X    if (record->ww->wlm.history_mode == CuWlmRecordHistory)
X	enqueue_event (&record->ww->wlm.history_ptr, CuWlmSetIntQueue,
X		       w, client, call) ;
X    *(record->target) = record->value ;
X    if (!((int)record->wlm_type & (int)CuWlmBypass))
X	record->ww->wlm.sre_status->status = CuWlmRequestSatisfied ;
X    }
X
Xreturn ;
X}
X
Xstatic void
Xcallback_set_string (w, client, call)
X    Widget w ;
X    caddr_t client ;
X    caddr_t call ;
X{
XCuWlmSetStringRecord *record = (CuWlmSetStringRecord *) client ;
X
X/*** If we could trust the client programmer not to pass us a garbage
X *** pointer initially, this would make sure that a lot of useless 
X *** Strings are not lying about.  But it will surely be disaster,
X *** since that kind of bug is extremely difficult to track down.
X *** (I could stick another field in CuWlmSetStringRecord that keeps
X ***  track of the number of times executed and free all strings after
X ***  the first...)
Xif (*(record->target))
X    XtFree (*(record->target)) ;
X***
X***/
Xif (record->ww->wlm.sre_status == NULL)
X    {
X    /* save this action if there are no requests oustanding */
X    enqueue_event (&record->ww->wlm.queue_ptr, CuWlmSetStringQueue,
X		   w, client, call) ;
X    }
Xelse
X    {
X    if (record->ww->wlm.history_mode == CuWlmRecordHistory)
X	enqueue_event (&record->ww->wlm.history_ptr, CuWlmSetStringQueue,
X		       w, client, call) ;
X    Cu_copy_ds (&(*(record->target)), record->value) ;
X    if (!((int)record->wlm_type & (int)CuWlmBypass))
X	record->ww->wlm.sre_status->status = CuWlmRequestSatisfied ;
X    }
X
Xreturn ;
X}
X
Xstatic void
Xcallback_get (w, client, call)
X    Widget w ;
X    caddr_t client ;
X    caddr_t call ;
X{
XCuWlmGetRecord *record = (CuWlmGetRecord *) client ;
Xif (record->ww->wlm.sre_status == NULL && !record->ww->wlm.sampling_active)
X    {
X    /* save this action if there are no requests oustanding */
X    /* and if sampling is not active */
X    enqueue_event (&record->ww->wlm.queue_ptr, CuWlmGetQueue, w, client, call) ;
X    }
Xelse
X    {
X    union {
X	  caddr_t caddr;
X	  int	  i ;
X	  float   f ;
X	  String  s ;
X	  } uni ;
X    uni.caddr = call ;
X
X    if (record->ww->wlm.history_mode == CuWlmRecordHistory)
X	enqueue_event (&record->ww->wlm.history_ptr, CuWlmGetQueue,
X		       w, client, call) ;
X
X    switch (record->type)
X      {
X      case CuWlmGetBoolType :
X	{
X	*((Boolean *) record->target) = (Boolean) uni.i ;
X	break ;
X	}
X      case CuWlmGetIntType :
X	{
X	*((int *) record->target) = uni.i ;
X	break ;
X	}
X      case CuWlmGetFloatType :
X	{
X	*((float *) record->target) = uni.f ;
X	break ;
X	}
X      case CuWlmGetStringType :
X	{
X	Cu_copy_ds (&(*((String *) record->target)), uni.s) ;
X	break ;
X	}
X      }
X    if (!((int)record->wlm_type & (int)CuWlmBypass) &&
X	!record->ww->wlm.sampling_active)
X	{
X	record->ww->wlm.sre_status->status = CuWlmRequestSatisfied ;
X	}
X    }
X
Xreturn ;
X}
X
Xstatic void
Xcallback_scan (w, client, call)
X    Widget w ;
X    caddr_t client ;
X    caddr_t call ;
X{
XCuWlmScanRecord *record = (CuWlmScanRecord *) client ;
Xif (record->ww->wlm.sre_status == NULL)
X    {
X    /* save this action if there are no requests oustanding */
X    enqueue_event (&record->ww->wlm.queue_ptr, CuWlmScanQueue, w, client, call) ;
X    }
Xelse
X    {
X    if (record->ww->wlm.history_mode == CuWlmRecordHistory)
X	enqueue_event (&record->ww->wlm.history_ptr, CuWlmScanQueue,
X		       w, client, call) ;
X    sscanf (*((String *) call), record->format,
X	record->t0, record->t1, record->t2, record->t3,
X	record->t4, record->t5, record->t6, record->t7,
X	record->t8, record->t9, record->t10, record->t11,
X	record->t12, record->t13, record->t14, record->t15,
X	record->t16, record->t17, record->t18, record->t19) ;
X    if (!((int)record->wlm_type & (int)CuWlmBypass))
X	record->ww->wlm.sre_status->status = CuWlmRequestSatisfied ;
X    }
X
Xreturn ;
X}
X
Xstatic void
Xcallback_not_found_warning (func, widget_class, widget_name, callback_name)
X    String func ;
X    String widget_class ;
X    String widget_name ;
X    String callback_name ;
X{
Xsprintf (error_text, "%s%s(),%s\n%s(%s)\n%s(%s)\n%s(%s)\n",
X"While doing a ", func, " the following callback was not found:",
X"    Widget Class  : ", widget_class,
X"    Widget Name   : ", widget_name,
X"    Callback Name : ", callback_name) ;
XXtWarning (error_text) ;
Xreturn ;
X}
X
Xstatic void
Xenqueue_event (wlm_queue_ptr, type, w, client, call)
X    CuWlmQueueRecord **wlm_queue_ptr ;
X    CuWlmQueueType type ;
X    Widget w ;
X    caddr_t client ;
X    caddr_t call ;
X{
XCuWlmQueueRecord *save ;
XCuWlmQueueRecord *queue_record ;
X
Xqueue_record = (CuWlmQueueRecord *) XtMalloc (sizeof (CuWlmQueueRecord)) ;
Xqueue_record->type = type ;
Xqueue_record->w = w ;
Xqueue_record->client = client ;
Xqueue_record->call = call ;
Xsave = *wlm_queue_ptr ;
X*wlm_queue_ptr = queue_record ;
Xqueue_record->next = save ;
X
Xreturn ;
X}
X
Xstatic void
Xdequeue_event (ww)
X    CuWlmWidget ww ;
X{
XCuWlmQueueRecord *record = ww->wlm.queue_ptr ;
XCuWlmSreRecord *save ;
X
Xif (record == NULL)
X    {
X    XtError ("??? Attempt to dequeue from an empty queue ???\n") ;
X    }
X
Xww->wlm.queue_ptr = record->next ;
X
Xsave = ww->wlm.sre_status ;
Xww->wlm.sre_status = (CuWlmSreRecord *) XtMalloc (sizeof (CuWlmSreRecord)) ;
Xww->wlm.sre_status->status = CuWlmRequestNotSatisfied ;
Xww->wlm.sre_status->next = save ;
X
Xswitch (record->type)
X  {
X  case CuWlmIndirectQueue :
X    {
X    callback_indirect (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmSetFloatQueue :
X    {
X    callback_set_float (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmSetIntQueue :
X    {
X    callback_set_int (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmSetStringQueue :
X    {
X    callback_set_string (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmGetQueue :
X    {
X    callback_get (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmScanQueue :
X    {
X    callback_scan (record->w, record->client, record->call) ;
X    break ;
X    }
X  default :
X    {
X    }
X  }
X
XXtFree (record) ;
Xsave = ww->wlm.sre_status ;
Xww->wlm.sre_status = ww->wlm.sre_status->next ;
XXtFree (save) ;
X
Xreturn ;
X}
X
X/* Undo has not yet been implemented! */
X
Xstatic void
Xundo (ww)
X    CuWlmWidget ww ;
X{
XCuWlmQueueRecord *record = ww->wlm.history_ptr ;
XCuWlmSreRecord *save ;
X
Xif (record == NULL)
X    {
X    XtError ("??? Attempt to undo from an empty queue ???\n") ;
X    }
X
Xww->wlm.history_ptr = record->next ;
X
Xsave = ww->wlm.sre_status ;
Xww->wlm.sre_status = (CuWlmSreRecord *) XtMalloc (sizeof (CuWlmSreRecord)) ;
Xww->wlm.sre_status->status = CuWlmRequestNotSatisfied ;
Xww->wlm.sre_status->next = save ;
X
Xswitch (record->type)
X  {
X  case CuWlmIndirectQueue :
X    {
X    callback_indirect (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmSetFloatQueue :
X    {
X    callback_set_float (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmSetIntQueue :
X    {
X    callback_set_int (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmSetStringQueue :
X    {
X    callback_set_string (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmGetQueue :
X    {
X    callback_get (record->w, record->client, record->call) ;
X    break ;
X    }
X  case CuWlmScanQueue :
X    {
X    callback_scan (record->w, record->client, record->call) ;
X    break ;
X    }
X  default :
X    {
X    }
X  }
X
XXtFree (record) ;
Xsave = ww->wlm.sre_status ;
Xww->wlm.sre_status = ww->wlm.sre_status->next ;
XXtFree (save) ;
X
Xreturn ;
X}
X
Xstatic void
Xmy_sync ()
X{
Xwhile (XtPending())
X    {

END_OF_FILE
echo shar: NEWLINE appended to \"'src/CuWlm.c.ac'\"
if test 26752 -ne `wc -c <'src/CuWlm.c.ac'`; then
    echo shar: \"'src/CuWlm.c.ac'\" unpacked with wrong size!
fi
# end of 'src/CuWlm.c.ac'
fi
echo shar: End of archive 4 \(of 12\).
cp /dev/null ark4isdone
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