/*
* Motif
*
* Copyright (c) 1987-2012, The Open Group. All rights reserved.
*
* These libraries and programs are free software; you can
* redistribute them and/or modify them under the terms of the GNU
* Lesser General Public License as published by the Free Software
* Foundation; either version 2 of the License, or (at your option)
* any later version.
*
* These libraries and programs are distributed in the hope that
* they will be useful, but WITHOUT ANY WARRANTY; without even the
* implied warranty of MERCHANTABILITY or FITNESS FOR A PARTICULAR
* PURPOSE. See the GNU Lesser General Public License for more
* details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with these librararies and programs; if not, write
* to the Free Software Foundation, Inc., 51 Franklin Street, Fifth
* Floor, Boston, MA 02110-1301 USA
*
*/
#ifdef HAVE_CONFIG_H
#include <config.h>
#endif
#include <Xm/ColumnP.h>
#include <Xm/RowColumn.h>
#include <Xm/Label.h>
#include <Xm/VaSimpleP.h>
#include "XmI.h"
#define XK_LATIN1
#include <X11/keysymdef.h>
static void ClassInitialize(void);
static void Initialize(Widget, Widget, ArgList, Cardinal*);
static void ClassPartInitialize(WidgetClass w_class);
static Boolean SetValues(Widget, Widget, Widget, ArgList, Cardinal*);
static void Destroy(Widget);
static void Resize(Widget);
static XtGeometryResult QueryGeometry(Widget,
XtWidgetGeometry*, XtWidgetGeometry*);
static XtGeometryResult GeometryManager(Widget,
XtWidgetGeometry*, XtWidgetGeometry*);
static void ChangeManaged(Widget);
static void ConstraintInitialize(Widget, Widget, ArgList, Cardinal*);
static Boolean ConstraintSetValues(Widget, Widget, Widget, ArgList, Cardinal*);
static void ConstraintDestroy(Widget);
static void ConstraintGetValues(Widget, ArgList, Cardinal*);
static Boolean CvtStringToXiAlignment(
Display*, XrmValue*, Cardinal*, XrmValue*, XrmValue*, XtPointer
);
static Boolean CvtStringToFillStyle(
Display*, XrmValue*, Cardinal*, XrmValue*, XrmValue*, XtPointer
);
static Boolean CvtStringToDistribution(
Display*, XrmValue*, Cardinal*, XrmValue*, XrmValue*, XtPointer
);
static void Layout(
XmColumnWidget, Widget, XtWidgetGeometry*, int, int
);
static void HorizontalLayout(
XmColumnWidget, Widget, XtWidgetGeometry*, int, int
);
static void VerticalLayout(
XmColumnWidget, Widget, XtWidgetGeometry*, int, int
);
static void VerifyResources(
XmColumnWidget, XmColumnWidget, XmColumnWidget
);
static void VerifyConstraints(
Widget, Widget, Widget
);
static void CalcSize(
XmColumnWidget, Widget, XtWidgetGeometry*, Boolean, Dimension*, Dimension*
);
static Boolean CompareGeometry(
XtWidgetGeometry*, XtWidgetGeometry*
);
static Boolean CompareGeometryToWidget(
XtWidgetGeometry*, Widget
);
static void CheckSetEntryLabelRenderTable(Widget wid, int offs, XrmValue *value);
static void CheckSetDefaultEntryLabelRenderTable(Widget wid, int offs, XrmValue *value);
static void XmColumnLabelDestroyedCallback(
Widget, XtPointer, XtPointer
);
#if 0 /* POSITION HANDLING */
Note: this code was never finished and has been pulled out. The
public and semi-public traces have been pulled out of the header files.
Everything is marked with the #if used above.
#endif
#define BBPart(w) ((XmBulletinBoardPart*)(&(((XmBulletinBoardWidget)(w))->bulletin_board)))
#define XiC(w) ((XmColumnConstraintPart*)(&((XmColumnConstraintPtr)((w)->core.constraints))->column))
#define XiValidChild(c) (((c)) != NULL && XtIsManaged((c)) && \
!(c)->core.being_destroyed && \
XiC(c)->label_widget != NULL)
#define XmColumn(c) ((XmColumnWidget) XtParent((c)))
#define XiAlignment(c) ((XiC((c))->label_alignment == XmALIGNMENT_UNSPECIFIED) \
? XmColumn_default_label_alignment(XmColumn((c))) \
: XiC(c)->label_alignment)
#if 0 /* POSITION HANDLING */
#define XiPosition(c) ((XiC(c)->label_position == XiLABEL_POSITION_UNSPECIFIED)\
? XmColumn_default_label_position(XmColumn(c)) \
: XiC(c)->label_position)
#endif
#define XiFill(c) ((XiC(c)->fill_style == XmFILL_UNSPECIFIED)\
? XmColumn_default_fill_style(XmColumn(c)) \
: XiC(c)->fill_style)
#define XiWidth(c) (XtWidth(c) + 2 * XtBorderWidth(c))
#define XiHeight(c) (XtHeight(c) + 2 * XtBorderWidth(c))
#if 0 /* POSITION HANDLING */
/* from public .h file */
#define XiLABEL_POSITION_UNSPECIFIED 0
#define XiLABEL_POSITION_CENTER (1L<<0)
#define XiLABEL_POSITION_LEFT (1L<<1)
#define XiLABEL_POSITION_RIGHT (1L<<2)
#define XiLABEL_POSITION_TOP (1L<<3)
#define XiLABEL_POSITION_BOTTOM (1L<<4)
/* structure member elements from private P.h file */
unsigned char default_label_position;
unsigned char label_position;
#define XmColumnC_label_position(w) XmColCField(w, label_position, unsigned char)
#define XmColumn_default_label_position(w) XmColField(w, default_label_position, unsigned char)
#endif
#define DEFAULT_ALIGNMENT XmALIGNMENT_BEGINNING
#if 0 /* POSITION HANDLING */
#define DEFAULT_POSITION XiLABEL_POSITION_LEFT
#endif
#define DEFAULT_ORIENTATION XmVERTICAL
#define DEFAULT_FILL_STYLE XmFILL_RAGGED
static XtResource resources[] =
{
{
"pri.vate", "Pri.vate", XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmColumnRec, column.check_set_render_table),
XmRImmediate, (XtPointer) False
},
{
XmNdefaultEntryLabelFontList, XmCFontList, XmRFontList,
sizeof(XmFontList), XtOffsetOf(XmBulletinBoardRec, bulletin_board.label_font_list),
XmRCallProc, (XtPointer) CheckSetDefaultEntryLabelRenderTable
},
{
XmNdefaultEntryLabelRenderTable, XmCRenderTable, XmRRenderTable,
sizeof(XmRenderTable), XtOffsetOf(XmBulletinBoardRec, bulletin_board.label_font_list),
XmRCallProc, (XtPointer) CheckSetDefaultEntryLabelRenderTable
},
{
XmNdefaultEntryLabelAlignment, XmCAlignment, XmRXmAlignment,
sizeof(unsigned char), XtOffsetOf(XmColumnRec, column.default_label_alignment),
XmRImmediate, (XtPointer) DEFAULT_ALIGNMENT
},
#if 0 /* POSITION HANDLING */
{
XmNdefaultEntryLabelPosition, XmCEntryLabelPosition, XmRLabelPosition,
sizeof(unsigned char), XtOffsetOf(XmColumnRec, column.default_label_position),
XmRImmediate, (XtPointer) DEFAULT_POSITION
},
#endif
{
XmNdefaultFillStyle, XmCFillStyle, XmRFillStyle,
sizeof(unsigned char), XtOffsetOf(XmColumnRec, column.default_fill_style),
XmRImmediate, (XtPointer) DEFAULT_FILL_STYLE
},
{
XmNitemSpacing, XmCItemSpacing, XmRVerticalDimension,
sizeof(Dimension), XtOffsetOf(XmColumnRec, column.item_spacing),
XmRImmediate, (XtPointer) 2
},
{
XmNlabelSpacing, XmCLabelSpacing, XmRHorizontalDimension,
sizeof(Dimension), XtOffsetOf(XmColumnRec, column.label_spacing),
XmRImmediate, (XtPointer) 10
},
{
XmNorientation, XmCOrientation, XmROrientation,
sizeof(unsigned char), XtOffsetOf(XmColumnRec, column.orientation),
XmRImmediate, (XtPointer) DEFAULT_ORIENTATION
},
{
XmNdistribution, XmCDistribution, XmRDistribution,
sizeof(unsigned char), XtOffsetOf(XmColumnRec, column.distribution),
XmRImmediate, (XtPointer) XmDISTRIBUTE_TIGHT
}
};
static XmSyntheticResource get_resources[] =
{
{
XmNlabelSpacing, sizeof(Dimension),
XtOffsetOf(XmColumnRec, column.label_spacing),
XmeFromHorizontalPixels, (XmImportProc) XmeToHorizontalPixels
},
{
XmNitemSpacing, sizeof(Dimension),
XtOffsetOf(XmColumnRec, column.item_spacing),
XmeFromVerticalPixels, (XmImportProc) XmeToVerticalPixels
}
};
static XtResource constraint_resources[] =
{
{
"pri.vate", "Pri.vate", XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmColumnConstraintRec, column.check_set_render_table),
XmRImmediate, (XtPointer) False
},
{
XmNentryLabelFontList, XmCFontList, XmRFontList,
sizeof(XmFontList), XtOffsetOf(XmColumnConstraintRec, column.label_font_list),
XmRCallProc, (XtPointer) CheckSetEntryLabelRenderTable
},
{
XmNentryLabelRenderTable, XmCRenderTable, XmRRenderTable,
sizeof(XmRenderTable), XtOffsetOf(XmColumnConstraintRec, column.label_font_list),
XmRCallProc, (XtPointer) CheckSetEntryLabelRenderTable
},
{
XmNentryLabelAlignment, XmCAlignment, XmRXmAlignment,
sizeof(unsigned char), XtOffsetOf(XmColumnConstraintRec, column.label_alignment),
XmRImmediate, (XtPointer) XmALIGNMENT_UNSPECIFIED
},
#if 0 /* POSITION HANDLING */
{
XmNentryLabelPosition, XmCEntryLabelPosition, XmRLabelPosition,
sizeof(unsigned char), XtOffsetOf(XmColumnConstraintRec, column.label_position),
XmRImmediate, (XtPointer) XiLABEL_POSITION_UNSPECIFIED
},
#endif
{
XmNfillStyle, XmCFillStyle, XmRFillStyle,
sizeof(unsigned char), XtOffsetOf(XmColumnConstraintRec, column.fill_style),
XmRImmediate, (XtPointer) XmFILL_UNSPECIFIED
},
{
XmNentryLabelType, XmCLabelType, XmRLabelType,
sizeof(unsigned char), XtOffsetOf(XmColumnConstraintRec, column.label_type),
XmRImmediate, (XtPointer) XmSTRING
},
{
XmNentryLabelString, XmCLabelString, XmRXmString,
sizeof(XmString), XtOffsetOf(XmColumnConstraintRec, column.label_string),
XmRImmediate, (XtPointer) NULL
},
{
XmNentryLabelPixmap, XmCLabelPixmap, XmRPrimForegroundPixmap,
sizeof(Pixmap), XtOffsetOf(XmColumnConstraintRec, column.label_pixmap),
XmRImmediate, (XtPointer) XmUNSPECIFIED_PIXMAP
},
{
XmNshowEntryLabel, XmCShowLabel, XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmColumnConstraintRec, column.show_label),
XmRImmediate, (XtPointer) True
},
{
XmNstretchable, XmCStretchable, XmRBoolean,
sizeof(Boolean), XtOffsetOf(XmColumnConstraintRec, column.stretchable),
XmRImmediate, (XtPointer) False
}
};
/*
* Synthetic constraints. Note that these are NOT currently used,
* as the constraint get_values_hook method below seems to work where
* synthetic resources don't. Dunno.
*/
static void Get_entryLabelString(Widget, int, XtArgVal *);
static XmSyntheticResource cont_get_resources[] =
{
{
XmNentryLabelString, sizeof(XmString),
XtOffsetOf(XmColumnConstraintRec, column.label_string),
Get_entryLabelString, (XmImportProc) NULL
}
};
ConstraintClassExtensionRec xiColumnConstraintExtension = {
NULL, /* next_extension */
NULLQUARK, /* record_type */
XtConstraintExtensionVersion, /* version */
sizeof(ConstraintClassExtensionRec), /* record_size */
ConstraintGetValues /* get_values_hook */
};
XmColumnClassRec xmColumnClassRec = {
{
/* core_class members */
/* superclass */ (WidgetClass) &xmBulletinBoardClassRec,
/* class_name */ "XmColumn",
/* widget_size */ sizeof(XmColumnRec),
/* class_initialize */ ClassInitialize,
/* class_part_init */ ClassPartInitialize,
/* class_inited */ False,
/* initialize */ Initialize,
/* initialize_hook */ NULL,
/* realize */ XtInheritRealize,
/* actions */ NULL,
/* num_actions */ 0,
/* resources */ (XtResource*)resources,
/* num_resources */ XtNumber(resources),
/* xrm_class */ NULLQUARK,
/* compress_motion */ True,
/* compress_exposure */ True,
/* compress_enterleave*/ True,
/* visible_interest */ False,
/* destroy */ Destroy,
/* resize */ Resize,
/* expose */ XtInheritExpose,
/* set_values */ SetValues,
/* set_values_hook */ NULL,
/* set_values_almost */ XtInheritSetValuesAlmost,
/* get_values_hook */ NULL,
/* accept_focus */ NULL,
/* version */ XtVersion,
/* callback_private */ NULL,
/* tm_table */ XtInheritTranslations,
/* query_geometry */ (XtGeometryHandler) QueryGeometry,
/* display_accelerator*/ NULL,
/* extension */ NULL,
},
{
/* composite_class members */
/* geometry_manager */ GeometryManager,
/* change_managed */ ChangeManaged,
/* insert_child */ XtInheritInsertChild,
/* delete_child */ XtInheritDeleteChild,
/* extension */ NULL,
},
{ /* constraint_class fields */
/* resource list */ (XtResource*)constraint_resources,
/* num resources */ XtNumber(constraint_resources),
/* constraint size */ sizeof(XmColumnConstraintRec),
/* init proc */ ConstraintInitialize,
/* destroy proc */ ConstraintDestroy,
/* set values proc */ ConstraintSetValues,
/* extension */ &xiColumnConstraintExtension,
},
{ /* manager_class fields */
/* default translations */ XtInheritTranslations,
/* syn_resources */ get_resources,
/* num_syn_resources */ XtNumber(get_resources),
/* syn_cont_resources */ NULL, /* cont_get_resources, */
/* num_syn_cont_resources */ 0, /* XtNumber(cont_get_resources),*/
/* parent_process */ XmInheritParentProcess,
/* extension */ NULL,
},
{ /* bulletin board members */
/* always_install_accel */ False,
/* geo_matrix_create */ NULL,
/* focus_moved_proc */ XmInheritFocusMovedProc,
/* extension */ NULL,
},
{
/* column class members */
/* extension */ NULL,
}
};
WidgetClass xmColumnWidgetClass = (WidgetClass) &xmColumnClassRec;
/*
* Function:
* ClassInitialize(void)
* Description:
* This function is called the first time XmColumn or subclass is
* created. This function is used to install all need type
* converters for this widget class.
* Input:
* None.
* Output:
* None.
*/
static void
ClassInitialize(void)
{
XmColumnClassRec* wc = &xmColumnClassRec;
#if 0 /* POSITION HANDLING */
XtSetTypeConverter(XmRString, XmRLabelPosition,
(XtTypeConverter) CvtStringToLabelPosition,
NULL, 0, XtCacheAll, NULL);
#endif
XtSetTypeConverter(XmRString, XmRXmAlignment,
(XtTypeConverter) CvtStringToXiAlignment,
NULL, 0, XtCacheAll, NULL);
XtSetTypeConverter(XmRString, XmRFillStyle,
(XtTypeConverter) CvtStringToFillStyle,
NULL, 0, XtCacheAll, NULL);
XtSetTypeConverter(XmRString, XmRDistribution,
(XtTypeConverter) CvtStringToDistribution,
NULL, 0, XtCacheAll, NULL);
}
/*
* ClassPartInitialize sets up the fast subclassing for the widget.
*/
static void
#ifdef _NO_PROTO
ClassPartInitialize(w_class)
WidgetClass w_class ;
#else
ClassPartInitialize(WidgetClass w_class)
#endif /* _NO_PROTO */
{
_XmFastSubclassInit (w_class, XmCOLUMN_BIT);
}
/*
* Function:
* Initialize(request, set, arg_list, arg_cnt)
* Description:
* This function is called to initialize the resource values for each
* new widget instance. This function verifies the resource values
* and takes the needed actions to initialize the new instance.
* Input:
* request : Widget - user resource requests
* set : Widget - the resource values for the new widget
* arg_list : ArgList - the argument list used to set the resource
* ang_cnt : Cardinal - the number of arguments in the list
* Output:
* None.
*/
/* ARGSUSED */
static void
Initialize(Widget request, Widget set, ArgList arg_list, Cardinal *arg_cnt)
{
XmColumnWidget rc = (XmColumnWidget) request,
sc = (XmColumnWidget) set;
VerifyResources(rc, (XmColumnWidget) NULL, sc);
if( rc->core.width == 0 )
{
sc->core.width = 2 * (rc->manager.shadow_thickness +
BBPart(rc)->margin_width);
}
if( rc->core.height == 0 )
{
sc->core.height = 2 * (rc->manager.shadow_thickness +
BBPart(rc)->margin_height);
}
}
/*
* Function:
* Destroy(widget)
* Description:
* This function is called when an instance of the Column is being
* destroyed. This function deallocates any memory allocated by the
* instance.
* Input:
* widget : Widget - the widget being destroyed
* Output:
* None.
*/
/* ARGSUSED */
static void
Destroy(Widget widget)
{
/* This space intentionally left blank */
}
/*
* Function:
* Resize(widget)
* Description:
* This function is called when an instance changes size. This
* function needs to adjust the childrens sizes and positions
* appropriately for the new size.
* Input:
* widget : Widget - the widget that changed size.
* Output:
* None.
*/
static void
Resize(Widget widget)
{
WidgetClass sc = XtSuperclass(widget);
XmColumnWidget cw = (XmColumnWidget) widget;
XtWidgetProc resize;
_XmProcessLock();
resize = *sc->core_class.resize;
_XmProcessUnlock();
(* resize) (widget);
Layout(cw, NULL, NULL, -1, -1);
XmColumn_resize_done(cw) = True;
}
/*
* Function:
* SetValues(current, request, set, arg_list, arg_cnt)
* Description:
* This function is called when the user changes the resource
* values for the column. This function adjusts the columns
* appearance and behavior based on the new resource settings.
* Input:
* current : Widget - the current resource values for the widget
* request : Widget - the requested resource values for the widget
* set : Widget - the new resource values for the widget
* arg_list : ArgList - the argument list used to change the resource
* values
* arg_cnt :Cardinal - the number of arguments
* Output:
* Boolean - True if the Column needs redisplayed, else False.
*/
/* ARGSUSED */
static Boolean
SetValues(Widget current, Widget request, Widget set, ArgList arg_list,
Cardinal *arg_cnt)
{
XmColumnWidget cc = (XmColumnWidget) current,
cs = (XmColumnWidget) set;
Boolean request_size = False,
relayout = False;
WidgetList kid, kids = cs->composite.children;
Cardinal n, i, kidCnt = cs->composite.num_children;
Arg args[10];
VerifyResources((XmColumnWidget) request, cc, cs);
if( XmColumn_item_spacing(cc) != XmColumn_item_spacing(cs) ||
XmColumn_label_spacing(cc) != XmColumn_label_spacing(cs) ||
XmColumn_distribution(cc) != XmColumn_distribution(cs) ||
XmColumn_orientation(cc) != XmColumn_orientation(cs) ||
cc->manager.shadow_thickness != cs->manager.shadow_thickness ||
BBPart(cc)->margin_width != BBPart(cs)->margin_width ||
BBPart(cc)->margin_height != BBPart(cs)->margin_height)
{
request_size = True;
}
if( XmColumn_default_fill_style(cc) != XmColumn_default_fill_style(cs)
#if 0 /* POSITION HANDLING */
|| XmColumn_default_label_position(cc) != XmColumn_default_label_position(cs)
#endif
)
{
relayout = True;
}
n = 0;
if( cc->core.background_pixel != cs->core.background_pixel )
{
XtSetArg(args[n], XmNbackground, cs->core.background_pixel); n++;
}
if( cc->manager.foreground != cs->manager.foreground )
{
XtSetArg(args[n], XmNforeground, cs->manager.foreground); n++;
}
for( i = 0, kid = kids; i < kidCnt; ++i, ++kid )
{
if( (*kid) == NULL || (*kid)->core.being_destroyed ||
XiC(*kid)->label_widget == NULL ) continue;
XtSetValues(XiC(*kid)->label_widget, args, n);
}
if( BBPart(cc)->label_font_list !=
BBPart(cs)->label_font_list )
{
for( i = 0, kid = kids; i < kidCnt; ++i, ++kid )
{
if( (*kid) == NULL || (*kid)->core.being_destroyed ||
XiC(*kid)->label_widget == NULL ) continue;
if( XiC(*kid)->label_font_list == NULL )
{
XtVaSetValues(XiC(*kid)->label_widget,
XmNrenderTable,
BBPart(cs)->label_font_list,
NULL);
}
}
}
if( XmColumn_default_label_alignment(cc) !=
XmColumn_default_label_alignment(cs) )
{
for( i = 0, kid = kids; i < kidCnt; ++i, ++kid )
{
if( (*kid) == NULL || (*kid)->core.being_destroyed ||
XiC(*kid)->label_widget == NULL ) continue;
if( XiC(*kid)->label_alignment == XmALIGNMENT_UNSPECIFIED )
{
XtVaSetValues(XiC(*kid)->label_widget,
XmNalignment,
XmColumn_default_label_alignment(cs),
NULL);
}
}
}
if( request_size )
{
Dimension width, height;
XmColumn_resize_done(cs) = False;
CalcSize(cs, NULL, NULL, False, &width, &height);
if( XtMakeResizeRequest((Widget) cs, width, height, &width,
&height) == XtGeometryAlmost )
{
XmColumn_resize_done(cs) = False;
XtMakeResizeRequest((Widget) cs, width, height, NULL, NULL);
}
relayout = !XmColumn_resize_done(cs);
}
if( relayout )
{
Resize((Widget) cs);
}
return( False );
}
/*
* Function:
* QueryGeometry(widget, request, allowed)
* Description:
* This function is called when someone wants to know how the Column
* would react to a specific geometry or when someone wants to know
* what size the Column wants to be.
* Input:
* widget : Widget - the column widget
* request : XtWidgetGeometry* - the requested widget geometry
* allowed : XtWidgetGeometry* - the geometry column is will to accept
* Output:
* XtWidgetResult - the columns response to the geometry request
*/
static XtGeometryResult
QueryGeometry(Widget widget, XtWidgetGeometry *request,
XtWidgetGeometry *wanted)
{
XmColumnWidget cw = (XmColumnWidget) widget;
XtGeometryResult result;
Dimension width, height;
/*
* Lets start by calling this handly dandy function to calculate
* the geometry we want to be.
*/
CalcSize(cw, NULL, NULL, False, &width, &height);
/*
* Now lets see if the caller requested anything and if not
* lets give him our prefered geometry.
*/
if( request->request_mode == 0 )
{
wanted->request_mode = CWWidth | CWHeight;
wanted->width = width;
wanted->height = height;
if( width == XtWidth(cw) && height == XtHeight(cw) )
{
return( XtGeometryNo );
}
return( XtGeometryAlmost );
}
*wanted = *request;
if( request->request_mode & CWWidth )
{
if( request->width < width )
{
wanted->width = width;
}
}
if( request->request_mode & CWHeight )
{
if( request->height < height )
{
wanted->height = height;
}
}
/*
* Now we have set everything in our return structure to what we
* want it to be. Now all that is left is to come up with the
* correct return result. The return result is something like.
*
* o request == wanted and wanted != real -> XtGeometryYes
* o request == wanted and wanted == real -> XtGeometryNo
* o request != wanted and wanted != real -> XtGeometryAlmost
* o request != wanted and wanted == real -> XtGeometryNo
*/
/*
* Lets first see if request == wanted
*/
if( CompareGeometryToWidget(wanted, (Widget) cw) )
{
result = XtGeometryNo;
}
else
{
if( CompareGeometry(request, wanted) )
{
result = XtGeometryYes;
}
else
{
result = XtGeometryNo;
}
}
return( result );
}
/*
* Function:
* GeometryManager(widget, request, allowed)
* Description:
* This function is called when a child of the Column would like
* to change size. This function reacts to the child's request.
* Input:
* widget : Widget - the child requesting the change
* request : XtWidgetGeometry* - the requested widget geometry
* allowed : XtWidgetGeometry* - the geometry column is will to accept
* Output:
* XtWidgetResult - the columns response to the geometry request
*/
static XtGeometryResult
GeometryManager(Widget widget, XtWidgetGeometry *request,
XtWidgetGeometry *allowed)
{
XmColumnWidget cw = (XmColumnWidget) XtParent(widget);
Dimension width, height, width_return, height_return;
XtGeometryResult result;
Boolean equal;
/*
* Now being the mean manager that we are, we are only going to
* allow our children to change geometry parts the affect their
* size. i.e. we will not even discuss with them their position,
* this is mainly because we do not want to deal with it.
*/
*allowed = *request;
allowed->request_mode = request->request_mode =
(request->request_mode & ~(CWX | CWY));
/*
* Now lets see what this child wants to change.
*/
if( request->request_mode & CWWidth )
{
allowed->width = request->width;
}
else
{
allowed->width = XiC(widget)->request_width;
}
if( request->request_mode & CWHeight )
{
allowed->height = request->height;
}
else
{
allowed->height = XiC(widget)->request_height;
}
if( request->request_mode & CWBorderWidth )
{
allowed->border_width = request->border_width;
}
else
{
allowed->border_width = XtBorderWidth(widget);
}
/*
* Now that we know what size our child want to be lets see
* how that effects the geometry we want to be.
*/
CalcSize(cw, widget, allowed, False, &width, &height);
/*
* Now that we know that size that we want to be, lets ask our
* parent and see what they have to say.
*/
if( request->request_mode & XtCWQueryOnly )
{
XtWidgetGeometry req, alw;
req.request_mode = CWWidth | CWHeight | XtCWQueryOnly;
req.width = width;
req.height = height;
width = XtWidth(cw);
height = XtHeight(cw);
switch( XtMakeGeometryRequest((Widget) cw, &req, &alw) )
{
case XtGeometryYes:
return( XtGeometryYes );
break;
case XtGeometryAlmost:
if( alw.request_mode & CWWidth ) width = alw.width;
if( alw.request_mode & CWHeight ) height = alw.height;
case XtGeometryNo:
default:
Layout(cw, widget, allowed, width, height);
allowed->width = XiC(widget)->position.width;
allowed->height = XiC(widget)->position.height;
break;
}
}
else
{
Dimension cur_width, cur_height;
XiC(widget)->request_width = allowed->width;
XiC(widget)->request_height = allowed->height;
XmColumn_resize_done(cw) = False;
cur_width = XtWidth(cw);
cur_height = XtHeight(cw);
switch( XtMakeResizeRequest((Widget) cw, width, height,
&width_return, &height_return) )
{
case XtGeometryYes:
/*
* It appears that our parent will has let us change to
* the size that we want to be, so lets see if we need to
* call our resize procedure.
*/
if( !XmColumn_resize_done(cw) ) Resize((Widget) cw);
Layout(cw, widget, allowed, width, height);
allowed->width = XiC(widget)->position.width;
allowed->height = XiC(widget)->position.height;
break;
case XtGeometryAlmost:
cur_width = width_return;
cur_height = height_return;
case XtGeometryNo:
default:
Layout(cw, widget, allowed, cur_width, cur_height);
allowed->width = XiC(widget)->position.width;
allowed->height = XiC(widget)->position.height;
break;
}
}
width = XtWidth(widget);
height = XtHeight(widget);
equal = CompareGeometryToWidget(allowed, widget);
if( equal )
{
result = XtGeometryNo;
}
else
{
if( CompareGeometry(request, allowed) )
{
result = XtGeometryYes;
}
else
{
result = XtGeometryAlmost;
}
}
if( result == XtGeometryYes )
{
Layout(cw, NULL, NULL, -1, -1);
}
return( result );
}
/*
* Function:
* ChangeManaged(widget)
* Description:
* This is called when one of the children of the column changes
* managed state. This routine just takes care of this situation.
* Input:
* widget : Widget - the column widget
* Output:
* None.
*/
static void
ChangeManaged(Widget widget)
{
static Boolean in = False;
XmColumnWidget cw = (XmColumnWidget) widget;
WidgetList kid = cw->composite.children;
Widget label;
Cardinal i;
Dimension width, height;
if( in ) return;
in = True;
for( i = 0; i < cw->composite.num_children; ++i, ++kid )
{
if( !XiValidChild(*kid) )
{
if( (*kid) != NULL && !XtIsManaged(*kid) )
{ /* CR03731 */
if (XiC(*kid)->label_widget) {
XtUnmanageChild(XiC(*kid)->label_widget);
}
XiC(*kid)->request_width = 0;
XiC(*kid)->request_height = 0;
}
continue;
}
label = XiC(*kid)->label_widget;
if( !XiC(*kid)->show_label )
{
if( XtIsManaged(*kid) ) XtUnmanageChild(label);
}
else if( XtIsManaged(*kid) != XtIsManaged(label) )
{
if( XtIsManaged(*kid) )
{
XtManageChild(label);
}
else
{
XtUnmanageChild(label);
}
}
if( XiC(*kid)->request_width == 0 && XtIsManaged(*kid) )
{
XiC(*kid)->request_width = XtWidth(*kid);
XiC(*kid)->request_height = XtHeight(*kid);
}
if( XtIsManaged(label) )
{
if( XiC(label)->request_width == 0 )
{
#if 0
XiC(label)->request_width = XtWidth(label);
XiC(label)->request_height = XtHeight(label);
#else
{
/* Unfortunately, XtWidth() and XtHeight() may not be valid in
** this case. The request_width and request_height values are
** used both to indicate real requested size and also, when 0,
** to indicate a label with particular geometry needs.
** However, if the code goes through ConstraintSetValues (in
** code generated by the Xcessory tools, constraint resources
** are set via set-values after widget creation) first, the
** sizes are 0 and are then set to 1 in VerticalLayout; then
** the code comes through here and updates the request values
** from the real widths -- 1 -- which are then set back on the
** widget as the geometry. The net result is that the labels
** appear with width 1 (and correct height).
**
** Ideally we would cache the real initial requested value and
** update from that value.
**
** For now, rather than storing those values, query the
** label locally for its preferences and use those; the result
** should be that the size is set correctly (going through
** CalcSize and then VerticalLayout).
*/
XtWidgetGeometry wants;
XtQueryGeometry(label, NULL, &wants);
if( wants.request_mode & CWWidth )
{
XiC(label)->request_width = wants.width;
}
else
{
XiC(label)->request_width = XtWidth(label);
}
if( wants.request_mode & CWHeight )
{
XiC(label)->request_height = wants.height;
}
else
{
XiC(label)->request_height = XtHeight(label);
}
}
#endif
}
}
else
{
XiC(label)->request_width = 0;
XiC(label)->request_height = 0;
}
}
CalcSize(cw, NULL, NULL, False, &width, &height);
if( XtMakeResizeRequest(widget, width, height, &width, &height) ==
XtGeometryAlmost )
{
XtMakeResizeRequest(widget, width, height, NULL, NULL);
}
Layout(cw, NULL, NULL, -1, -1);
in = False;
}
/*
* Function:
* ConstraintInitialize(request, new_w, arg_list, arg_cnt)
* Description:
* This function initializes the constraint record for a new child,
* this includes adding a label for each child.
* Input:
* request : Widget - the requested resource values
* new_w : Widget - the new_w resource values (the new widget)
* arg_list : ArgList - the argument used to create the widget
* arg_cnt : Cardinal - the number of arguments
* Output:
* None.
*/
/* ARGSUSED */
static void
ConstraintInitialize(Widget request, Widget new_w, ArgList arg_list,
Cardinal *arg_cnt)
{
static Boolean label_widget = False; /* STATIC DATA */
XmColumnWidget cw = (XmColumnWidget) XtParent(new_w);
XmBulletinBoardPart *bbpart;
/* CR03562 CR02961 When ChangeManaged is bypassed, request width and height
are not set. The 2 line will prevent this assumption which sometimes
will case the widget size to have zero width/height */
#if 1
/* Note! below fix problematic w.r.t. ChangeManaged code, and needs
** revisiting; back out temporarily
*/
/*
** It is possible that the widget will have a constraint resource set
** on it before the XmColumn itself is realized (ChangeManaged is
** bypassed in that case), so that we enter the Layout code without
** having the values request_width and request_height set from the
** code in ChangeManaged. Rather than use 0 here, which gives poor
** results when those values are used in XtConfigureWidget to set
** the size, initialize them to reasonable default values.
*/
XiC(new_w)->request_width = XtWidth(new_w);
XiC(new_w)->request_height = XtHeight(new_w);
#else
XiC(new_w)->request_width = 0;
XiC(new_w)->request_height = 0;
#endif
XiC(new_w)->label_string = XmStringCopy(XiC(new_w)->label_string);
if( label_widget )
{
XiC(new_w)->label_alignment = XmALIGNMENT_UNSPECIFIED;
#if 0 /* POSITION HANDLING */
XiC(new_w)->label_position = XiLABEL_POSITION_UNSPECIFIED;
#endif
XiC(new_w)->label_type = XmSTRING;
XiC(new_w)->label_pixmap = XmUNSPECIFIED_PIXMAP;
XiC(new_w)->label_string = (XmString) NULL;
XiC(new_w)->label_widget = (Widget) NULL;
XiC(new_w)->show_label = False;
}
else
{
Arg args[64];
int nargs;
char buf[256];
Widget label;
XmFontList lfont;
VerifyConstraints(request, NULL, new_w);
if( strlen(XtName(new_w)) > 240 )
{
strncpy(buf, XtName(new_w), 240);
buf[240] = '\0';
strcat(buf, "_label");
}
else
{
strcpy(buf, XtName(new_w));
strcat(buf, "_label");
}
label_widget = True;
lfont = XmColumnC_label_font_list(new_w);
bbpart = BBPart(XtParent(new_w));
if(lfont == NULL)
lfont = bbpart->label_font_list;
nargs = 0;
XtSetArg(args[nargs], XmNmarginWidth, 0); nargs++;
XtSetArg(args[nargs], XmNmarginHeight, 0); nargs++;
XtSetArg(args[nargs], XmNmarginTop, 0); nargs++;
XtSetArg(args[nargs], XmNmarginBottom, 0); nargs++;
XtSetArg(args[nargs], XmNmarginLeft, 0); nargs++;
XtSetArg(args[nargs], XmNmarginRight, 0); nargs++;
XtSetArg(args[nargs], XmNshadowThickness, 0); nargs++;
XtSetArg(args[nargs], XmNhighlightThickness, 0); nargs++;
XtSetArg(args[nargs], XmNtraversalOn, False); nargs++;
XtSetArg(args[nargs], XmNlabelType, XiC(new_w)->label_type); nargs++;
XtSetArg(args[nargs],
XmNlabelString, XiC(new_w)->label_string); nargs++;
XtSetArg(args[nargs],
XmNlabelPixmap, XiC(new_w)->label_pixmap); nargs++;
XtSetArg(args[nargs], XmNalignment, XiAlignment(new_w)); nargs++;
XtSetArg(args[nargs], XmNrenderTable, lfont); nargs++;
XtSetArg(args[nargs], XmNrecomputeSize, True); nargs++;
XtSetArg(args[nargs], XmNforeground, cw->manager.foreground); nargs++;
XtSetArg(args[nargs],
XmNbackground, cw->core.background_pixel); nargs++;
label = XtCreateWidget(buf, xmLabelWidgetClass, (Widget) cw,
args, nargs);
XiC(new_w)->label_widget = label;
XtAddCallback(label, XmNdestroyCallback,
XmColumnLabelDestroyedCallback, (XtPointer) new_w);
XiC(label)->label_alignment = XmALIGNMENT_UNSPECIFIED;
#if 0 /* POSITION HANDLING */
XiC(label)->label_position = XiLABEL_POSITION_UNSPECIFIED;
#endif
XiC(label)->label_type = XmSTRING;
XiC(label)->label_pixmap = XmUNSPECIFIED_PIXMAP;
XiC(label)->label_string = (XmString) NULL;
XiC(label)->label_widget = (Widget) NULL;
XiC(label)->show_label = False;
label_widget = False;
}
}
/*
* Function:
* ConstraintSetValues(current, request, new_w, arg_list, arg_cnt)
* Description:
* This function is called when the user changes an attribute of
* one of the columns children. This routine reacts to the change.
* Input:
* current : Widget - the current state of the child
* request : Widget - the request state of the child
* new_w : Widget - the child with the requested changes
* arg_list : ArgList - the argument that modified the child
* arg_cnt : Cardinal - the number of argument
* Output:
* Boolean - True if the child needs to be redisplayed, else False.
*/
/* ARGSUSED */
static Boolean
ConstraintSetValues(Widget current, Widget request, Widget new_w,
ArgList arg_list, Cardinal *arg_cnt)
{
XmColumnWidget cw = (XmColumnWidget) XtParent(new_w);
XmColumnConstraintPart *cc = XiC(current),
*sc = XiC(new_w);
Boolean relayout = False;
Arg args[10];
Cardinal i = 0;
if( XiC(new_w)->label_widget == NULL ) return( False );
VerifyConstraints(request, current, new_w);
if(
#if 0 /* POSITION HANDLING */
cc->label_position != sc->label_position ||
#endif
cc->fill_style != sc->fill_style ||
cc->show_label != sc->show_label )
{
relayout = True;
}
if( cc->label_font_list != sc->label_font_list )
{
XmFontList lfont = XmColumnC_label_font_list(new_w);
if(lfont == NULL)
lfont = BBPart(XtParent(new_w))->label_font_list;
XtSetArg(args[i], XmNrenderTable, lfont); ++i;
}
if( cc->label_alignment != sc->label_alignment )
{
XtSetArg(args[i], XmNalignment, XiAlignment(new_w)); ++i;
}
if( cc->label_string != sc->label_string )
{
XmStringFree(cc->label_string);
sc->label_string = XmStringCopy(sc->label_string);
XtSetArg(args[i], XmNlabelString, sc->label_string); ++i;
}
if( cc->label_pixmap != sc->label_pixmap )
{
XtSetArg(args[i], XmNlabelPixmap, sc->label_pixmap); ++i;
}
if( cc->label_type != sc->label_type )
{
XtSetArg(args[i], XmNlabelType, sc->label_type); ++i;
}
if( i > 0 ) XtSetValues(sc->label_widget, args, i);
XmColumn_resize_done(cw) = False;
if( cc->show_label != sc->show_label )
{
if( sc->show_label )
{
XtManageChild(sc->label_widget);
}
else
{
XtUnmanageChild(sc->label_widget);
}
}
if( relayout && !XmColumn_resize_done(cw) )
{
Layout(cw, NULL, NULL, -1, -1);
}
return( False );
}
/*
* Function:
* ConstraintDestroy(widget)
* Description:
* This function is called to deallocate any resources allocated by
* the constraint record.
* Input:
* widget : Widget - the widget being destroyed.
* Output:
* None.
*/
static void
ConstraintDestroy(Widget widget)
{
XmStringFree(XiC(widget)->label_string);
if( XiC(widget)->label_widget != NULL )
{
XtRemoveCallback(XiC(widget)->label_widget, XmNdestroyCallback,
XmColumnLabelDestroyedCallback, (XtPointer) widget);
XtDestroyWidget(XiC(widget)->label_widget);
XiC(widget)->label_widget = NULL;
}
}
/*
* Function:
* ConstraintGetValues
* Description:
* The constraint get_values_hook method. It makes copies of the
* XmNentryLabelString values to prevent returning internal
* XmString data.
* Input:
* w - The child widget
* args - Array of Arg structures
* num_args - Number of entries in args
* Output:
* none (other than the silently copies XmString value)
*/
static void
ConstraintGetValues(Widget w, ArgList args, Cardinal *num_args)
{
XrmQuark quark;
int i;
quark = XrmStringToQuark(XmNentryLabelString);
for (i = 0; i < ((int) *num_args); i++)
{
if (quark == XrmStringToQuark(args[i].name))
{
args[i].value =
(XtArgVal) XmStringCopy(XmColumnC_label_string(w));
break;
}
}
}
static int
CompareISOLatin1 (char *first, char *second)
{
register unsigned char *ap, *bp;
for (ap = (unsigned char *) first, bp = (unsigned char *) second;
*ap && *bp; ap++, bp++) {
register unsigned char a, b;
if ((a = *ap) != (b = *bp)) {
/* try lowercasing and try again */
if ((a >= XK_A) && (a <= XK_Z))
a += (XK_a - XK_A);
else if ((a >= XK_Agrave) && (a <= XK_Odiaeresis))
a += (XK_agrave - XK_Agrave);
else if ((a >= XK_Ooblique) && (a <= XK_Thorn))
a += (XK_oslash - XK_Ooblique);
if ((b >= XK_A) && (b <= XK_Z))
b += (XK_a - XK_A);
else if ((b >= XK_Agrave) && (b <= XK_Odiaeresis))
b += (XK_agrave - XK_Agrave);
else if ((b >= XK_Ooblique) && (b <= XK_Thorn))
b += (XK_oslash - XK_Ooblique);
if (a != b) break;
}
}
return (((int) *bp) - ((int) *ap));
}
/*
* Function:
* done
* Description:
* This macro is used by the resource conversion routines and
* simply assigns the value and returns the correct result.
*/
#define done(type, value) \
{ \
if( to->addr != NULL ) \
{ \
if( to->size < sizeof(type) ) \
{ \
to->size = sizeof(type); \
return( False ); \
} \
*(type*)(to->addr) = (value); \
} \
else \
{ \
static type static_val; \
static_val = (value); \
to->addr = (XtPointer) &static_val; \
} \
to->size = sizeof(type); \
return( True ); \
}
#if 0 /* POSITION HANDLING */
/*
* Function:
* CvtStringToLabelPosition(dpy, args, arg_cnt, from, to, data)
* Description:
* This function converts a string representation of the representation
* type XmRLabelPosition to an actual value.
* Input:
* dpy : Display - unused
* args : XrmValue* - unused
* arg_cnt : Cardinal - unused
* from : XrmValue* - contains the string representation of the value
* to : XrmValue* - returns the actual value
* data : XtPointer - unused
* Output:
* Boolean - True if the conversion was successful else False.
*/
static Boolean
CvtStringToLabelPosition(Display *dpy, XrmValue *args, Cardinal *arg_cnt,
XrmValue *from, XrmValue *to, XtPointer data)
{
unsigned char result = XiLABEL_POSITION_LEFT;
String str = (String) (from->addr);
if( CompareISOLatin1(str, "label_position_unspecified") == 0 ||
CompareISOLatin1(str, "unspecified") == 0 )
{
result = XiLABEL_POSITION_UNSPECIFIED;
}
else if( CompareISOLatin1(str, "label_position_left") == 0 ||
CompareISOLatin1(str, "left") == 0 )
{
result = XiLABEL_POSITION_LEFT;
}
else if( CompareISOLatin1(str, "label_position_right") == 0 ||
CompareISOLatin1(str, "right") == 0 )
{
result = XiLABEL_POSITION_RIGHT;
}
else if( CompareISOLatin1(str, "label_position_top") == 0 ||
CompareISOLatin1(str, "top") == 0 )
{
result = XiLABEL_POSITION_TOP;
}
else if( CompareISOLatin1(str, "label_position_bottom") == 0 ||
CompareISOLatin1(str, "bottom") == 0 )
{
result = XiLABEL_POSITION_BOTTOM;
}
else if( CompareISOLatin1(str, "label_position_center") == 0 ||
CompareISOLatin1(str, "CENTER") == 0 )
{
result = XiLABEL_POSITION_CENTER;
}
else
{
XtDisplayStringConversionWarning(dpy, from->addr, XmRLabelPosition);
return( False );
}
done(unsigned char, result);
}
#endif
/*
* Function:
* CvtStringToXiAlignment(dpy, args, arg_cnt, from, to, data)
* Description:
* This function converts a string representation of the representation
* type XmRXnAlignment to an actual value.
* Input:
* dpy : Display - unused
* args : XrmValue* - unused
* arg_cnt : Cardinal - unused
* from : XrmValue* - contains the string representation of the value
* to : XrmValue* - returns the actual value
* data : XtPointer - unused
* Output:
* Boolean - True if the conversion was successful else False.
*/
/* ARGSUSED */
static Boolean
CvtStringToXiAlignment(Display *dpy, XrmValue *args, Cardinal *arg_cnt,
XrmValue *from, XrmValue *to, XtPointer data)
{
unsigned char result = XmALIGNMENT_CENTER;
String str = (String) (from->addr);
if( CompareISOLatin1(str, "alignment_unspecified") == 0 ||
CompareISOLatin1(str, "unspecified") == 0 )
{
result = XmALIGNMENT_UNSPECIFIED;
}
else if( CompareISOLatin1(str, "alignment_beginning") == 0 ||
CompareISOLatin1(str, "beginning") == 0 )
{
result = XmALIGNMENT_BEGINNING;
}
else if( CompareISOLatin1(str, "alignment_center") == 0 ||
CompareISOLatin1(str, "center") == 0 )
{
result = XmALIGNMENT_CENTER;
}
else if( CompareISOLatin1(str, "alignment_end") == 0 ||
CompareISOLatin1(str, "end") == 0 )
{
result = XmALIGNMENT_END;
}
else
{
XtDisplayStringConversionWarning(dpy, from->addr, XmRXmAlignment);
return( False );
}
done(unsigned char, result);
}
/*
* Function:
* CvtStringToFillStyle(dpy, args, arg_cnt, from, to, data)
* Description:
* This function converts a string representation of the representation
* type XmRFillStyle to an actual value.
* Input:
* dpy : Display - unused
* args : XrmValue* - unused
* arg_cnt : Cardinal - unused
* from : XrmValue* - contains the string representation of the value
* to : XrmValue* - returns the actual value
* data : XtPointer - unused
* Output:
* Boolean - True if the conversion was successful else False.
*/
/* ARGSUSED */
static Boolean
CvtStringToFillStyle(Display *dpy, XrmValue *args, Cardinal *arg_cnt,
XrmValue *from, XrmValue *to, XtPointer data)
{
unsigned char result = XmFILL_UNSPECIFIED;
String str = (String) (from->addr);
if( CompareISOLatin1(str, "fill_unspecified") == 0 ||
CompareISOLatin1(str, "unspecified") == 0 )
{
result = XmFILL_UNSPECIFIED;
}
else if( CompareISOLatin1(str, "fill_flush") == 0 ||
CompareISOLatin1(str, "flush") == 0 )
{
result = XmFILL_FLUSH;
}
else if( CompareISOLatin1(str, "fill_ragged") == 0 ||
CompareISOLatin1(str, "ragged") == 0 )
{
result = XmFILL_RAGGED;
}
else
{
XtDisplayStringConversionWarning(dpy, from->addr, XmRFillStyle);
return( False );
}
done(unsigned char, result);
}
/*
* Function:
* CvtStringToDistribution(dpy, args, arg_cnt, from, to, data)
* Description:
* This function converts a string representation of the representation
* type XmRDistribution to an actual value.
* Input:
* dpy : Display - unused
* args : XrmValue* - unused
* arg_cnt : Cardinal - unused
* from : XrmValue* - contains the string representation of the value
* to : XrmValue* - returns the actual value
* data : XtPointer - unused
* Output:
* Boolean - True if the conversion was successful else False.
*/
/* ARGSUSED */
static Boolean
CvtStringToDistribution(Display *dpy, XrmValue *args, Cardinal *arg_cnt,
XrmValue *from, XrmValue *to, XtPointer data)
{
unsigned char result = XmDISTRIBUTE_TIGHT;
String str = (String) (from->addr);
if( CompareISOLatin1(str, "distribute_tight") == 0 ||
CompareISOLatin1(str, "tight") == 0 )
{
result = XmDISTRIBUTE_TIGHT;
}
else if( CompareISOLatin1(str, "distribute_spread") == 0 ||
CompareISOLatin1(str, "spread") == 0 )
{
result = XmDISTRIBUTE_SPREAD;
}
else
{
XtDisplayStringConversionWarning(dpy, from->addr, XmRDistribution);
return( False );
}
done(unsigned char, result);
}
/*
* Function:
* VerifyResources(request, current, new_w)
* Description:
* This function verifies the values for the Column's resource in
* "new_w" resetting them to the previous or default values if an
* invalid resource value was set.
* Input:
* request : XmColumnWidget - the requested setting for the widget
* current : XmColumnWidget - the current setting for the widget
* new_w : XmColumnWidget - the setting for the widget
* Output:
* None.
*/
/* ARGSUSED */
static void
VerifyResources(XmColumnWidget request, XmColumnWidget current,
XmColumnWidget new_w)
{
Boolean reset;
if( BBPart(new_w)->label_font_list == NULL )
{
BBPart(new_w)->label_font_list =
XmeGetDefaultRenderTable((Widget) new_w, XmLABEL_FONTLIST);
}
reset = False;
#if 0 /* POSITION HANDLING */
switch( XmColumn_default_label_position(new_w) )
{
case XiLABEL_POSITION_CENTER:
case XiLABEL_POSITION_LEFT:
case XiLABEL_POSITION_RIGHT:
case XiLABEL_POSITION_TOP:
case XiLABEL_POSITION_BOTTOM:
break;
case XiLABEL_POSITION_UNSPECIFIED:
XmeWarning((Widget) new_w),
"The illegal resource value \"XiLABEL_POSITION_UNSPECIFIED\" was assigned to the resource XmNDefaultLabelPosition");
reset = True;
break;
default:
XmeWarning((Widget) new_w,
"An illegal resource value was assigned to the resource XmNDefaultLabelPosition");
reset = True;
break;
}
if( reset )
{
XmColumn_default_label_position(new_w) =
(current != NULL
? XmColumn_default_label_position(current)
: DEFAULT_POSITION);
}
#endif
reset = False;
switch( XmColumn_default_label_alignment(new_w) )
{
case XmALIGNMENT_BEGINNING:
case XmALIGNMENT_CENTER:
case XmALIGNMENT_END:
break;
case XmALIGNMENT_UNSPECIFIED:
XmeWarning((Widget) new_w,
"The illegal resource value \"XmALIGNMENT_UNSPECIFIED\" was assigned to the resource XmNdefaultEntryLabelAlignment");
reset = True;
break;
default:
XmeWarning((Widget) new_w,
"An illegal resource value was assigned to the resource XmNdefaultEntryLabelAlignment");
reset = True;
break;
}
if( reset )
{
XmColumn_default_label_alignment(new_w) =
(current != NULL
? XmColumn_default_label_alignment(current)
: DEFAULT_ALIGNMENT);
}
reset = False;
switch( XmColumn_orientation(new_w) )
{
case XmHORIZONTAL:
case XmVERTICAL:
break;
default:
XmeWarning((Widget) new_w,
"An illegal resource value was assigned to the resource XmNorientation");
reset = True;
break;
}
if( reset )
{
XmColumn_orientation(new_w) =
(current != NULL
? XmColumn_orientation(current)
: DEFAULT_ORIENTATION);
}
}
/*
* Function:
* Layout(cw, child, child_size, col_width, col_height)
* Description:
* This is simply a launcher routine. This routine passes control
* to the appropriate layout routine depending on the orientation
* of the column.
* Input:
* cw : XmColumnWidget - the column to layout
* child : Widget - A childs whose geometry is specified
* child_size : XtWidgetGeometry* - the specified child geometry
* col_width : int - a specified width for the column
* col_height : int - a specified height for the column
* Output:
* None.
*/
static void
Layout(XmColumnWidget cw, Widget child, XtWidgetGeometry *child_size,
int col_width, int col_height)
{
if (XmColumn_orientation(cw) == XmHORIZONTAL)
{
HorizontalLayout(cw, child, child_size, col_width, col_height);
}
else
{
VerticalLayout(cw, child, child_size, col_width, col_height);
}
}
/*
* Function:
* HorizontalLayout(cw, child, child_size, col_witdh, col_height)
* Description:
* This routine handles the horizontal layout for the column widget
* Input:
* cw : XmColumnWidget - the column to layout
* child : Widget - A childs whose geometry is specified
* child_size : XtWidgetGeometry* - the specified child geometry
* col_width : int - a specified width for the column
* col_height : int - a specified height for the column
* Output:
* None.
*/
static void
HorizontalLayout(XmColumnWidget cw, Widget child,
XtWidgetGeometry *child_size, int col_width, int col_height)
{
/* Do the Horizontal Layout, Baby! */
WidgetList kids = cw->composite.children, kid;
Widget label;
Cardinal i, kidCnt = cw->composite.num_children;
Position x, y;
int cWidth, cBorder, cbWidth, lWidth, valid, space;
Dimension fillHeight;
int ispace = (int)XmColumn_item_spacing(cw);
int kidSpace;
if( col_width < 0 ) col_width = XtWidth(cw);
if( col_height < 0 ) col_height = XtHeight(cw);
fillHeight = col_height - 2 * (cw->manager.shadow_thickness +
BBPart(cw)->margin_height);
for( i = 0, kid = kids, lWidth = 0, cbWidth = 0, valid = 0,
space = 0, kidSpace = 0; i < kidCnt; ++i, ++kid )
{
XiC(*kid)->position.x = XiC(*kid)->position.y = 0;
if( *kid == child )
{
XiC(*kid)->position.width = child_size->width;
XiC(*kid)->position.height = child_size->height;
}
else
{
XiC(*kid)->position.width = XiC(*kid)->request_width;
XiC(*kid)->position.height = XiC(*kid)->request_height;
}
if( !XiValidChild(*kid) ) continue;
valid++;
if( *kid == child )
cbWidth += child_size->width + 2*child_size->border_width;
else
cbWidth += XiC(*kid)->request_width + 2*XtBorderWidth(*kid);
if( !XiC(*kid)->show_label ) continue;
space += XmColumn_label_spacing(cw);
kidSpace++;
label = XiC(*kid)->label_widget;
if( label == child )
lWidth += child_size->width;
else
lWidth += XiC(label)->request_width;
}
x = cw->manager.shadow_thickness + BBPart(cw)->margin_width;
if( valid > 0 && (x + lWidth + space + cbWidth + ispace*(valid-1) + x > col_width ) )
{
/*
* First try to shrink labelSpacing, then itemSpacing, otherwise clip.
*/
int have = (col_width - 2 * x),
want = lWidth + space + ispace*(valid-1) + cbWidth,
diff = want - have;
if ( space - diff > 1)
{
space -= diff;
}
else
{
if (0 != space)
space = kidSpace;
want = lWidth + space + ispace*(valid-1) + cbWidth;
diff = want - have;
if (ispace*(valid-1) - diff > 1)
ispace = (ispace*(valid-1)-diff)/(valid-1);
else
{
if (0 != ispace)
ispace = 1;
}
}
}
if (0==kidSpace) kidSpace = 1;
space /= kidSpace;
/*
* Calculating the widths for the various kids is a one shot, so lets
* first walk through the kids and calculate all the width.
*/
for( kid = kids, i = 0; i < kidCnt; ++i, ++kid )
{
int mySpace;
if( !XiValidChild(*kid) ) continue;
label = XiC(*kid)->label_widget;
XiC(label)->position.width = XtWidth(label);
if( XiC(*kid)->show_label )
{
lWidth = XtWidth(label);
mySpace = space;
}
else
{
lWidth = 0;
mySpace = 0;
}
if (LayoutIsRtoLM(cw))
XiC(label)->position.x = col_width - x - lWidth;
else
XiC(label)->position.x = x;
/* First, let's calculate the kid's X-position */
if( *kid == child )
cWidth = XiC(*kid)->position.width = child_size->width;
else
cWidth = XiC(*kid)->position.width = XiC(*kid)->request_width;
if (LayoutIsRtoLM(cw))
XiC(*kid)->position.x = col_width - (x + lWidth + space) - cWidth;
else
XiC(*kid)->position.x = x + lWidth + space;
if( child == *kid )
cBorder = child_size->border_width;
else
cBorder = XtBorderWidth(*kid);
x += lWidth + mySpace + cWidth + ispace + 2*cBorder;
/* Now, let's calculate the kid's Y-position */
y = cw->manager.shadow_thickness + BBPart(cw)->margin_height;
XiC(label)->position.y += y;
XiC(*kid)->position.y += y;
/* If XmNfillStyle == XmFILL_FLUSH, adjust height to same as column */
if (XiFill(*kid) == XmFILL_FLUSH)
{
XiC(label)->position.height = fillHeight;
XiC(*kid)->position.height = fillHeight;
}
}
if( child == NULL )
{
for( i = 0, kid = kids; i < kidCnt; ++i, ++kid )
{
if( !XiValidChild(*kid) ) continue;
label = XiC(*kid)->label_widget;
if( XiC(*kid)->show_label ) {
XtConfigureWidget(label, XiC(label)->position.x,
XiC(label)->position.y,
XiC(label)->position.width,
XiC(*kid)->position.height, 0);
}
XtConfigureWidget(*kid, XiC(*kid)->position.x,
XiC(*kid)->position.y,
XiC(*kid)->position.width,
XiC(*kid)->position.height,
XtBorderWidth(*kid));
}
}
}
/*
* Function:
* VerticalLayout(cw, child, child_size, col_witdh, col_height)
* Description:
* This routine handles the vertical layout for the column widget
* Input:
* cw : XmColumnWidget - the column to layout
* child : Widget - A childs whose geometry is specified
* child_size : XtWidgetGeometry* - the specified child geometry
* col_width : int - a specified width for the column
* col_height : int - a specified height for the column
* Output:
* None.
*/
static void
VerticalLayout(XmColumnWidget cw, Widget child, XtWidgetGeometry *child_size,
int col_width, int col_height)
{
WidgetList kids = cw->composite.children, kid;
Widget label;
Cardinal i, kidCnt = cw->composite.num_children, j;
Position x, y;
int cWidth, cMaxWidth, cMinWidth, cHeight, cBorder, cbWidth, cbHeight,
lWidth, lHeight, cnt, hExtra, hEach =0 , hLeft = 0, valid, space;
Dimension width, height;
Boolean change, stretch;
if( col_width < 0 ) col_width = XtWidth(cw);
if( col_height < 0 ) col_height = XtHeight(cw);
CalcSize(cw, NULL, NULL, False, &width, &height);
for( i = 0, kid = kids, lWidth = 0, cMinWidth = 0, cMaxWidth = 0, cnt = 0, valid = 0,
space = 0; i < kidCnt; ++i, ++kid )
{
XiC(*kid)->position.x = XiC(*kid)->position.y = 0;
if( *kid == child )
{
XiC(*kid)->position.width = child_size->width;
XiC(*kid)->position.height = child_size->height;
}
else
{
XiC(*kid)->position.width = XiC(*kid)->request_width;
XiC(*kid)->position.height = XiC(*kid)->request_height;
}
if( !XiValidChild(*kid) ) continue;
valid++;
if( *kid == child )
{
cbWidth = child_size->width + 2*child_size->border_width;
}
else
{
cbWidth = XiC(*kid)->request_width + 2*XtBorderWidth(*kid);
}
if( cMinWidth == 0 )
{
cMinWidth = cbWidth;
}
else if( cbWidth < cMinWidth )
{
cMinWidth = cbWidth;
}
if( cMaxWidth == 0 )
{
cMaxWidth = cbWidth;
}
else if( cbWidth > cMaxWidth )
{
cMaxWidth = cbWidth;
}
if( XiC(*kid)->stretchable ) ++cnt;
if( !XiC(*kid)->show_label ) continue;
space = XmColumn_label_spacing(cw);
label = XiC(*kid)->label_widget;
if( child == label )
{
if( (int)child_size->width > lWidth )
{
lWidth = child_size->width;
}
}
else
{
if( (int)XiC(label)->request_width > lWidth )
{
lWidth = XiC(label)->request_width;
}
}
}
x = cw->manager.shadow_thickness + BBPart(cw)->margin_width;
if( valid > 0 && (x + lWidth + space + cMaxWidth + x > col_width ) )
{
int have = (col_width - 2 * x),
want = lWidth + space + cMaxWidth,
diff = want - have;
/* Try to subtract from the label space first; if we can't do it (it
** may be 0 right now),
** then the data fields will shrink until they are the size of the
** smallest field, and after that the labels will shrink.
** The shadow and margin aren't affected.
*/
if ( space - diff > 1)
space -= diff;
else
{
if (0 != space)
space = 1;
want = lWidth + space + cMinWidth;
diff = want - have;
if (diff > 0)
{
if( lWidth - diff > 1 )
lWidth -= diff;
else
lWidth = 1;
}
}
}
/*
* Calculating the widths for the various kids is a one shot, so lets
* first walk through the kids and calculate all the width.
*/
for( kid = kids, i = 0; i < kidCnt; ++i, ++kid )
{
if( !XiValidChild(*kid) ) continue;
label = XiC(*kid)->label_widget;
cBorder = XtBorderWidth(*kid);
if (LayoutIsRtoLM(cw))
XiC(label)->position.x = col_width - x - lWidth;
else
XiC(label)->position.x = x;
XiC(label)->position.width = lWidth;
/* cbWidth is whatever is left over */
cbWidth = col_width -
((int)cw->manager.shadow_thickness +
(int)BBPart(cw)->margin_width +
x + lWidth + space);
if( cbWidth < 1 ) cbWidth = 1;
cWidth = cbWidth - 2*cBorder;
if( cWidth < 1 ) cWidth = 1;
/* cWidth is now the value to use for XmFILL_FLUSH */
if( XiFill(*kid) == XmFILL_RAGGED )
{
if( child == *kid )
{
if( (int) child_size->width < cWidth )
{
cWidth = child_size->width;
}
}
else
{
if( (int) XiC(*kid)->request_width < cWidth )
{
cWidth = XiC(*kid)->request_width;
}
}
}
if (LayoutIsRtoLM(cw))
XiC(*kid)->position.x = col_width - (x + lWidth + space + cWidth);
else
XiC(*kid)->position.x = x + lWidth + space;
XiC(*kid)->position.width = cWidth;
}
/*
* Now that we have calculated the x position and the width of
* each of the children lets now try to calculate the y position
* and the height.
*/
space = XmColumn_item_spacing(cw);
hExtra = col_height - height;
/* but first make a quick check on reducing the itemSpacing */
if (hExtra < 0)
{
if (valid)
{
int totalItemSpacing = (valid - 1) * space;
if (totalItemSpacing + hExtra > 0)
space = (totalItemSpacing + hExtra)/(valid-1);
else
space = 1;
}
hExtra = 0; /* or very close to it */
}
for( j = 0; j < 2; ++j )
{
do {
y = cw->manager.shadow_thickness +
BBPart(cw)->margin_height;
if( j != 0 )
{
cnt = valid;
}
if( cnt > 0 )
{
hEach = hExtra / cnt;
hLeft = hExtra % cnt;
}
else if( cnt == 0 )
{
hEach = 0;
hLeft = hExtra;
}
change = False;
for( kid = kids, i = 0; i < kidCnt; ++i, ++kid )
{
if( !XiValidChild(*kid) ) continue;
label = XiC(*kid)->label_widget;
cHeight = XiC(*kid)->position.height;
if( j == 0 || hExtra > 0 )
{
stretch = XiC(*kid)->stretchable;
}
else
{
stretch = True;
}
if( stretch )
{
if( hExtra < 0 && cHeight > 1 )
{
if( hEach != 0 )
{
int tmp = -hEach;
change = True;
if( tmp < cHeight )
{
hExtra += tmp;
cHeight -= tmp;
}
else
{
tmp = cHeight - 1;
hExtra += tmp;
cHeight = 1;
}
}
if( hLeft != 0 && cHeight > 1 )
{
change = True;
hLeft++;
hExtra++;
cHeight--;
}
}
else if( hExtra > 0 )
{
change = True;
cHeight += hEach;
hExtra -= hEach;
if( hLeft > 0 )
{
cHeight++;
hLeft--;
hExtra--;
}
}
}
if( cHeight < 1 ) cHeight = 1;
if( child == *kid )
{
cBorder = child_size->border_width;
}
else
{
cBorder = XtBorderWidth(*kid);
}
if( XiC(*kid)->show_label )
{
if( child == label )
{
lHeight = child_size->height;
}
else
{
lHeight = XiC(label)->request_height;
}
}
else
{
lHeight = 1;
}
cbHeight = cHeight + 2 * cBorder;
if( cbHeight > lHeight || stretch )
{
lHeight = cbHeight;
}
else
{
cHeight = lHeight - 2*cBorder;
if( cHeight < 1 ) cHeight = 1;
cbHeight = cHeight + 2*cBorder;
}
XiC(label)->position.y = y;
XiC(label)->position.height = lHeight;
XiC(*kid)->position.y = y;
XiC(*kid)->position.height = cHeight;
if( child == *kid )
{
cBorder = child_size->border_width;
}
else
{
cBorder = XtBorderWidth(*kid);
}
y += XiC(*kid)->position.height + (2 * cBorder) + space;
}
} while( hExtra != 0 && change );
}
/*
* If we get here and we still have some extra space we want to see
* if the user wants to distribute the space between children or
* not.
*/
if( XmColumn_distribution(cw) == XmDISTRIBUTE_SPREAD &&
hExtra > 0 )
{
if( valid == 1 )
{
hEach = hExtra / 2;
XiC(*kids)->position.y += hEach;
}
else
{
if( valid > 1 )
{
valid--;
hEach = hExtra / valid;
hLeft = hExtra % valid;
}
else
{
hEach = 0;
hLeft = hExtra;
}
y = cw->manager.shadow_thickness +
BBPart(cw)->margin_height;
for( i = 0, kid = kids; i < kidCnt; ++i, ++kid )
{
if( !XiValidChild(*kid) ) continue;
if( i > 0 )
{
XiC(*kid)->position.y = y;
XiC(XiC(*kid)->label_widget)->position.y = y;
}
space = XmColumn_item_spacing(cw) + hEach;
if( hLeft > 0 ) {
space++;
hLeft--;
}
if( child == *kid )
{
cBorder = child_size->border_width;
}
else
{
cBorder = XtBorderWidth(*kid);
}
y += XiC(*kid)->position.height + (2 * cBorder) +
space;
}
}
}
if( child == NULL )
{
for( i = 0, kid = kids; i < kidCnt; ++i, ++kid )
{
if( !XiValidChild(*kid) ) continue;
label = XiC(*kid)->label_widget;
if( XiC(*kid)->show_label )
{
XtConfigureWidget(label, XiC(label)->position.x,
XiC(label)->position.y,
XiC(label)->position.width,
XiC(*kid)->position.height, 0);
}
XtConfigureWidget(*kid, XiC(*kid)->position.x,
XiC(*kid)->position.y,
XiC(*kid)->position.width,
XiC(*kid)->position.height,
XtBorderWidth(*kid));
}
}
}
/*
* Function:
* VerifyConstraint(request, current, set)
* Description:
* This function verifies the values for the Column child's constraint
* resources in "set" resetting them to the previous or default
* values if an invalid resource value was set.
* Input:
* request : Widget - the requested setting for the widget
* current : Widget - the current setting for the widget
* set : Widget - the setting for the widget
* Output:
* None.
*/
/* ARGSUSED */
static void
VerifyConstraints(Widget request, Widget current, Widget set)
{
Boolean reset;
#if 0 /* POSITION HANDLING */
reset = False;
switch( XiC(set)->label_position )
{
case XiLABEL_POSITION_CENTER:
case XiLABEL_POSITION_LEFT:
case XiLABEL_POSITION_RIGHT:
case XiLABEL_POSITION_TOP:
case XiLABEL_POSITION_BOTTOM:
case XiLABEL_POSITION_UNSPECIFIED:
break;
default:
XmeWarning(set,
"An illegal resource value was assigned to the resource XmNentryLabelPosition");
reset = True;
break;
}
if( reset )
{
XiC(set)->label_position = (current != NULL
? XiC(current)->label_position
: XiLABEL_POSITION_UNSPECIFIED);
}
#endif
reset = False;
switch( XiC(set)->label_alignment )
{
case XmALIGNMENT_BEGINNING:
case XmALIGNMENT_CENTER:
case XmALIGNMENT_END:
case XmALIGNMENT_UNSPECIFIED:
break;
default:
XmeWarning(set,
"An illegal resource value was assigned to the resource XmNentryLabelAlignment");
reset = True;
break;
}
if( reset )
{
XiC(set)->label_alignment = (current != NULL
? XiC(current)->label_alignment
: XmALIGNMENT_UNSPECIFIED);
}
reset = False;
switch( XiC(set)->fill_style )
{
case XmFILL_UNSPECIFIED:
case XmFILL_FLUSH:
case XmFILL_RAGGED:
break;
default:
XmeWarning(set,
"An illegal resource value was assigned to the resource XmNfillStyle");
reset = True;
break;
}
if( reset )
{
XiC(set)->fill_style = (current != NULL
? XiC(current)->fill_style
: XmFILL_UNSPECIFIED);
}
}
/*
* Function:
* CalcSize(cw, child, child_size, query, width, height)
* Description:
* This function calculates and returns the prefered size for the
* column.
* Input:
* cw : XmColumnWidget - the column widget
* child : Widget - a widget whose geometry is specified
* child_size : XtWidgetGeometry* - the specified child's geometry
* query : Boolean - query the kids?
* width : Dimension* - return the desired width
* height : Dimension* - return the desired height
* Output:
* None.
*/
static void
CalcSize(XmColumnWidget cw, Widget child, XtWidgetGeometry *child_size,
Boolean query, Dimension *width, Dimension *height)
{
int _width = 0, _height = 0, cnt = 0;
Cardinal i, kidCnt = cw->composite.num_children;
WidgetList kid, kids = cw->composite.children;
Widget label;
Dimension cWidth, cHeight, cBorder, cSum = 0, lWidth, lHeight;
Dimension lSum = 0, space = 0, hSumSpace = 0;
XtWidgetGeometry wants;
for (i = 0, kid = kids; i < kidCnt; ++i, ++kid)
{
if (!XiValidChild(*kid)) continue;
if (XiC(*kid)->show_label)
{
space = XmColumn_label_spacing(cw);
hSumSpace += XmColumn_label_spacing(cw);
}
/*
* Check for the child widgets preferred geometry.
* if the prefered geometry is greater than the requested
* geometry, then set the query geometry to "True".
* Doing this, column widget will take care of improper
* size settings on the compound children widgets (CR03821)
*/
query = False;
XtQueryGeometry(*kid, NULL, &wants);
if (wants.width > XiC(*kid)->request_width || \
wants.height > XiC(*kid)->request_height)
{
query = True;
}
if (*kid == child && child_size != NULL)
{
cWidth = child_size->width;
cHeight = child_size->height;
cBorder = child_size->border_width;
} else if (query)
{
XtQueryGeometry(*kid, NULL, &wants);
if (wants.request_mode & CWWidth)
{
cWidth = wants.width;
XiC(*kid)->request_width = wants.width;
}
else
{
cWidth = XiC(*kid)->request_width;
}
if (wants.request_mode & CWHeight)
{
cHeight = wants.height;
XiC(*kid)->request_height = wants.height;
}
else
{
cHeight = XiC(*kid)->request_height;
}
if (wants.request_mode & CWBorderWidth)
{
cBorder = wants.border_width;
}
else
{
cBorder = XtBorderWidth(*kid);
}
}
else
{
cWidth = XiC(*kid)->request_width;
cHeight = XiC(*kid)->request_height;
cBorder = XtBorderWidth(*kid);
}
cWidth += (2 * cBorder);
cHeight += (2 * cBorder);
if (XtIsManaged((label = XiC(*kid)->label_widget)))
{
if (label == child && child_size != NULL)
{
lWidth = child_size->width;
lHeight = child_size->height;
}
else if (query)
{
XtQueryGeometry(label, NULL, &wants);
if (wants.request_mode & CWWidth)
{
lWidth = wants.width;
}
else
{
lWidth = XiC(label)->request_width;
}
if (wants.request_mode & CWHeight)
{
lHeight = wants.height;
}
else
{
lHeight = XiC(label)->request_height;
}
}
else
{
lWidth = XiC(label)->request_width;
lHeight = XiC(label)->request_height;
}
}
else
{
lWidth = lHeight = 0;
}
if (XmColumn_orientation(cw) == XmVERTICAL)
{
if (lWidth > lSum) lSum = lWidth;
if (cWidth > cSum) cSum = cWidth;
_height += (lHeight > cHeight ? lHeight : cHeight);
}
else /* XmHORIZONTAL Layout */
{
/* Choose the maximum height */
if (_height < (int)cHeight) _height = cHeight;
if (_height < (int)lHeight) _height = lHeight;
_width += lWidth + cWidth;
}
cnt++;
}
if (cnt > 1) --cnt;
if (XmColumn_orientation(cw) == XmVERTICAL)
{
_width = lSum + cSum + space +
2 * (cw->manager.shadow_thickness +
BBPart(cw)->margin_width);
_height += (cnt * XmColumn_item_spacing(cw) +
2 * (cw->manager.shadow_thickness +
BBPart(cw)->margin_height));
}
else /* XmHORIZONTAL Layout */
{
_width += (hSumSpace +
2 * (cw->manager.shadow_thickness +
BBPart(cw)->margin_width)) + cnt*XmColumn_item_spacing(cw);
_height += 2 * (cw->manager.shadow_thickness +
BBPart(cw)->margin_height);
}
if (_width < 1) _width = 1;
if (_height < 1) _height = 1;
if (width != NULL) *width = _width;
if (height != NULL) *height = _height;
}
/*
* Function:
* CompareGeometry(geom1, geom2)
* Description:
* This function compares to XtWidgetGeometry structure to see if
* the are equal.
* Input:
* geom1 : XtWidgetGeometry* - a geometry spec
* geom2 : XtWidgetGeometry* - another geometry spec
* Output:
* Boolean - True if the geometry structures are equal, else False
*/
static Boolean
CompareGeometry(XtWidgetGeometry *geom1, XtWidgetGeometry *geom2)
{
Boolean result;
result = (geom1 == NULL || geom2 == NULL) ||
(geom1->request_mode != geom2->request_mode) ||
(geom1->request_mode & CWX && geom1->x != geom2->x) ||
(geom1->request_mode & CWY && geom1->y != geom2->y) ||
(geom1->request_mode & CWWidth && geom1->width != geom2->width) ||
(geom1->request_mode & CWHeight && geom1->height != geom2->height) ||
(geom1->request_mode & CWBorderWidth &&
geom1->border_width != geom2->border_width);
return( !result );
}
/*
* Function:
* CompareGeometryToWidget(geom, widget)
* Description:
* Compares a geometry spec to a widget's actual geometry.
* Input:
* geom : XtWidgetGeometry* - the geometry
* widget : Widget - the widget
* Output:
* Boolean - True if the widget equals the geom spec, else False.
*/
static Boolean
CompareGeometryToWidget(XtWidgetGeometry *geom, Widget widget)
{
Boolean result;
result = (geom == NULL || widget == NULL) ||
(geom->request_mode == 0) ||
(geom->request_mode & CWX && geom->x != XtX(widget)) ||
(geom->request_mode & CWY && geom->y != XtY(widget)) ||
(geom->request_mode & CWWidth && geom->width != XtWidth(widget)) ||
(geom->request_mode & CWHeight &&
geom->height != XtHeight(widget)) ||
(geom->request_mode & CWBorderWidth &&
geom->border_width != XtBorderWidth(widget));
return( !result );
}
/*
* XmRCallProc routine for checking label_font_list before setting it to NULL
* If constrainit's "check_set_render_table" is True, then function has
* been called twice on same widget, thus resource needs to be set NULL,
* otherwise leave it alone.
*/
/*ARGSUSED*/
static void
CheckSetEntryLabelRenderTable(Widget wid, int offs, XrmValue *value)
{
XmColumnConstraintPart* cc = XiC(wid);
/* Check if been here before */
if (cc->check_set_render_table)
value->addr = NULL;
else {
cc->check_set_render_table = True;
value->addr = (char*)&(cc->label_font_list);
}
}
/*
* XmRCallProc routine for checking label_font_list before setting it to NULL
* If column's "check_set_render_table" is True, then function has
* been called twice on same widget, thus resource needs to be set NULL,
* otherwise leave it alone.
*/
/*ARGSUSED*/
static void
CheckSetDefaultEntryLabelRenderTable(Widget wid, int offs, XrmValue *value)
{
XmBulletinBoardPart* bb = BBPart(wid);
XmColumnWidget c = (XmColumnWidget)wid;
/* Check if been here before */
if (c->column.check_set_render_table)
value->addr = NULL;
else {
c->column.check_set_render_table = True;
value->addr = (char*)&(bb->label_font_list);
}
}
/*
* Function:
* XmColumnLabelDestroyedCallback(widget, client, cbdata)
* Description:
* This callback is called when a label that is associated with a field
* is destoyed. The purpose of this callback is to inform the column
* when this happens to it does not try to do bad things.
* Input:
* widget : Widget - the widget being destroyed
* client : XtPointer - the widget that this label is associated with
* cbdata : XtPointer - unused.
* Output:
* None.
*/
/* ARGSUSED */
static void
XmColumnLabelDestroyedCallback(Widget widget, XtPointer client,
XtPointer cbdata)
{
Widget field = (Widget) client;
XiC(field)->label_widget = NULL;
}
/* ARGSUSED */
static void Get_entryLabelString (Widget widget, int offset, XtArgVal *value)
{
(*value) = (XtArgVal) XmStringCopy(XiC(widget)->label_string);
}
/*
* Function:
* XmCreateColumn(parent, name, arg_list, arg_cnt);
* Description:
* Creates an unmanaged instance of an XmColumn and returns its
* widget id.
* Input:
* parent : Widget - the parent of the new instance.
* name : String - the name of the new instance.
* arg_list : ArgList - the arguments to create the instance with.
* arg_cnt : Cardinal - the number of arguments in the list
*
* Output:
* Widget - the widget id of the new instance.
*/
Widget
XmCreateColumn(Widget parent, String name, ArgList arg_list, Cardinal arg_cnt)
{
return( XtCreateWidget(name, xmColumnWidgetClass, parent, arg_list,
arg_cnt) );
}
Widget
XmVaCreateColumn(
Widget parent,
char *name,
...)
{
register Widget w;
va_list var;
int count;
Va_start(var,name);
count = XmeCountVaListSimple(var);
va_end(var);
Va_start(var, name);
w = XmeVLCreateWidget(name,
xmColumnWidgetClass,
parent, False,
var, count);
va_end(var);
return w;
}
Widget
XmVaCreateManagedColumn(
Widget parent,
char *name,
...)
{
Widget w = NULL;
va_list var;
int count;
Va_start(var, name);
count = XmeCountVaListSimple(var);
va_end(var);
Va_start(var, name);
w = XmeVLCreateWidget(name,
xmColumnWidgetClass,
parent, True,
var, count);
va_end(var);
return w;
}