v03i078: Xcu -- widget set from Cornell University, Part02/12
Dan Heller
argv at island.uu.net
Tue Apr 25 09:56:49 AEST 1989
Submitted-by: Gene Dykes <gdykes at tcgould.tn.cornell.edu>
Posting-number: Volume 3, Issue 78
Archive-name: xcu/part02
#! /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 at 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 2 (of 12)."
# Contents: src/CuTbl.c.ab src/CuWlm.c.ab wlmCompiler/wlc.l
# Wrapped by argv at island on Mon Apr 24 15:41:26 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'src/CuTbl.c.ab' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/CuTbl.c.ab'\"
else
echo shar: Extracting \"'src/CuTbl.c.ab'\" \(27239 characters\)
sed "s/^X//" >'src/CuTbl.c.ab' <<'END_OF_FILE'
X
X arbs = (int *) XtMalloc (cols[i] * sizeof(int)) ;
X for (j=0; j < cols[i]; j++)
X {
X CuTblConstraints constraint =
X (CuTblConstraints) (item[i][j].pw->core.constraints) ;
X if (constraint->tbl.fill_column)
X {
X arbs[n_arbs++] = j ;
X }
X }
X
X if (n_arbs && !tw->tbl.equal_cols[i])
X {
X Cardinal i_arb ;
X int arb_adjustment ;
X
X arb_adjustment = (int) ((float) (needed_width - r_width[i]) /
X n_arbs + 0.5) ;
X /*
X * adjust each one by its proportion of the slack, except for the
X * last, which must take up enough to make up for round-off errors
X */
X for (i_arb=0; i_arb < n_arbs-1; i_arb++)
X {
X item[i][arbs[i_arb]].width += arb_adjustment ;
X }
X item[i][arbs[n_arbs-1]].width += (needed_width - r_width[i] -
X (n_arbs-1)*arb_adjustment) ;
X XtFree ((char *)arbs) ;
X continue ;
X }
X
X XtFree ((char *)arbs) ;
X
X /* else everybody has to adjust */
X
X if (tw->tbl.equal_cols[i])
X {
X /* Doesn't include the two outermost children borders */
X slack = needed_width - (cols[i] - 1) * (tw->tbl.inter_width +
X 2 * tw->tbl.typical_border) ;
X portions = (int *) XtMalloc (cols[i] * sizeof(int)) ;
X
X e_apportion_slack (slack, cols[i], portions) ;
X
X for (j=0; j < cols[i]; j++)
X {
X if (item[i][j].primary == TBL_ITEM ||
X item[i][j].primary == TBL_HSPAN)
X {
X if (item[i][j].primary == TBL_ITEM)
X {
X last_item = j ;
X item[i][last_item].width = 0 ;
X }
X else
X {
X item[i][last_item].width +=
X (tw->tbl.inter_width + 2 * tw->tbl.typical_border) ;
X }
X item[i][last_item].width += portions[j] ;
X }
X }
X XtFree ((char *) portions) ;
X }
X else
X {
X int last_child = -1 ;
X int padding = (tw->tbl.r_item[i] - 1) *
X (tw->tbl.inter_width + 2 * tw->tbl.typical_border) ;
X
X for (j=0; j < cols[i]; j++)
X {
X last_child = j ;
X /* each item is expanded by its proportion of width */
X item[i][j].width = (int)((float) (needed_width - padding) /
X (r_width[i] - padding) * item[i][j].width + 0.5) ;
X }
X
X if (!tw->tbl.equal_cols[i] && last_child >= 0)
X {
X /* need to adjust the last item in this row to take up any slack */
X int adj ;
X int wide = 0 ;
X
X for (j=0; j < cols[i]; j++)
X {
X if (j == 0 || item[i][j].pw != item[i][j-1].pw)
X {
X wide += item[item[i][j].pi][item[i][j].pj].width ;
X }
X }
X adj = needed_width - wide -
X (tw->tbl.r_item[i] - 1) *
X (tw->tbl.inter_width + 2 * tw->tbl.typical_border) ;
X item[i][last_child].width += adj ;
X }
X }
X }
X
X/*
X * Now, do the same thing for row equalization
X * The process for the rows is somewhat simpler since there can not be a
X * variable number of rows per column (except that caused by spanning).
X */
X
X/* Step 1 : find the min height needed for each row */
X
Xfor (i=0; i < tw->tbl.rows; i++)
X {
X Cardinal j ;
X r_height[i] = 0 ;
X for (j=0; j < cols[i]; j++)
X {
X if (item[i][j].primary == TBL_ITEM)
X {
X int child_height ;
X CuTblConstraints constraint ;
X child = item[i][j].pw ;
X constraint = (CuTblConstraints)child->core.constraints;
X
X /* height of a row is its largest child */
X child_height = item[i][j].height / constraint->tbl.span_height ;
X if (child_height > r_height[i])
X r_height[i] = child_height ;
X }
X else
X if (item[i][j].primary == TBL_VSPAN)
X {
X /*
X * Need to include proper fraction of vertically spanned items
X * Simple because it is illegal to have a variable number of columns
X * during vertical spanning
X */
X int child_height ;
X CuTblConstraints constraint =
X (CuTblConstraints)item[i][j].pw->core.constraints;
X
X child_height = item[i][j].height / constraint->tbl.span_height ;
X if (tw->tbl.equal_rows == True)
X child_height = item[i][j].height ;
X if (child_height > r_height[i])
X r_height[i] = child_height ;
X }
X }
X if (r_height[i] > max_r_height)
X max_r_height = r_height[i] ;
X }
X
X/* if keyword "equal_row_key", all rows changed to maximum row height */
Xif (tw->tbl.equal_rows == True)
X {
X for (i=0; i < tw->tbl.rows; i++)
X {
X r_height[i] = max_r_height ;
X }
X }
X
X/* Now adjust each row to fit within its specified height */
X
Xfor (i=0; i < tw->tbl.rows; i++)
X {
X Cardinal j ;
X for (j=0; j < cols[i]; j++)
X {
X if (item[i][j].primary == TBL_ITEM)
X {
X int ii ;
X int sum_height = 0 ;
X CuTblConstraints constraint ;
X child = item[i][j].pw ;
X constraint = (CuTblConstraints)child->core.constraints;
X
X for (ii=0; ii < constraint->tbl.span_height; ii++)
X {
X sum_height += r_height[i+ii] ;
X }
X sum_height +=
X (constraint->tbl.span_height - 1) *
X (tw->tbl.inter_height + 2 * tw->tbl.typical_border) ;
X if (XtIsManaged(child))
X {
X item[i][j].height = sum_height ;
X }
X }
X }
X }
X
Xtw->tbl.standalone_width = needed_width +
X 2 * tw->tbl.typical_border +
X 2 * tw->tbl.internal_width ;
X
X/* Now one final pass to add in allowances for borders and padding */
X
Xtw->tbl.standalone_height = 0 ;
Xfor (i=0; i < tw->tbl.rows; i++)
X {
X Widget last_pw = NULL ;
X Cardinal j ;
X
X tw->tbl.standalone_height += r_height[i] ;
X for (j=0; j < cols[i]; j++)
X {
X if (item[i][j].primary == TBL_ITEM)
X {
X if (XtIsManaged(item[i][j].pw))
X {
X CuTblConstraints constraint =
X (CuTblConstraints) item[i][j].pw->core.constraints ;
X constraint->tbl.sts_width = item[i][j].width ;
X constraint->tbl.sts_height = item[i][j].height ;
X }
X }
X if (item[i][j].pw != last_pw)
X {
X last_pw = item[i][j].pw ;
X }
X }
X }
X
Xtw->tbl.standalone_height += (tw->tbl.rows-1) * tw->tbl.inter_height +
X 2 * tw->tbl.internal_height +
X 2 * tw->tbl.rows * tw->tbl.typical_border ;
X
X/*
X * cleanup
X */
X
XXtFree ((char *)r_width) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * Trial_ETS * ** *** **** *****/
X
Xstatic void
XTrial_ETS (tw)
X CuTblWidget tw ;
X{
XCardinal i ;
Xint c_slack ; /* Can't be "Dimension" */
Xint r_slack ;
Xint *p_r_slack = (int *) XtMalloc (tw->tbl.rows * sizeof(int)) ;
Xint *r_height = tw->tbl.r_height ;
Xfloat c_expansion ;
Xfloat r_expansion ;
Xint internal_width = tw->tbl.internal_width ;
Xint internal_height = tw->tbl.internal_height ;
Xint inter_width = tw->tbl.inter_width ;
Xint inter_height = tw->tbl.inter_height ;
Xint inter_width_delta ;
Xint inter_height_delta ;
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 tbl)
X * 3) Expand the interWidgetWidth,Height (spreads them out)
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/smaller (the slack) than the minimum we are.
X */
X
X/* height */
X
Xif (tw->core.height == 0)
X tw->core.height = tw->tbl.standalone_height ;
X
Xif (tw->core.height < tw->tbl.standalone_height && tw->tbl.clip_on_shrink)
X tw->tbl.new_height = tw->tbl.standalone_height ;
Xelse
X tw->tbl.new_height = tw->core.height ;
X
Xr_expansion = (float) tw->tbl.new_height / tw->tbl.standalone_height ;
Xr_slack = tw->tbl.new_height - tw->tbl.standalone_height ;
X
X/* width */
X
Xif (tw->core.width == 0)
X tw->core.width = tw->tbl.standalone_width ;
X
Xif (tw->core.width < tw->tbl.standalone_width && tw->tbl.clip_on_shrink)
X tw->tbl.new_width = tw->tbl.standalone_width ;
Xelse
X tw->tbl.new_width = tw->core.width ;
X
Xc_expansion = (float) tw->tbl.new_width / tw->tbl.standalone_width ;
Xc_slack = tw->tbl.new_width - tw->tbl.standalone_width ;
X
X/*
X * Depending on what is allowed to change,
X * compute new padding parameters
X */
X
Xif ((int)tw->tbl.resize_participants & (int)CuResizeInternals)
X {
X if (((int)tw->tbl.resize_participants & (int)CuResizeInters) &&
X ((int)tw->tbl.resize_participants & (int)CuResizeChildren))
X {
X /* internal padding and inter-widget just expand proportionately */
X internal_height = tw->tbl.internal_height * r_expansion ;
X inter_height = tw->tbl.inter_height * r_expansion ;
X r_slack -= 2 * (internal_height - tw->tbl.internal_height) ;
X r_slack -= (tw->tbl.rows - 1) *
X (inter_height - tw->tbl.inter_height) ;
X
X internal_width = tw->tbl.internal_width * c_expansion ;
X inter_width = tw->tbl.inter_width * c_expansion ;
X c_slack -= 2 * (internal_width - tw->tbl.internal_width) ;
X c_slack -= (tw->tbl.max_cols - 1) *
X (inter_width - tw->tbl.inter_width) ;
X }
X else
X if (!((int)tw->tbl.resize_participants & (int)CuResizeInters) &&
X ((int)tw->tbl.resize_participants & (int)CuResizeChildren))
X {
X /*
X * For now, internal padding just expands proportionately.
X * That means widgets will have to expand just a bit more than
X * their fair share (also expanding for all of inters' share)
X * This should be quite an adequate approximation
X */
X internal_height = tw->tbl.internal_height * r_expansion ;
X r_slack -= 2 * (internal_height - tw->tbl.internal_height) ;
X
X internal_width = tw->tbl.internal_width * c_expansion ;
X c_slack -= 2 * (internal_width - tw->tbl.internal_width) ;
X }
X else
X if ( ((int)tw->tbl.resize_participants & (int)CuResizeInters) &&
X !((int)tw->tbl.resize_participants & (int)CuResizeChildren))
X {
X /* split up the slack between inter widget and internals */
X int row_num_participants = (tw->tbl.rows - 1) + 2 ;
X int col_num_participants = (tw->tbl.max_cols - 1) + 2 ;
X inter_height = tw->tbl.inter_height +
X r_slack / row_num_participants ;
X internal_height =
X tw->tbl.internal_height +
X (r_slack -
X (inter_height - tw->tbl.inter_height) *
X (row_num_participants - 2)) / 2 ;
X r_slack -= (2 * (internal_height - tw->tbl.internal_height) +
X (row_num_participants - 2) *
X (inter_height - tw->tbl.inter_height)) ;
X
X inter_width = tw->tbl.inter_width +
X c_slack / col_num_participants ;
X internal_width =
X tw->tbl.internal_width +
X (c_slack -
X (inter_width - tw->tbl.inter_width) *
X (col_num_participants - 2)) / 2 ;
X c_slack -= (2 * (internal_width - tw->tbl.internal_width) +
X (col_num_participants - 2) *
X (inter_width - tw->tbl.inter_width)) ;
X }
X else
X {
X /* internal padding takes up all the slack */
X internal_height = tw->tbl.internal_height + r_slack/2 ;
X r_slack -= 2 * (internal_height - tw->tbl.internal_height) ;
X
X internal_width = tw->tbl.internal_width + c_slack/2 ;
X c_slack -= 2 * (internal_width - tw->tbl.internal_width) ;
X }
X }
Xelse
Xif ((int)tw->tbl.resize_participants & (int)CuResizeInters)
X {
X if ((int)tw->tbl.resize_participants & (int)CuResizeChildren)
X {
X /*
X * For now, inter widget padding just expands proportionately.
X * That means widgets will have to expand just a bit more than
X * their fair share (also expanding for all of internals' share)
X * This should be quite an adequate approximation
X */
X if (tw->tbl.inter_height > 0)
X inter_height = tw->tbl.inter_height * r_expansion ;
X r_slack -= (tw->tbl.max_cols - 1) *
X (inter_height - tw->tbl.inter_height) ;
X
X if (tw->tbl.inter_width > 0)
X inter_width = tw->tbl.inter_width * c_expansion ;
X c_slack -= (tw->tbl.max_cols - 1) *
X (inter_width - tw->tbl.inter_width) ;
X }
X else
X {
X /* inter widget padding takes up all the slack */
X if (tw->tbl.rows > 1)
X inter_height = tw->tbl.inter_height + r_slack /
X (int) (tw->tbl.rows - 1) ;
X r_slack -= (tw->tbl.rows - 1) *
X (inter_height - tw->tbl.inter_height) ;
X
X if (tw->tbl.max_cols > 1)
X {
X inter_width = tw->tbl.inter_width + c_slack /
X (int) (tw->tbl.max_cols - 1) ;
X }
X c_slack -= (tw->tbl.max_cols - 1) *
X (inter_width - tw->tbl.inter_width) ;
X }
X }
X
Xinter_width_delta = inter_width - tw->tbl.inter_width ;
Xinter_height_delta = inter_height - tw->tbl.inter_height ;
X
X/*
X * else widgets take up all the slack
X */
X
Xv_apportion_slack (r_slack, tw->tbl.rows, p_r_slack, r_height) ;
X
Xfor (i=0; i < tw->tbl.rows; i++)
X {
X int *p_c_slack = (int *)XtMalloc(tw->tbl.cols[i] * sizeof (int)) ;
X Cardinal j ;
X Cardinal slack_ptr = 0 ;
X int this_c_slack ;
X
X /*
X * we need to apportion the slack evenly over the widgets in the row
X * ( if the columns were supposed to be even, I suppose a one pixel
X * difference won't be too bad. E.g., adding a slack of two pixels
X * to 3 even columns will result in the last column being one short.
X * Insisting on rounding up the slack is conceivable but would probably
X * result in more extensive negotiations in the hierarchy. I'll yield
X * unilaterally.)
X */
X
X this_c_slack = c_slack +
X inter_width_delta * (tw->tbl.max_cols - tw->tbl.cols[i]) ;
X /*
X * If the items in the row are of variable lengths we want to apportion
X * the slack in proportion to the width of each item, but
X * if the row has "equal_cols" then we want to allocate the space equally
X * for each column.
X */
X if (tw->tbl.equal_cols[i])
X {
X e_apportion_slack (this_c_slack, tw->tbl.cols[i], p_c_slack) ;
X for (j=0; j < tw->tbl.cols[i]; j++)
X {
X if (tw->tbl.item[i][j].primary == TBL_ITEM)
X {
X if (XtIsManaged(tw->tbl.item[i][j].pw))
X {
X Cardinal k ;
X CuTblConstraints constraint =
X (CuTblConstraints) tw->tbl.item[i][j].pw->core.constraints ;
X constraint->tbl.ets_width = constraint->tbl.sts_width ;
X for (k=0; k < constraint->tbl.span_width; k++)
X {
X /*
X * Add in the appropriate slack for each column entry
X * that it spans
X */
X constraint->tbl.ets_width += p_c_slack[slack_ptr++] ;
X if (k != 0)
X {
X /*
X * Also add in the amount of space between entries
X */
X constraint->tbl.ets_width += inter_width_delta ;
X }
X }
X
X /* similar computation for rows */
X
X constraint->tbl.ets_height = constraint->tbl.sts_height ;
X for (k=0; k < constraint->tbl.span_height; k++)
X {
X constraint->tbl.ets_height += p_r_slack[i+k] ;
X if (k != 0)
X {
X constraint->tbl.ets_height += inter_height_delta ;
X }
X }
X }
X }
X }
X }
X else
X {
X int n_widths = 0 ;
X int *r_widths = (int *) XtMalloc (tw->tbl.cols[i] * sizeof(int)) ;
X
X /* Find the widths of the true items in this row */
X for (j=0; j < tw->tbl.cols[i]; j++)
X {
X if (tw->tbl.item[i][j].primary == TBL_ITEM)
X {
X if (XtIsManaged(tw->tbl.item[i][j].pw))
X {
X CuTblConstraints constraint =
X (CuTblConstraints)tw->tbl.item[i][j].pw->core.constraints;
X r_widths[n_widths++] = constraint->tbl.sts_width ;
X }
X }
X }
X
X v_apportion_slack (this_c_slack, n_widths, p_c_slack, r_widths) ;
X
X for (j=0; j < tw->tbl.cols[i]; j++)
X {
X if (tw->tbl.item[i][j].primary == TBL_ITEM)
X {
X if (XtIsManaged(tw->tbl.item[i][j].pw))
X {
X Cardinal k ;
X CuTblConstraints constraint =
X (CuTblConstraints) tw->tbl.item[i][j].pw->core.constraints ;
X constraint->tbl.ets_width = constraint->tbl.sts_width ;
X constraint->tbl.ets_width += p_c_slack[slack_ptr++] ;
X
X /* similar computation for rows */
X
X constraint->tbl.ets_height = constraint->tbl.sts_height ;
X for (k=0; k < constraint->tbl.span_height; k++)
X {
X constraint->tbl.ets_height += p_r_slack[i+k] ;
X if (k != 0)
X {
X constraint->tbl.ets_height += inter_height_delta ;
X }
X }
X }
X }
X }
X }
X
X XtFree ((char *) p_c_slack) ;
X }
XXtFree ((char *) p_r_slack) ;
X
X/*
X * Now to actually configure the children...
X */
X
X {
X Position current_y = internal_height ;
X Position *e_current_y = NULL ;
X Boolean vspan_current = False ;
X
X for (i=0; i < tw->tbl.rows; i++)
X {
X Widget last_pw = NULL ;
X Position current_x = internal_width ;
X Cardinal j ;
X CuTblConstraints constraint =
X (CuTblConstraints) tw->tbl.item[i][0].pw->core.constraints ;
X
X /*
X * If this is the first row of a series of rows with equal columns...
X */
X
X if (!vspan_current &&
X (tw->tbl.vspan_status[i] && (i == 0 || !tw->tbl.vspan_status[i-1])))
X {
X vspan_current = True ;
X e_current_y = (Position *)
X XtMalloc (tw->tbl.cols[i] * sizeof (Position)) ;
X for (j=0; j < tw->tbl.cols[i]; j++)
X e_current_y[j] = current_y ;
X }
X
X /*
X * else if this is the first row of a series of rows with unequal columns...
X */
X
X else
X if (vspan_current &&
X (!tw->tbl.vspan_status[i] && (i == 0 || tw->tbl.vspan_status[i-1])))
X {
X vspan_current = False ;
X if (e_current_y)
X {
X current_y = e_current_y[0] ; /* all should be the same */
X XtFree ((char *) e_current_y) ;
X e_current_y = NULL ;
X }
X }
X
X /*
X * if vspan_current and a new number of columns...
X */
X
X if (vspan_current &&
X i != 0 &&
X tw->tbl.cols[i] != tw->tbl.cols[i-1] &&
X tw->tbl.vspan_status[i-1])
X {
X current_y = e_current_y[0] ;
X XtFree ((char *) e_current_y) ;
X e_current_y = (Position *)
X XtMalloc (tw->tbl.cols[i] * sizeof (Position)) ;
X for (j=0; j < tw->tbl.cols[i]; j++)
X e_current_y[j] = current_y ;
X }
X
X for (j=0; j < tw->tbl.cols[i]; j++)
X {
X CuTblConstraints constraint =
X (CuTblConstraints) tw->tbl.item[i][j].pw->core.constraints ;
X if (tw->tbl.item[i][j].primary == TBL_ITEM)
X {
X if (XtIsManaged(tw->tbl.item[i][j].pw))
X {
X Position this_y ;
X this_y = vspan_current ? e_current_y[j] : current_y ;
X constraint->tbl.ets_x = current_x ;
X constraint->tbl.ets_y = this_y ;
X }
X }
X
X if (vspan_current && (tw->tbl.item[i][j].primary == TBL_ITEM ||
X tw->tbl.item[i][j].primary == TBL_HSPAN))
X {
X e_current_y[j] += constraint->tbl.ets_height +
X inter_height + 2*tw->tbl.typical_border ;
X }
X if (tw->tbl.item[i][j].pw != last_pw)
X {
X current_x += constraint->tbl.ets_width + inter_width +
X 2*tw->tbl.typical_border ;
X last_pw = tw->tbl.item[i][j].pw ;
X }
X }
X
X if (!vspan_current)
X {
X current_y += constraint->tbl.ets_height +
X inter_height + 2*tw->tbl.typical_border ;
X }
X }
X if (e_current_y)
X {
X XtFree ((char *) e_current_y) ;
X }
X }
X
Xreturn ;
X}
X
X/***** **** *** ** * DoLayout * ** *** **** *****/
X
Xstatic void
XDoLayout (tw, requesting_widget)
X CuTblWidget tw ;
X Widget requesting_widget ;
X{
Xint num_children = tw->composite.num_children;
XWidgetList children = tw->composite.children;
XWidget *childP;
X
X/* Use ConfigureWidget on siblings, modify requester directly */
X
Xfor (childP = children; childP - children < num_children; childP++)
X {
X CuTblConstraints twc = (CuTblConstraints)(*childP)->core.constraints;
X
X if (!XtIsManaged(*childP))
X continue ;
X
X if (*childP != requesting_widget)
X {
X XtConfigureWidget (*childP, twc->tbl.ets_x, twc->tbl.ets_y,
X (Dimension) twc->tbl.ets_width,
X (Dimension) twc->tbl.ets_height,
X (Dimension) tw->tbl.typical_border) ;
X }
X else
X {
X requesting_widget->core.x = twc->tbl.ets_x ;
X requesting_widget->core.y = twc->tbl.ets_y ;
X requesting_widget->core.width = twc->tbl.ets_width ;
X requesting_widget->core.height = twc->tbl.ets_height ;
X requesting_widget->core.border_width = tw->tbl.typical_border ;
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 /***
X XtConfigureWidget (*childP, twc->tbl.ets_x, twc->tbl.ets_y,
X (Dimension) twc->tbl.ets_width,
X (Dimension) twc->tbl.ets_height,
X (Dimension) tw->tbl.typical_border) ;
X ***/
X }
X }
X
Xtw->core.width = tw->tbl.new_width ;
Xtw->core.height = tw->tbl.new_height ;
X
Xreturn ;
X}
X
X/***** **** *** ** * adjust_aligned_columns * ** *** **** *****/
X
Xstatic Boolean
Xadjust_aligned_columns (tw)
X CuTblWidget tw ;
X{
X/*
X * All items in a column need to be the same width if aligned_columns is True
X * Therefore, find biggest member in each column,
X * and set all items of the column to that width.
X */
XCardinal i, j ;
XBoolean change_value = False ;
X
Xif (!tw->tbl.aligned_columns)
X return False ;
X
Xfor (j=0; j < tw->tbl.cols[0]; j++)
X {
X int max_width = 0 ;
X int max_adj_width = 0 ;
X for (i=0; i < tw->tbl.rows; i++)
X {
X if (tw->tbl.item[i][j].adj_width > max_adj_width)
X {
X max_width = tw->tbl.item[i][j].width ;
X max_adj_width = tw->tbl.item[i][j].adj_width ;
X }
X }
X
X for (i=0; i < tw->tbl.rows; i++)
X {
X if (tw->tbl.item[i][j].adj_width < max_adj_width)
X {
X change_value = True ;
X tw->tbl.item[i][j].adj_width = max_adj_width ;
X tw->tbl.item[i][j].width = max_width ;
X }
X }
X }
Xreturn change_value ;
X}
X
X/***** **** *** ** * adjust_equal_columns * ** *** **** *****/
X
Xstatic Boolean
Xadjust_equal_columns (tw)
X CuTblWidget tw ;
X{
X/*
X * All columns in a row marked with an 'e', need to be same width.
X * Therefore, find biggest member, and set all members of the set to that width.
X */
XCardinal i, j ;
XBoolean change_value = False ;
X
Xfor (i=0; i < tw->tbl.rows; i++)
X {
X int max_width = 0 ;
X int max_adj_width = 0 ;
X for (j=0; j < tw->tbl.cols[i]; j++)
X {
X if (tw->tbl.item[i][j].e && tw->tbl.item[i][j].adj_width >max_adj_width)
X {
X max_width = tw->tbl.item[i][j].width ;
X max_adj_width = tw->tbl.item[i][j].adj_width ;
X }
X }
X
X /* Only need to adjust if some columns were marked */
X if (max_width > 0)
X {
X for (j=0; j < tw->tbl.cols[i]; j++)
X {
X if (tw->tbl.item[i][j].e && tw->tbl.item[i][j].adj_width <
X max_adj_width)
X {
X change_value = True ;
X tw->tbl.item[i][j].adj_width = max_adj_width ;
X tw->tbl.item[i][j].width = max_width ;
X }
X }
X }
X }
Xreturn change_value ;
X}
X
X/***** **** *** ** * adjust_spanned_columns * ** *** **** *****/
X
Xstatic Boolean
Xadjust_spanned_columns (tw)
X CuTblWidget tw ;
X{
X/*
X * All corresponding columns in spanned rows need to be same width.
X * Therefore, find biggest member, and set all members of the set to that width.
X */
XCardinal i, j ;
XBoolean change_value = False ;
X
Xfor (i=0; i < tw->tbl.rows; i++)
X {
X Cardinal ii = i ;
X /*
X * Look for the start of a spanning run
X */
X if (tw->tbl.vspan_status[i] && (i == 0 || !tw->tbl.vspan_status[i-1]))
X {
X /*
X * For each column, search down through the spans
X */
X for (j=0; j < tw->tbl.cols[i]; j++)
X {
X int max_width = 0 ;
X int max_adj_width = 0 ;
X int filled_columns = 0 ;
X for (ii=i; ii < tw->tbl.rows && tw->tbl.vspan_status[ii]; ii++)
X {
X CuTblConstraints constraint =
X (CuTblConstraints)tw->tbl.item[ii][j].pw->core.constraints ;
X if (constraint->tbl.fill_column)
X filled_columns++ ;
X if (tw->tbl.item[ii][j].primary == TBL_ITEM &&
X tw->tbl.item[ii][j].adj_width > max_adj_width)
X {
X max_adj_width = tw->tbl.item[ii][j].adj_width ;
X max_width = tw->tbl.item[ii][j].width ;
X }
X }
X /*
X * If some, but not all, of the entries in this column's spanning
X * run were set to take up slack, then they must all be so set...
X */
X if (filled_columns > 0 && filled_columns < ii - i)
X {
X for (ii=i; ii < tw->tbl.rows && tw->tbl.vspan_status[ii]; ii++)
X {
X CuTblConstraints constraint =
X (CuTblConstraints)tw->tbl.item[ii][j].pw->core.constraints;
X constraint->tbl.fill_column = True ;
X }
X }
X /* Only need to adjust if some columns were marked */
X if (max_adj_width > 0)
X {
X for (ii=i; ii < tw->tbl.rows && tw->tbl.vspan_status[ii]; ii++)
X {
X if (tw->tbl.item[ii][j].primary != TBL_HSPAN &&
X tw->tbl.item[ii][j].adj_width < max_adj_width)
X {
X change_value = True ;
X tw->tbl.item[ii][j].adj_width = max_adj_width ;
X tw->tbl.item[ii][j].width = max_width ;
X }
X }
X }
X }
X }
X i = ii ; /* bump past the spanning run */
X }
Xreturn change_value ;
X}
X
X/***** **** *** ** * v_apportion_slack * ** *** **** *****/
X
Xstatic void
Xv_apportion_slack (slack, n, portions, widths)
X int slack ;
X int n ;
X int *portions ;
X int *widths ;
X{
XCardinal i ;
Xfloat exact_portion ;
Xfloat running_exact_portion = 0.0 ;
Xint apportioned = 0 ;
Xint total_width = 0 ;
X
Xfor (i=0; i < n; i++)
X total_width += widths[i] ;
X
Xfor (i=0; i < n-1; i++)
X {
X exact_portion = (float) widths[i] / total_width * slack ;
X running_exact_portion += exact_portion ;
X portions[i] = running_exact_portion - apportioned ;
X apportioned += portions[i] ;
X }
X
Xportions[n-1] = slack - apportioned ;
Xreturn ;
X}
X
X/***** **** *** ** * e_apportion_slack * ** *** **** *****/
X
Xstatic void
Xe_apportion_slack (slack, n, portions)
X int slack ;
X int n ;
X int *portions ;
X{
XCardinal i ;
Xfloat exact_portion = ((float) slack + 0.999) / n ;
Xfloat running_exact_portion = 0.0 ;
Xint apportioned = 0 ;
X
Xfor (i=0; i < n; i++)
X {
X running_exact_portion += exact_portion ;
X portions[i] = running_exact_portion - apportioned ;
X apportioned += portions[i] ;
X }
X
Xreturn ;
X}
X
X/***** **** *** ** * SetupLayout * ** *** **** *****/
X
Xstatic void
XSetupLayout (tw)
X CuTblWidget tw ;
X{
X/*
X * Don't want to count children that have:
X * core/mappedWhenManaged "False"
X * and
X * constraint/layoutWhenUnmapped "False"
X */
X
Xif (tw->tbl.format_file != NULL)
X {
X /*
X * Layout is contained in a file.
X * We'll read the file as one big string.
X */
X FILE *fd ;
X struct stat buf ;
X
X tw->tbl.format_mode = TBL_STRING_FORMAT ;
X fd = fopen (tw->tbl.format_file, "r") ;
X if (fd <= 0)
X {
X char *my_text = "CuTbl: Couldn't open (%s) for reading\n" ;
X char *etext = XtMalloc (strlen(my_text) + strlen(tw->tbl.format_file)) ;
X sprintf (etext, my_text, tw->tbl.format_file) ;
X XtError (etext) ;
X }
X fstat (fileno(fd), &buf) ;
X layout_input->input_buffer = XtMalloc (buf.st_size + 1) ;
X fread (layout_input->input_buffer, (int)buf.st_size, 1, fd) ;
X layout_input->input_buffer[buf.st_size] = '\0' ;
X layout_input->string_file = (int) TBL_FILE_FORMAT ;
X
X Cu_copy_ds (&layout_input->cur_file, tw->tbl.format_file) ;
X XtFree (tw->tbl.format_file) ;
X tw->tbl.format_file = NULL ;
X
X fclose (fd) ;
X }
Xelse
Xif (tw->tbl.format_string != NULL)
X {
X /*
X * Layout is contained in a string.
X */
X tw->tbl.format_mode = TBL_STRING_FORMAT ;
X Cu_copy_ds (&layout_input->cur_file, "(String Resource)") ;
X layout_input->input_buffer = tw->tbl.format_string ;
X layout_input->string_file = (int) TBL_STRING_FORMAT ;
X }
Xelse
Xif (tw->tbl.format_mode == TBL_FIRST_PASS)
X {
X /* default to a row of widgets */
X Cardinal i ;
X tw->tbl.format_mode = TBL_STRING_FORMAT ;
X Cu_copy_ds (&layout_input->cur_file, "(Default Resource)") ;
X tw->tbl.format_string = XtCalloc (tw->composite.num_children * 2 + 2,
X sizeof(char)) ;
X layout_input->input_buffer = tw->tbl.format_string ;
END_OF_FILE
echo shar: NEWLINE appended to \"'src/CuTbl.c.ab'\"
if test 27240 -ne `wc -c <'src/CuTbl.c.ab'`; then
echo shar: \"'src/CuTbl.c.ab'\" unpacked with wrong size!
fi
# end of 'src/CuTbl.c.ab'
fi
if test -f 'src/CuWlm.c.ab' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'src/CuWlm.c.ab'\"
else
echo shar: Extracting \"'src/CuWlm.c.ab'\" \(23487 characters\)
sed "s/^X//" >'src/CuWlm.c.ab' <<'END_OF_FILE'
X }
Xelse
Xif (not_found_action == CuWlmNullOnNotFound)
X {
X return NULL ;
X }
X/* if here, no list found, so we add one */
X
Xwidget_id_list = (WidgetIdList *) XtMalloc (sizeof (WidgetIdList)) ;
Xwidget_id_list->id = widget_id ;
Xwidget_id_list->next = NULL ;
X*last_ptr = widget_id_list ;
X
Xreturn widget_id_list ;
X}
X
X/***** **** *** ** * bmgr_search * ** *** **** *****/
X
Xstatic void
Xbmgr_search (ww, child)
X CuWlmWidget ww ;
X Fetus *child ;
X{
Xint i ; /* must not be Cardinal */
Xif (child->class_name == Bmgr_quark)
X bmgr_setup (ww, child) ;
X
Xfor (i = child->n_children - 1; i >=0; i--)
X bmgr_search (ww, &child->children[i]) ;
X
Xreturn;
X}
X
X/***** **** *** ** * directive_search * ** *** **** *****/
X
Xstatic void
Xdirective_search (ww, child)
X Fetus *child ;
X CuWlmWidget ww ;
X{
Xint i ; /* must not be Cardinal */
Xif (child->directives)
X directive_setup (ww, child) ;
X
Xfor (i = child->n_children - 1; i >=0; i--)
X directive_search (ww, &child->children[i]) ;
X
Xreturn;
X}
X
X/***** **** *** ** * bmgr_setup * ** *** **** *****/
X
Xstatic void
Xbmgr_setup (ww, child)
X CuWlmWidget ww ;
X Fetus *child ;
X{
XCuButtonWidget *button_list ;
Xcaddr_t *value_list ;
Xint i ;
X
X/*
X * Look widgets up in a list of name/id pairs.
X */
X
Xif (!child->n_manage_list)
X {
X char text[200] ;
X sprintf (text, "CuWlm: Bmgr (%s) with no children!\n", child->widget_name) ;
X XtError (text) ;
X }
Xbutton_list = (CuButtonWidget *) XtMalloc (child->n_manage_list * sizeof (CuButtonWidget)) ;
Xvalue_list = (caddr_t *) XtMalloc (child->n_manage_list * sizeof (caddr_t)) ;
X
Xfor (i=0; i < child->n_manage_list; i++)
X {
X Arg arg ;
X button_list[i] = (CuButtonWidget)
X get_widget_id(ww, "CuButton", child->manage_list[i].widget);
X if (child->manage_list[i].type != NULL)
X {
X convert_string_to_arg (ww, child->manage_list[i].type, "",
X child->manage_list[i].value, &arg) ;
X value_list[i] = (caddr_t) arg.value ;
X }
X else
X {
X value_list[i] = NULL ;
X }
X }
X
XCuBmgrManage ((CuBmgrWidget)child->id, button_list, value_list,
X child->n_manage_list) ;
Xreturn ;
X}
X
X/***** **** *** ** * directive_setup * ** *** **** *****/
X
Xstatic void
Xdirective_setup (ww, child)
X CuWlmWidget ww ;
X Fetus *child ;
X{
XCardinal i, j ;
X
Xfor (i=0; i < child->n_directives; i++)
X {
X Directive *directive = &child->directives[i] ;
X /*
X * for each unique callback in the directives, add a callback
X */
X for (j=0; j < i; j++)
X {
X if (strcmp (child->directives[i].callback_name,
X child->directives[j].callback_name) == 0)
X break ;
X }
X if (j == i)
X {
X directive->client_data[0] = (long) ww ;
X directive->client_data[1] =
X (long) directive->callback_name ;
X directive->client_data[2] = (long) child ;
X XtAddCallback (child->id, directive->callback_name,
X wlm_central, (caddr_t) directive->client_data) ;
X add_to_sample_list (ww, XrmQuarkToString(child->class_name), child->id);
X }
X }
Xreturn ;
X}
X
X/***** **** *** ** * wlm_central * ** *** **** *****/
X
Xstatic void
Xwlm_central (w, client, call)
X Widget w ;
X caddr_t client ; /* [0] is the wlm widget,
X * [1] is the callback_name,
X * [2] is the child
X */
X caddr_t call ;
X{
XCardinal i ;
Xlong *long_client = (long *) client ;
XCuWlmWidget ww = (CuWlmWidget) long_client[0] ;
XString call_callback = (String) long_client[1] ;
XFetus *child = (Fetus *) long_client[2] ;
XWidget id ;
X
X/*
X * Check for directive actions
X */
X
Xfor (i=0; i < child->n_directives; i++)
X {
X Cardinal j ;
X Directive *directive = &child->directives[i] ;
X if (strcmp(directive->callback_name, call_callback) != 0)
X continue ; /* not the callback for this directive */
X
X /*
X * We need to check each comparison -- all must be true to trigger action
X */
X for (j=0; j < directive->n_call_comparisons; j++)
X {
X Boolean comparison ;
X int k ; /* Must not be Cardinal */
X CuWlmArgType case_number ;
X caddr_t **ptr ;
X Arg arg ;
X /*
X * 1) convert call_data to real data via call_data_converter
X * 2) find data in caller
X * 3) compare using call_data_operator
X */
X case_number = convert_string_to_arg
X (ww, directive->call_data_converter[j],
X "", directive->call_data[j], &arg) ;
X /*
X * For each index except the last, do a dereference
X * WARNING: This code assumes that all pointers are created equal...
X */
X ptr = (caddr_t **) call ;
X for (k=0; k < (int)directive->n_call_indices[j] - 1; k++)
X {
X ptr = (caddr_t **) *(call + directive->call_data_index[j][k]) ;
X }
X
X /*
X * For the last dereference, we absolutely must branch according
X * to type...
X * TODO: For now,
X * these are hardwired, but eventually they will be generated
X * by a compile-time preprocessor and included...
X */
X
X switch (case_number)
X {
X case CuWlmArgValArg :
X {
X XtArgVal value ;
X if (directive->n_call_indices[j] == 0)
X {
X union { caddr_t **ptr ; XtArgVal value ; } uni ;
X uni.ptr = ptr ;
X value = uni.value ;
X }
X else
X value = *(((XtArgVal *)ptr) + directive->call_data_index[j][k]);
X switch (directive->call_data_operator[j])
X {
X case CuWlmDirectiveEquivalence :
X {
X comparison = (value == arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveNonEquivalence :
X {
X comparison = (value != arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveGreaterThan :
X {
X comparison = (value > arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveLessThan :
X {
X comparison = (value < arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveGreaterThanOrEqualTo :
X {
X comparison = (value >= arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveLessThanOrEqualTo :
X {
X comparison = (value <= arg.value ? True : False) ;
X break ;
X }
X }
X break ;
X }
X case CuWlmFloatArg :
X {
X /*
X * This seems like a disgusting hack, but...
X */
X float value ;
X float arg_value ;
X union { XtArgVal i ; float f ; } i_to_f ;
X
X i_to_f.i = arg.value ;
X arg_value = i_to_f.f ;
X
X if (directive->n_call_indices[j] == 0)
X {
X union { caddr_t **ptr ; float value ; } uni ;
X uni.ptr = ptr ;
X value = uni.value ;
X }
X else
X {
X value = *(((float *) ptr) + directive->call_data_index[j][k]) ;
X }
X
X switch (directive->call_data_operator[j])
X {
X case CuWlmDirectiveEquivalence :
X {
X comparison = (value == arg_value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveNonEquivalence :
X {
X comparison = (value != arg_value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveGreaterThan :
X {
X comparison = (value > arg_value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveLessThan :
X {
X comparison = (value < arg_value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveGreaterThanOrEqualTo :
X {
X comparison = (value >= arg_value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveLessThanOrEqualTo :
X {
X comparison = (value <= arg_value ? True : False) ;
X break ;
X }
X }
X break ;
X }
X case CuWlmCharArg :
X {
X char value ;
X if (directive->n_call_indices[j] == 0)
X {
X union { caddr_t **ptr ; char value ; } uni ;
X uni.ptr = ptr ;
X value = uni.value ;
X }
X else
X value = *(((char *) ptr) + directive->call_data_index[j][k]) ;
X switch (directive->call_data_operator[j])
X {
X case CuWlmDirectiveEquivalence :
X {
X comparison = (value == arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveNonEquivalence :
X {
X comparison = (value != arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveGreaterThan :
X {
X comparison = (value > arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveLessThan :
X {
X comparison = (value < arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveGreaterThanOrEqualTo :
X {
X comparison = (value >= arg.value ? True : False) ;
X break ;
X }
X case CuWlmDirectiveLessThanOrEqualTo :
X {
X comparison = (value <= arg.value ? True : False) ;
X break ;
X }
X }
X break ;
X }
X case CuWlmStringArg :
X {
X String value ;
X if (directive->n_call_indices[j] == 0)
X {
X union { caddr_t **ptr ; String value ; } uni ;
X uni.ptr = ptr ;
X value = uni.value ;
X }
X else
X value = *(((String *) ptr) + directive->call_data_index[j][k]) ;
X switch (directive->call_data_operator[j])
X {
X case CuWlmDirectiveEquivalence :
X {
X comparison = (strcmp (value,
X (String) arg.value) == 0) ?
X True : False ;
X break ;
X }
X case CuWlmDirectiveNonEquivalence :
X {
X comparison = (strcmp (value,
X (String) arg.value) != 0) ?
X True : False ;
X break ;
X }
X }
X break ;
X }
X }
X
X
X if (comparison == False)
X break ;
X }
X
X if (j < directive->n_call_comparisons)
X {
X continue ; /* do nothing, there was something not matched */
X }
X /*
X * Action has been triggered
X * First find the target widget, then branch on the two possibilities
X */
X
X id = get_widget_id (ww, directive->target_class, directive->target_name) ;
X
X if (directive->resource.name)
X {
X /* The directive is to modify a widget's resource */
X Arg arg ;
X
X convert_string_to_arg (ww,
X get_resource_info (XtClass(id),
X directive->resource.name,
X CuWlmResourceInfoRepresentation),
X directive->resource.name,
X directive->resource.value, &arg) ;
X XtSetValues (id, &arg, ONE) ;
X }
X else
X {
X XrmValue string_value ;
X XrmValue converted_value ;
X Cardinal k ;
X#define MAX_WLM_PROCEDURE_ARGS 10
X Arg arg[MAX_WLM_PROCEDURE_ARGS] ;
X /* The directive is to call a widget's public procedure */
X string_value.addr = (caddr_t) directive->procedure ;
X string_value.size = strlen (string_value.addr) ;
X
X ww->wlm.conversion_class = XrmStringToQuark(directive->target_class) ;
X XtConvert ((Widget)ww, XtRString, &string_value,
X "Procedure", &converted_value) ;
X for (k=0; k < directive->n_arguments; k++)
X {
X convert_string_to_arg (ww,
X directive->argument_converters[k],
X "",
X directive->argument_strings[k],
X &arg[k]) ;
X }
X (*(*((XtProc *) converted_value.addr)))(id, arg[0].value,
X arg[1].value, arg[2].value, arg[3].value, arg[4].value, arg[5].value,
X arg[6].value, arg[7].value, arg[8].value, arg[9].value) ;
X }
X }
X
Xreturn ;
X}
X
X/***** **** *** ** * get_resource_info * ** *** **** *****/
X
X/*
X * given a widget class and a resource name,
X * this looks up the class of the resource
X */
X
Xstatic String
Xget_resource_info (class, name, info_type)
X WidgetClass class ;
X String name ;
X CuWlmResourceInfoType info_type ;
X{
XCardinal i ;
XXtResourceList t_resource ;
XCardinal nt_resource ;
XString t_info ;
X
X
XXtGetResourceList (class, &t_resource, &nt_resource) ;
X
Xfor (i=0; i < nt_resource; i++)
X {
X if (strcmp (name, t_resource[i].resource_name) == 0)
X break ;
X }
X
Xif (i == nt_resource)
X {
X return NULL ;
X }
X
Xif (info_type == CuWlmResourceInfoClass)
X {
X Cu_copy_ds (&t_info, t_resource[i].resource_class) ;
X }
Xelse
X {
X Cu_copy_ds (&t_info, t_resource[i].resource_type) ;
X }
X
XXtFree (t_resource) ;
X
Xreturn t_info ;
X}
X
X/***** **** *** ** * AddStringToWidgetConverter * ** *** **** *****/
X
Xstatic void
XAddStringToWidgetConverter (ww)
X CuWlmWidget ww ;
X{
XWidgetClassList *class_list ;
XXtConvertArgRec *widgetConvertArgs ;
X/*
X * for each widget class, add a converter
X */
Xfor (class_list = ww->wlm.widget_class_list;
X class_list != NULL;
X class_list = class_list->next)
X {
X widgetConvertArgs = (XtConvertArgRec *)
X XtMalloc (sizeof(XtConvertArgRec)) ;
X widgetConvertArgs->address_mode = XtAddress ;
X widgetConvertArgs->address_id = (caddr_t) class_list ;
X widgetConvertArgs->size = (Cardinal) sizeof(WidgetClassList *) ;
X
X XtAddConverter (XtRString, XrmQuarkToString (class_list->quark),
X CvtStringToWidget,
X widgetConvertArgs, ONE) ;
X }
Xreturn ;
X}
X
X/***** **** *** ** * AddStringToProcedureConverter * ** *** **** *****/
X
Xstatic void
XAddStringToProcedureConverter ()
X{
Xstatic XtConvertArgRec procedureConvertArgs[] =
X {
X {
X XtBaseOffset,
X (caddr_t) XtOffset (CuWlmWidget, wlm.widget_class_list),
X sizeof (WidgetClassList *)
X }
X ,{
X XtBaseOffset,
X (caddr_t) XtOffset (CuWlmWidget, wlm.conversion_class),
X sizeof (XrmQuark)
X }
X } ;
X
XXtAddConverter (XtRString, "Procedure", CvtStringToProcedure,
X procedureConvertArgs, XtNumber (procedureConvertArgs)) ;
Xreturn ;
X}
X
X/***** **** *** ** * CvtStringToWidget * ** *** **** *****/
X
X/*
X * Convert String To Widget
X * Given a widget name,
X * and the wlm class list of the widget,
X * It returns the first id in the IdList for the appropriate widget
X * TODO: How and whether or not to handle multiple id's
X */
X
Xstatic void
XCvtStringToWidget (args, num_args, fromVal, toVal)
X XrmValuePtr args ; /* contains the address of the class list */
X Cardinal *num_args ; /* unused */
X XrmValuePtr fromVal ;
X XrmValuePtr toVal ;
X{
XString widget_name = (String) fromVal->addr ;
X
XWidgetClassList *class_list = (WidgetClassList *) args[0].addr ;
XWidgetNameList *name_list ;
X
Xname_list = get_widget_name_list (class_list, widget_name, CuWlmCroakOnNotFound) ;
X
XtoVal->size = sizeof (WidgetIdList *) ;
XtoVal->addr = (caddr_t) &name_list->widget_id_list->id ;
X
Xreturn ;
X}
X
X/***** **** *** ** * CvtStringToProcedure * ** *** **** *****/
X
X/*
X * Convert String To Procedure
X * Given a procedure name
X * and the wlm procedure list of the wlm widget that contains the widget,
X * It returns the address of the appropriate public function
X */
X
Xstatic void
XCvtStringToProcedure (args, num_args, fromVal, toVal)
X XrmValuePtr args ; /* contains the address of the proc list */
X Cardinal *num_args ; /* unused */
X XrmValuePtr fromVal ;
X XrmValuePtr toVal ;
X{
XString proc_name = (String) fromVal->addr ;
XXrmQuark widget_class = *((XrmQuark *) args[1].addr) ;
XWidgetClassList *initial_class_list = *((WidgetClassList **) args[0].addr) ;
XWidgetClassList *class_list ;
X
Xstatic XtProc procedure ;
X
Xclass_list = get_widget_class_list (&initial_class_list, widget_class,
X CuWlmCroakOnNotFound) ;
Xprocedure = get_proc_list (class_list->proc_list, proc_name) ;
X
XtoVal->size = sizeof (WidgetIdList *) ;
XtoVal->addr = (caddr_t) &procedure ;
X
Xreturn ;
X}
X
X/**
X ** The routines to read in the compiled layout
X **/
X
X#define get_pad() *ptr += pad
X#define get_nl() (*ptr)++
X
X/***** **** *** ** * ParseCuWlmLayout * ** *** **** *****/
X
Xstatic void
XParseCuWlmLayout (ww)
X CuWlmWidget ww ;
X{
XString ptr ;
Xptr = layout_input->input_buffer ;
Xif (*ptr != '#' || *(ptr+1) != 'W' || *(ptr+2) != 'L' ||
X *(ptr+3) != 'D' || *(ptr+4) != 'L')
X {
X String errortext = XtMalloc (strlen(layout_input->file0) + 80) ;
X sprintf (errortext,
X "CuWlm: File specified (%s) is not a compiled layout file!\n",
X layout_input->file0) ;
X XtError (errortext) ;
X }
Xptr+=6 ;
X
Xww->wlm.max_depth = get_int (&ptr) ;
Xww->wlm.child = (Fetus *) XtCalloc (1, sizeof (Fetus)) ;
Xget_child (ww->wlm.child, &ptr, 0) ;
Xreturn ;
X}
X
X/***** **** *** ** * get_child * ** *** **** *****/
X
Xstatic void
Xget_child (child, ptr, pad)
X Fetus *child ;
X String *ptr ;
X int pad ;
X{
XCardinal i ;
X
Xget_nl() ;
Xget_pad() ;
Xchild->class_name = XrmStringToQuark (get_word(ptr)) ;
X
Xget_pad() ;
Xchild->n_resources = get_int(ptr) ;
X
Xif (child->n_resources)
Xchild->resources = (Resource *)
X XtMalloc (child->n_resources * sizeof (Resource)) ;
Xfor (i=0; i < child->n_resources; i++)
X {
X get_resource (&child->resources[i], ptr, pad) ;
X }
X
Xget_pad() ;
Xchild->n_directives = get_int(ptr) ;
X
Xif (child->n_directives)
Xchild->directives = (Directive *)
X XtMalloc (child->n_directives * sizeof (Directive)) ;
Xfor (i=0; i < child->n_directives; i++)
X get_directive (&child->directives[i], ptr, pad) ;
X
Xget_pad() ;
Xchild->n_manage_list = get_int(ptr) ;
X
Xif (child->n_manage_list)
Xchild->manage_list = (CuWlmManageItem *)
X XtMalloc (child->n_manage_list * sizeof (CuWlmManageItem)) ;
Xfor (i=0; i < child->n_manage_list; i++)
X get_manage (&child->manage_list[i], ptr, pad) ;
X
Xget_pad() ;
Xchild->n_children = get_int(ptr) ;
X
Xif (child->n_children)
Xchild->children = (Fetus *) XtCalloc (child->n_children, sizeof (Fetus)) ;
Xpad += 2 ;
Xfor (i=0; i < child->n_children; i++)
X get_child (&child->children[i], ptr, pad) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * get_int * ** *** **** *****/
X
Xstatic int
Xget_int (ptr)
X String *ptr ;
X{
Xint value ;
XString p = *ptr ;
X/*
X * ptr is now looking at something like: 5
X * Find the end of ascii integer and put a null there; use atoi to convert it.
X * Advance master pointer to point to just past that null,
X * and return the integer.
X */
X
Xwhile (*p != ' ' && *p != '\n')
X p++ ;
X*p = '\0';
Xvalue = atoi(*ptr) ;
X*ptr = p+1 ;
Xreturn value ;
X}
X
X/***** **** *** ** * get_word * ** *** **** *****/
X
Xstatic String
Xget_word (ptr)
X String *ptr ;
X{
Xint length ;
XString p ;
X/*
X * ptr is now looking at something like: 5 Label
X * Find the end of ascii integer and put a null there; use atoi to convert it.
X * Then put a null at the end of the word to be found.
X * Advance master pointer to point to just past that null,
X * and return a pointer to the word.
X */
X
Xlength = get_int(ptr) ;
Xp = *ptr ;
Xp[length] = '\0' ;
X*ptr = p + length + 1 ;
Xreturn p ;
X}
X
X/***** **** *** ** * get_string * ** *** **** *****/
X
Xstatic String
Xget_string (ptr)
X String *ptr ;
X{
Xint length ;
XString p ;
X/*
X * Same as get_word, but string is enclosed in parentheses
X */
X
Xlength = get_int(ptr) ;
Xp = *ptr + 1 ;
Xp[length] = '\0' ;
X*ptr = p + length + 2 ;
Xreturn p ;
X}
X
X/***** **** *** ** * get_resource * ** *** **** *****/
X
Xstatic void
Xget_resource (resource, ptr, pad)
X Resource *resource ;
X String *ptr ;
X int pad ;
X{
XString context ;
Xget_pad() ;
Xresource->name = get_word(ptr) ;
Xresource->value = get_string(ptr) ;
Xcontext = get_word(ptr) ;
Xresource->context = (strlen(context)==5) ? CuWlmLocalContext : CuWlmGlobalContext ;
X
Xreturn ;
X}
X
X/***** **** *** ** * get_directive * ** *** **** *****/
X
Xstatic void
Xget_directive (directive, ptr, pad)
X Directive *directive ;
X String *ptr ;
X int pad ;
X{
XCardinal i, j, n ;
XString dtype ;
X
Xget_pad() ;
Xdirective->callback_name = get_word(ptr) ;
Xdirective->target_class = get_word(ptr) ;
Xdirective->target_name = get_word(ptr) ;
Xn = directive->n_call_comparisons = get_int(ptr) ;
Xdtype = get_word(ptr) ;
X
Xpad++ ;
Xdirective->call_data_converter = (String *) XtMalloc (n * sizeof (String)) ;
Xdirective->call_data = (String *) XtMalloc (n * sizeof (String)) ;
Xdirective->call_data_operator = (CuWlmDirectiveOperator *)
X XtMalloc (n * sizeof (CuWlmDirectiveOperator)) ;
Xdirective->n_call_indices = (Cardinal *) XtMalloc (n * sizeof (Cardinal)) ;
Xdirective->call_data_index = (int **) XtMalloc (n * sizeof (int *)) ;
X
Xfor (i=0; i < n; i++)
X {
X String dummy ;
X get_pad() ;
X directive->call_data_converter[i] = get_word(ptr) ;
X directive->call_data[i] = get_string(ptr) ;
X directive->call_data_operator[i] = (CuWlmDirectiveOperator) get_int(ptr) ;
X dummy = get_word(ptr) ; /* there only for visualization of operator */
X directive->n_call_indices[i] = (Cardinal) get_int(ptr) ;
X (*ptr) += 2 ; /* skip the ": " */
X directive->call_data_index[i] =
X (int *) XtMalloc (directive->n_call_indices[i] * sizeof (int)) ;
X for (j=0; j < directive->n_call_indices[i]; j++)
X directive->call_data_index[i][j] = get_int(ptr) ;
X }
Xpad-- ;
X
Xget_pad() ;
Xif (strcmp(dtype, "XtSetValues") == 0)
X {
X directive->target_class = get_word(ptr) ;
X directive->target_name = get_string(ptr) ;
X directive->resource.name = get_word(ptr) ;
X directive->resource.value = get_string(ptr) ;
X }
Xelse
X {
X directive->resource.name = NULL ;
X directive->procedure = get_word(ptr) ;
X directive->n_arguments = get_int(ptr) ;
X directive->argument_converters =
X (String *) XtMalloc (directive->n_arguments * sizeof(String)) ;
X directive->argument_strings =
X (String *) XtMalloc (directive->n_arguments * sizeof(String)) ;
X for (i=0; i < directive->n_arguments; i++)
X {
X get_pad() ;
X directive->argument_converters[i] = get_word(ptr) ;
X directive->argument_strings[i] = get_string(ptr) ;
X }
X }
X
Xreturn ;
X}
X
X/***** **** *** ** * get_manage * ** *** **** *****/
X
Xstatic void
Xget_manage (managed, ptr, pad)
X CuWlmManageItem *managed ;
X String *ptr ;
X int pad ;
X{
Xget_pad() ;
Xmanaged->widget = get_string(ptr) ;
Xmanaged->type = get_word(ptr) ;
Xmanaged->value = get_string(ptr) ;
X
Xreturn ;
X}
X
X/**
X ***
X **** Public Procedures
X ***
X **/
X
X/**
X ** Device Functions
X **/
X
X/***** **** *** ** * CuWlmSample * ** *** **** *****/
X
Xvoid
XCuWlmSample (ww)
X CuWlmWidget ww ;
X{
XCuWlmSampleList *sample_list ;
X
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X XtError("CuWlmSample requires arg to be subclass of cuWlmWidgetClass");
X }
X
Xif (ww->wlm.first_device)
X {
X ww->wlm.first_device = False ;
X }
X
Xww->wlm.sampling_active = True ;
X
Xfor (sample_list=ww->wlm.sample_list;
X sample_list != NULL;
X sample_list = sample_list->next)
X {
X (*sample_list->sample_proc)(sample_list->id) ;
X }
X
Xww->wlm.sampling_active = False ;
X
Xreturn ;
X}
X
X/***** **** *** ** * CuWlmRequest * ** *** **** *****/
X
Xvoid
XCuWlmRequest (ww)
X CuWlmWidget ww ;
X{
XCuWlmSreRecord *save ;
X/*
X * if there is a wlmEvent already queued, return it
X * o.w., wait for something to happen
X */
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X XtError("CuWlmRequest requires arg to be subclass of cuWlmWidgetClass");
X }
Xif (ww->wlm.first_device)
X {
X CuWlmSample (ww) ;
X ww->wlm.first_device = False ;
X }
X
Xif (ww->wlm.queue_ptr != NULL)
X {
X dequeue_event (ww) ;
X ww->wlm.event_stamp++ ;
X return ;
X }
X
X/*
X * Since requests can be recursive, we have to keep a stack of them
X */
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
Xwhile (ww->wlm.sre_status->status == CuWlmRequestNotSatisfied)
X {
X XEvent event ;
X
X XtNextEvent (&event) ;
X XtDispatchEvent (&event) ;
X }
Xmy_sync () ;
X
Xww->wlm.event_stamp++ ;
Xsave = ww->wlm.sre_status ;
Xww->wlm.sre_status = ww->wlm.sre_status->next ;
XXtFree (save) ;
X
Xreturn ;
X}
X
X/***** **** *** ** * CuWlmEvent * ** *** **** *****/
X
XBoolean
XCuWlmEvent (ww)
X CuWlmWidget ww ;
X{
XCuWlmSreRecord *save ;
XBoolean return_status ;
X/*
X * if there is a wlmEvent already queued, return it
X * o.w., wait for something to happen
X */
Xif (!XtIsSubclass ((Widget)ww, (WidgetClass)cuWlmWidgetClass)) {
X XtError("CuWlmEvent requires arg to be subclass of cuWlmWidgetClass");
X }
Xif (ww->wlm.first_device)
X {
X CuWlmSample (ww) ;
X ww->wlm.first_device = False ;
X }
X
Xif (ww->wlm.queue_ptr != NULL)
X {
X dequeue_event (ww) ;
X return True ;
X }
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
Xif (XtPending())
X {
X /***
X XEvent event ;
X
X XtNextEvent (&event) ;
X XtDispatchEvent (&event) ;
X ***/
X my_sync () ;
X }
X
Xreturn_status = (ww->wlm.sre_status->status == CuWlmRequestSatisfied) ;
Xsave = ww->wlm.sre_status ;
Xww->wlm.sre_status = ww->wlm.sre_status->next ;
XXtFree (save) ;
X
END_OF_FILE
echo shar: NEWLINE appended to \"'src/CuWlm.c.ab'\"
if test 23488 -ne `wc -c <'src/CuWlm.c.ab'`; then
echo shar: \"'src/CuWlm.c.ab'\" unpacked with wrong size!
fi
# end of 'src/CuWlm.c.ab'
fi
if test -f 'wlmCompiler/wlc.l' -a "${1}" != "-c" ; then
echo shar: Will not clobber existing file \"'wlmCompiler/wlc.l'\"
else
echo shar: Extracting \"'wlmCompiler/wlc.l'\" \(1946 characters\)
sed "s/^X//" >'wlmCompiler/wlc.l' <<'END_OF_FILE'
X%{
X#define ManageContext 1
X#define DirectiveContext 2
Xstatic int oops_context ;
X
Xstatic void convert_nl () ;
X
Xstatic Boolean first_time = True ; /* recognizes the first time for yylex()*/
Xstatic Boolean nested_args = False ;
X
Xextern int lex_bug ;
X
Xstatic char *ttt ;
X
X#undef input
X#undef unput
X
X/***
X#include "y.tab.h"
X***/
X%}
X
X%START string
X
X%%
X
X"/*" /* look for start of comment */
X {
X char c ;
X for (;;)
X {
X while ((c = input()) != '*')
X ;
X if ((c = input()) == '/')
X break ;
X unput (c) ;
X }
X }
X
X["] /* look for start of string */
X {
X BEGIN string ;
X }
X
X<string>[^"]*\" /* anything but another quote */
X {
X yytext[yyleng-1] = '\0' ; /* trash the trailing quote */
X Cu_copy_ds (&ttt, yytext) ;
X convert_nl (ttt) ; /* convert '\' 'n' to '\n' and remove '\' '\n' */
X yylval.s_val = ttt ;
X
X BEGIN 0 ;
X return STRING ;
X }
X
Xif /* if keyword */
X {
X return IF_KEY ;
X }
X
XXtSetValues /* set_values keyword */
X {
X return SET_VALUES_KEY ;
X }
X
Xinclude /* include keyword */
X {
X return INCL_KEY ;
X }
X
Xmanage /* manage keyword */
X {
X return MANAGE_KEY ;
X }
X
X[^ \t\n\{\}\:\(\)\[\]\"\,\=\&\!\<\>\*]* /* item (anything but punctuation) */
X {
X Cu_copy_ds (&ttt, yytext) ;
X yylval.s_val = ttt ;
X return WORD ;
X }
X
X[\{\}\<\>\(\)\[\]\:\,\=\&\!\*] /* punctuation */
X {
X return (yytext[0]) ;
X }
X
X[ \n\t] /* white space */
X {
X ;
X }
X
X. {
X sprintf (error_text, "LEX returning ERROR on char (%c)\n", *yytext) ;
X XtWarning (error_text) ;
X return ERROR ;
X }
X%%
X
Xstatic void
Xconvert_nl (text)
X char *text ;
X{
XCardinal i ;
Xfor (i=0; i < strlen (text); i++)
X {
X if (text[i] == '\\' && text[i+1] == 'n')
X {
X Cardinal j ;
X text[i] = '\n' ;
X j = i+1 ;
X while (text[j] != 0)
X {
X text[j] = text[j+1] ;
X j++ ;
X }
X }
X else
X if (text[i] == '\\' && text[i+1] == '\n')
X {
X Cardinal j = i ;
X while (1)
X {
X text[j] = text[j+2] ;
X if (text[j] == '\0')
X break ;
X j++ ;
X }
X }
X }
Xreturn ;
X}
X
END_OF_FILE
echo shar: NEWLINE appended to \"'wlmCompiler/wlc.l'\"
if test 1947 -ne `wc -c <'wlmCompiler/wlc.l'`; then
echo shar: \"'wlmCompiler/wlc.l'\" unpacked with wrong size!
fi
# end of 'wlmCompiler/wlc.l'
fi
echo shar: End of archive 2 \(of 12\).
cp /dev/null ark2isdone
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
More information about the Comp.sources.x
mailing list