v10i059: wcl -- Widget Creation Library, Part11/11

David E. Smyth david at jpl-devvax.jpl.nasa.gov
Tue Dec 18 09:18:38 AEST 1990


Submitted-by: david at jpl-devvax.jpl.nasa.gov (David E. Smyth)
Posting-number: Volume 10, Issue 59
Archive-name: wcl/part11

# to unbundle, "sh" this file -- DO NOT use csh
#  SHAR archive format.  Archive created Fri Oct 19 09:33:30 PDT 1990
echo x - WcCreateP.h
sed 's/^X//' > WcCreateP.h <<'+FUNKY+STUFF+'
X/*
X** Copyright (c) 1990 David E. Smyth
X**
X** This file was derived from work performed by Martin Brunecky at
X** Auto-trol Technology Corporation, Denver, Colorado, under the
X** following copyright:
X**
X*******************************************************************************
X* Copyright 1990 by Auto-trol Technology Corporation, Denver, Colorado.
X*
X*                        All Rights Reserved
X*
X* Permission to use, copy, modify, and distribute this software and its
X* documentation for any purpose and without fee is hereby granted, provided
X* that the above copyright notice appears on all copies and that both the
X* copyright and this permission notice appear in supporting documentation
X* and that the name of Auto-trol not be used in advertising or publicity
X* pertaining to distribution of the software without specific, prior written
X* permission.
X*
X* Auto-trol disclaims all warranties with regard to this software, including
X* all implied warranties of merchantability and fitness, in no event shall
X* Auto-trol be liable for any special, indirect or consequential damages or
X* any damages whatsoever resulting from loss of use, data or profits, whether
X* in an action of contract, negligence or other tortious action, arising out
X* of or in connection with the use or performance of this software.
X*******************************************************************************
X**
X** Redistribution and use in source and binary forms are permitted
X** provided that the above copyright notice and this paragraph are
X** duplicated in all such forms and that any documentation, advertising
X** materials, and other materials related to such distribution and use
X** acknowledge that the software was developed by David E. Smyth.  The
X** name of David E. Smyth may not be used to endorse or promote products
X** derived from this software without specific prior written permission.
X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X**
X*/
X
X/*
X* SCCS_data: @(#)WcCreateP.h 1.03 ( 13 July 1990 )
X*
X* Include_name:
X*
X*     WcCreateP.h
X*
X* Subsystem_group:
X*
X*     Widget Creation Library
X*
X* Include_description:
X*
X*     Private defines for the Widget Creation Library supporting widget
X*     tree creation from the Xrm database.
X*
X* Include_history:
X*
X*   mm/dd/yy  initials  action
X*   --------  --------  -------------------------------------------------------
X*   06/30/90   R.Whitby added Action declarations
X*   05/24/90   D.Smyth  created from provate section of WsCreate.h
X*   03/02/90   marbru   created
X*
X*******************************************************************************
X*/
X#ifndef _WcCreateP_h
X#define _WcCreateP_h
X
X/*
X*******************************************************************************
X* Private_constant_declarations.
X*******************************************************************************
X*/
X#undef  NUL
X#define NUL '\0'
X#define MAX_XRMSTRING   4096		/* max length of the Xrm DB string  */
X#define MAX_ERRMSG      1024		/* max length of error message      */
X#define MAX_CHILDREN    1024		/* max number of widget's children  */
X#define MAX_PATHNAME    1024		/* max length of the pathname       */
X#define INCR_REGISTRY     32		/* incr of cl, con, cb registries   */
X#define MAX_CALLBACKS     64            /* max callbacks per Xrm resource   */
X#define MAX_WIDGETS      512		/* max depth of a widget tree       */
X#define MAX_ROOT_WIDGETS  32		/* max # separate widget trees	    */
X#define MAX_RES_FILES    512		/* max # res file names per interf  */
X
X#define WcNwcResFile		"wcResFile"
X#define WcNwcChildren		"wcChildren"
X#define WcNwcClass		"wcClass"
X#define WcNwcClassName		"wcClassName"
X#define WcNwcConstructor	"wcConstructor"
X#define WcNwcManaged		"wcManaged"
X#define WcNwcTrace		"wcTrace"
X#define WcNwcCallback		"wcCallback"
X
X#define WcCWcResFile		"WcResFile"
X#define WcCWcChildren		"WcChildren"
X#define WcCWcClass		"WcClass"
X#define WcCWcClassName		"WcClassName"
X#define WcCWcConstructor	"WcConstructor"
X#define WcCWcManaged		"WcManaged"
X#define WcCWcTrace		"WcTrace"
X#define WcCWcCallback		"WcCallback"
X
X/* Motif 1.0 has a bug: widgets ask for Windows 
X** instead of Widgets for their resources...
X*/
X#define WcRWidget		"Window"
X#define WcRClassPtr		"ClassPtr"
X#define WcRClassName		"ClassName"
X#define WcRConstructor		"Constructor"
X/*
X*******************************************************************************
X* Private_type_declarations.
X*******************************************************************************
X*/
X
Xtypedef Widget (*PtrFuncWidget)();	/* ptr to func returning Widget	*/
X
X/* Registration structs: It is a good idea if the classes, class names,
X** constructors, and callbacks are registered with the same upper & lower 
X** case names as the names in the ref manuals and source files, as this 
X** makes the user error messages clearer.
X*/
X
Xtypedef struct                          /* Class cache record		*/
X{
X    String	   name;		/* class ptr name as registered	*/
X    XrmQuark       quark;               /* quarkified class ptr name	*/
X    WidgetClass    class;               /* widget class pointer		*/
X} ClCacheRec;
X
Xtypedef struct                          /* Class Name cache record	*/
X{
X    String	   name;		/* class name as registered	*/
X    XrmQuark       quark;               /* quarkified class name	*/
X    WidgetClass    class;               /* widget class pointer		*/
X} ClNameCacheRec;
X
Xtypedef struct                          /* Constructor cache record	*/
X{
X    String	   name;		/* constructor as registered	*/
X    XrmQuark       quark;               /* quarkified constructor name	*/
X    Widget         (*constructor)();    /* constructor function ptr	*/
X} ConCacheRec;
X
Xtypedef struct				/* Callback cache record	*/
X{
X    String         name;		/* name as registered 		*/
X    XrmQuark       quark;               /* quarkified callback name	*/
X    XtCallbackProc callback;            /* callback procedure pointer	*/
X    caddr_t	   closure;		/* default client data		*/
X} CBCacheRec;
X
Xtypedef struct  _ResourceRec
X{
X    String          resFile;            /* additional resource file name    */
X    String          children;           /* list of children names to create */
X    WidgetClass     class;              /* widget class pointer             */
X    WidgetClass     classFromName;      /* widget class pointer             */
X    ConCacheRec*    constructor;	/* ptr to Constructo cache record   */
X    Boolean         managed;            /* created  managed (default TRUE)  */
X    Boolean         deferred;           /* deferred creation, (def FALSE)   */
X    Boolean         trace;              /* creation trace required          */
X    XtCallbackList  callback;           /* creation callback list           */
X} ResourceRec, *ResourceRecPtr;
X
X/*
X*******************************************************************************
X* Private_macro_definitions.
X*******************************************************************************
X*/
X
X#define ONCE_PER_XtAppContext( app )	\
X{					\
X    static XtAppContext already[1024];	\
X    static int apps = 0;		\
X    int i;				\
X					\
X    for (i = 0; i < apps ; i++)		\
X        if (already[i])			\
X            return;			\
X					\
X    already[++apps] = app;		\
X}
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X    The following cache/registry of known widget classes and contructors,
X    initially empty, are loaded by the application using "registration"
X    routines.
X    Assuming small numbers of constructors, the sequential search
X    of such cache is (initially) considered acceptable.
X*/
X
X/*  -- Named class pointer cache, intially empty */
X
Xextern int         classes_num;
Xextern int         classes_max;
Xextern ClCacheRec* classes_ptr;
X
X/*  -- Class name cache, intially empty */
X
Xextern int             cl_nm_num;
Xextern int             cl_nm_max;
Xextern ClNameCacheRec* cl_nm_ptr;
X
X/*  -- Named object constructor cache, intially empty */
X
Xextern int          constrs_num;
Xextern int          constrs_max;
Xextern ConCacheRec* constrs_ptr;
X
X/*  -- Callback function cache, initially empty */
X
Xextern int	    callbacks_num;
Xextern int	    callbacks_max;
Xextern CBCacheRec*  callbacks_ptr;
X/*  -- Widget Creation resources */
X
Xextern XtResource wc_resources[];
X
X/*
X*******************************************************************************
X* Private_function_declarations.
X*******************************************************************************
X    The following functions are generally private functions to the
X    WcCreate routines, but they may be defined in different files from
X    where they are used.  Client programs probably should not invoke
X    these functions directly.
X*/
X
X#ifdef FUNCTION_PROTOTYPES
X/****************************** ANSI FUNC DECLS ******************************/
X
X#define EV extern void
X
X/*  -- Resource converters */
X
XEV WcAddConverters     ( XtAppContext );
XEV CvtStringToClassPtr    ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
XEV CvtStringToClassName   ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
XEV CvtStringToConstructor ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
XEV CvtStringToCallback    ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
XEV CvtStringToWidget      ( XrmValue*, Cardinal*, XrmValue*, XrmValue* );
X
X/*  -- Find root widget of argument, remember if never seen before */
X
Xextern Widget WcRootWidget	( Widget );
X
X/*  -- Convenience Callbacks - Clients generally invoke these only
X       by binding them to widgets via the resource file.  They can
X       be programmatically bound, but generally should not be.
X*/
X
XEV WcCreateChildrenCB     (Widget w, char* parent_children, caddr_t unused   );
XEV WcManageCB             (Widget w, char* widgetNames,     caddr_t unused   );
XEV WcUnmanageCB           (Widget w, char* widgetNames,     caddr_t unused   );
XEV WcManageChildrenCB     (Widget w, char* parent_children, caddr_t unused   );
XEV WcUnmanageChildrenCB   (Widget w, char* parent_children, caddr_t unused   );
XEV WcDestroyCB            (Widget w, char* widgetNames,     caddr_t unused   );
XEV WcSetValueCB           (Widget w, char* name_res_resVal, caddr_t unused   );
XEV WcSetSensitiveCB       (Widget w, char* widgetNames,     caddr_t unused   );
XEV WcSetInsensitiveCB     (Widget w, char* widgetNames,     caddr_t unused   );
XEV WcLoadResourceFileCB   (Widget w, char* resFileName,     caddr_t unused   );
XEV WcTraceCB              (Widget w, char* annotation,      caddr_t unused   );
XEV WcPopupCB              (Widget w, char* widgetName,	    caddr_t unused   );
XEV WcPopupGrabCB          (Widget w, char* widgetName,	    caddr_t unused   );
XEV WcPopdownCB            (Widget w, char* widgetName,      caddr_t unused   );
XEV WcMapCB                (Widget w, char* widgetName,      caddr_t unused   );
XEV WcUnmapCB              (Widget w, char* widgetName,      caddr_t unused   );
XEV WcSystemCB             (Widget w, char* shellCmdString,  caddr_t unused   );
XEV WcExitCB               (Widget w, char* exitValue,       caddr_t unused   );
X
X/*  -- Convenience Actions - Clients generally invoke these only
X       by binding them to widgets via the resource file.  They can
X       be programmatically bound, but generally should not be.
X*/
X
X#define ACT_ARGS Widget w, XEvent *event, String *params, Cardinal *num_params
X
XEV WcCreateChildrenACT    ( ACT_ARGS );
XEV WcManageACT            ( ACT_ARGS );
XEV WcUnmanageACT          ( ACT_ARGS );
XEV WcManageChildrenACT    ( ACT_ARGS );
XEV WcUnmanageChildrenACT  ( ACT_ARGS );
XEV WcDestroyACT           ( ACT_ARGS );
XEV WcSetValueACT          ( ACT_ARGS );
XEV WcSetSensitiveACT      ( ACT_ARGS );
XEV WcSetInsensitiveACT    ( ACT_ARGS );
XEV WcLoadResourceFileACT  ( ACT_ARGS );
XEV WcTraceACT             ( ACT_ARGS );
XEV WcPopupACT             ( ACT_ARGS );
XEV WcPopupGrabACT         ( ACT_ARGS );
XEV WcPopdownACT           ( ACT_ARGS );
XEV WcMapACT               ( ACT_ARGS );
XEV WcUnmapACT             ( ACT_ARGS );
XEV WcSystemACT            ( ACT_ARGS );
XEV WcExitACT              ( ACT_ARGS );
X
X#undef ACT_ARGS
X#undef EV
X
X#else
X/**************************** NON-ANSI FUNC DECLS ****************************/
X
X/*  -- Resource converters */
X
Xextern void WcAddConverters        ();
Xextern void CvtStringToClassPtr    ();
Xextern void CvtStringToClassName    ();
Xextern void CvtStringToConstructor ();
Xextern void CvtStringToCallback    ();
Xextern void CvtStringToWidget      ();
X
X/*  -- Find root widget of argument, remember if never seen before */
X
Xextern Widget WcRootWidget ();
X
X/*  -- Convenience Callbacks - Clients generally invoke these only
X       by binding them to widgets via the resource file.  They can
X       be programmatically bound, but generally should not be.
X*/
X
Xextern void WcCreateChildrenCB     ();
Xextern void WcManageCB             ();
Xextern void WcUnmanageCB           ();
Xextern void WcManageChildrenCB     ();
Xextern void WcUnmanageChildrenCB   ();
Xextern void WcDestroyCB            ();
Xextern void WcSetValueCB           ();
Xextern void WcSetSensitiveCB       ();
Xextern void WcSetInsensitiveCB     ();
Xextern void WcLoadResourceFileCB   ();
Xextern void WcTraceCB              ();
Xextern void WcPopupCB              ();
Xextern void WcPopupGrabCB          ();
Xextern void WcPopdownCB            ();
Xextern void WcMapCB                ();
Xextern void WcUnmapCB              ();
Xextern void WcSystemCB             ();
Xextern void WcExitCB               ();
X
X/*  -- Convenience Actions - Clients generally invoke these only
X       by binding them to widgets via the resource file.  They can
X       be programmatically bound, but generally should not be.
X*/
X
Xextern void WcCreateChildrenACT    ();
Xextern void WcManageACT            ();
Xextern void WcUnmanageACT          ();
Xextern void WcManageChildrenACT    ();
Xextern void WcUnmanageChildrenACT  ();
Xextern void WcDestroyACT           ();
Xextern void WcSetValueACT          ();
Xextern void WcSetSensitiveACT      ();
Xextern void WcSetInsensitiveACT    ();
Xextern void WcLoadResourceFileACT  ();
Xextern void WcTraceACT             ();
Xextern void WcPopupACT             ();
Xextern void WcPopupGrabACT         ();
Xextern void WcPopdownACT           ();
Xextern void WcMapACT               ();
Xextern void WcUnmapACT             ();
Xextern void WcSystemACT            ();
Xextern void WcExitACT              ();
X
X#endif /* FUNCTION_PROTOTYPES */
X
X#ifdef DEBUG
X#ifdef MOTIF
X#include "WcMotifP.h"
X#else
X#include "WcAthenaP.h"
X#endif
X#endif
X
X#endif /* _WcCreateP_h */
+FUNKY+STUFF+
echo '-rw-r--r--  1 david       14725 Oct 16 14:38 WcCreateP.h    (as sent)'
chmod u=rw,g=r,o=r WcCreateP.h
ls -l WcCreateP.h
echo x - WcMotifP.h
sed 's/^X//' > WcMotifP.h <<'+FUNKY+STUFF+'
X/*
X** Copyright (c) 1990 David E. Smyth
X** 
X** Redistribution and use in source and binary forms are permitted
X** provided that the above copyright notice and this paragraph are
X** duplicated in all such forms and that any documentation, advertising
X** materials, and other materials related to such distribution and use
X** acknowledge that the software was developed by David E. Smyth.  The
X** name of David E. Smyth may not be used to endorse or promote products
X** derived from this software without specific prior written permission.
X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X** 
X*/
X
X/*
X* SCCS_data: @(#)WcMotifP.h 1.0 ( 19 June 1990 )
X*/
X
X#ifndef _WcMotifP_h_
X#define _WcMotifP_h_
X
X/* Core, Object, RectObj, WindowObj, 
X** XmGadget, XmPrimitive, and XmComposite, 
X** Shell, OverrideShell, WMShell, VendorShell, TopLevelShell, ApplicationShell, 
X** Constraint, XmManager.
X*/
X#include <Xm/XmP.h>
X
X/* XmGadget Subclasses
X*/
X#include <Xm/ArrowBGP.h>
X#include <Xm/SeparatoGP.h>
X#include <Xm/LabelGP.h>
X#include <Xm/CascadeBGP.h>
X#include <Xm/PushBGP.h>
X#include <Xm/ToggleBGP.h>
X
X/* XmPrimitive Subclasses
X*/
X#include <Xm/ArrowBP.h>
X#include <Xm/ListP.h>
X#include <Xm/ScrollBarP.h>
X#include <Xm/SeparatorP.h>
X#include <Xm/TextP.h>
X#include <Xm/LabelP.h>
X#include <Xm/CascadeBP.h>
X#include <Xm/DrawnBP.h>
X#include <Xm/PushBP.h>
X#include <Xm/ToggleBP.h>
X
X/* XmManager Subclasses
X*/
X#include <Xm/DrawingAP.h>
X#include <Xm/FrameP.h>
X#include <Xm/PanedWP.h>
X#include <Xm/RowColumnP.h>
X#include <Xm/ScaleP.h>
X#include <Xm/ScrolledWP.h>
X#include <Xm/MainWP.h>
X#include <Xm/BulletinBP.h>
X#include <Xm/FormP.h>
X#include <Xm/MessageBP.h>
X#include <Xm/SelectioBP.h>
X#include <Xm/CommandP.h>
X#include <Xm/FileSBP.h>
X
X/* Shell Subclasses
X*/
X#include <X11/ShellP.h>
X#include <X11/VendorP.h>
X#include <Xm/MenuShellP.h>
X#include <Xm/DialogSP.h>
X
X/* Apparently Obsolete 
X*/
X#include <Xm/SashP.h>
X
X#endif
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        2048 Aug  6 09:36 WcMotifP.h    (as sent)'
chmod u=rw,g=r,o=r WcMotifP.h
ls -l WcMotifP.h
echo x - WcName.c
sed 's/^X//' > WcName.c <<'+FUNKY+STUFF+'
X/*
X** Copyright (c) 1990 David E. Smyth
X**
X** Redistribution and use in source and binary forms are permitted
X** provided that the above copyright notice and this paragraph are
X** duplicated in all such forms and that any documentation, advertising
X** materials, and other materials related to such distribution and use
X** acknowledge that the software was developed by David E. Smyth.  The
X** name of David E. Smyth may not be used to endorse or promote products
X** derived from this software without specific prior written permission.
X** THIS SOFTWARE IS PROVIDED ``AS IS'' AND WITHOUT ANY EXPRESS OR IMPLIED
X** WARRANTIES, INCLUDING, WITHOUT LIMITATION, THE IMPLIED WARRANTIES OF
X** MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE.
X**
X*/
X
X/******************************************************************************
X** SCCS_data: @(#)WcName.c 1.0 ( 19 June 1990 )
X**
X** Description:	Implements several name-to-widget and widget-to-name
X**		functions which are generally useful, especially a name 
X**		to widget function which really works:
X**
X**			Widget WcFullNameToWidget(char* widget_name)
X**
X**		The widget names understood by WcFullNameToWidget() are
X**		a superset of those understood by XtNameToWidget in
X**		the X11R4 version of libXt.  XtNameToWidget only knows
X**		how to find children of a reference widget, and so the
X**		names start _below- the refernce widget.  However,
X**		WcFullNameToWidget knows how to find widgets anywhere
X**		in the widget tree: it normally starts the name search
X**		from the root of the widget tree, but it can also
X**		perform the name search relatively from the reference
X**		widget, both up and down the widget tree.
X**
X**		When name searches start at the root of the widget
X**		tree, the same syntax as that understood by Xrm is
X**		used.  Below are four examples of acceptable names:
X**
X**			*foo			*foo.XmRowColumn*glorp
X**			Mri.some*other.foo	*Form.glorp
X**
X**		Note that components may be class names, such as
X**		XmRowColumn, or may be instance names of the widgets.
X**		Ambiguous names are resolved exactly as done by 
X**		XtNameToWidget: shallowest wins, `.' binds tighter
X**		than `*', instance names bind tighter than class
X**		names.
X**
X**		In addition to resolving names from the root of the
X**		widget tree, WcFullNameToWidget also can find widget
X**		using a relative root prefix.  Three special characters
X**		are used:
X**
X**			^	means "parent"
X**			~	means the closest shell ancestor
X**			.	means start at the reference widget
X**
X**		The relative root prefix characters are exactly that:
X**		a prefix of a name which will then be passed to
X**		XtNameToWidget.  Some examples:
X**
X**			.foo	a child of the reference widget
X**			^foo	a sibling of the reference widget
X**			^^foo	a sibling of the ref' widgets's parent
X**			~foo	a child of the shell ancestor.
X**			~~*foo	some child of the shell's shell ancestor.
X**
X**		The ^ and ~ prefix characters are only valid at the 
X**		beginning.  They effectively operate on the reference
X**		widget.
X**
X**		In all cases, the characters are scanned left to right.
X**		So, the first character is acted upon, then the second,
X**		and so on.
X**		
X** Notes:	Most of the "private" part of this file goes away when 
X**		the bug in the Xt Intrinsics is fixed which causes 
X**		XtNameToWidget() to dump core whenever a Gadget exists 
X**		in the widget heirarchy...
X**
X******************************************************************************/
X
X/******************************************************************************
X* Include_files.
X******************************************************************************/
X
X#include <ctype.h>      /* isupper() and tolower macros */
X
X/*  -- X Window System includes */
X#include <X11/StringDefs.h>
X
X#ifdef MOTIF
X#include <Xm/XmP.h>
X#endif
X
X/*  -- Widget Creation Library includes */
X#include "WcCreate.h"
X#include "WcCreateP.h"
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X*/
X
X/* shared error message and name buffers
X*******************************************************************************
X** NOTE: These are shared arrays because they are large: i.e.,
X** this is a performacne optimization intended to reduce page
X** faults which can occur while making large extensions to the
X** stack space.  Wait a minute: wouldn't this just happen
X** once, and then the stack space is alloc'd?  Yes, but a
X** huge stack space runs the risk of getting swapped, which causes
X** page faults.  This is probably a nit-picky sort of optimization.
X** Remember that D.Smyth is an old sys programmer from the stone
X** ages, and pity him instead of flaming him.
X** Be careful when filling msg not to call any funcs in here,
X** so the message does not get garbled.
X*/
X
Xstatic char     msg[MAX_ERRMSG];
Xstatic char     cleanName[MAX_PATHNAME];
X
X/* Private Data involving the root widget list
X*******************************************************************************
X*/
X
Xstatic int    numRoots = 0;
Xstatic Widget rootWidgets[MAX_ROOT_WIDGETS];
X
X/*
X*******************************************************************************
X* Private_function definitions.
X*******************************************************************************
X/*
X    The following is the XtGetConstraintResourceList function from
X    the R4 Intrinsics.  This function is not provided by the Motif
X    1.0 Intrinsics.  Only change: ConstraintClassFlag was changed to
X    _XtConstraintBit.
X*/
X
X#if defined(MOTIF) && defined(MOTIF_MINOR) && MOTIF == 1 && MOTIF_MINOR == 0
X#include <X11/IntrinsicP.h>
X/*************** Begin source from X11R4 GetResList.c ***************/
X
Xstatic Boolean ClassIsSubclassOf(class, superclass)
X    WidgetClass class, superclass;
X{
X    for (; class != NULL; class = class->core_class.superclass) {
X	if (class == superclass) return True;
X    }
X    return False;
X}
X
Xvoid XtGetConstraintResourceList(widget_class, resources, num_resources)
X	WidgetClass widget_class;
X	XtResourceList *resources;
X	Cardinal *num_resources;
X{
X	int size;
X	register int i, dest = 0;
X	register XtResourceList *list, dlist;
X	ConstraintWidgetClass class = (ConstraintWidgetClass)widget_class;
X
X	if (   (class->core_class.class_inited &&
X		!(class->core_class.class_inited & _XtConstraintBit)) /* DES */
X	    || (!class->core_class.class_inited &&
X		!ClassIsSubclassOf(widget_class, constraintWidgetClass))
X	    || class->constraint_class.num_resources == 0) {
X
X	    *resources = NULL;
X	    *num_resources = 0;
X	    return;
X	}
X
X	size = class->constraint_class.num_resources * sizeof(XtResource);
X	*resources = (XtResourceList) XtMalloc((unsigned) size);
X
X	if (!class->core_class.class_inited) {
X	    /* Easy case */
X
X	    bcopy((char *)class->constraint_class.resources,
X		    (char *) *resources, size);
X	    *num_resources = class->constraint_class.num_resources;
X	    return;
X	}
X
X	/* Nope, it's the hard case */
X
X	list = (XtResourceList *) class->constraint_class.resources;
X	dlist = *resources;
X	for (i = 0; i < class->constraint_class.num_resources; i++) {
X	    if (list[i] != NULL) {
X		dlist[dest].resource_name = (String)
X			XrmQuarkToString((XrmQuark) list[i]->resource_name);
X		dlist[dest].resource_class = (String) 
X			XrmQuarkToString((XrmQuark) list[i]->resource_class);
X		dlist[dest].resource_type = (String)
X			XrmQuarkToString((XrmQuark) list[i]->resource_type);
X		dlist[dest].resource_size = list[i]->resource_size;
X		dlist[dest].resource_offset = -(list[i]->resource_offset + 1);
X		dlist[dest].default_type = (String)
X			XrmQuarkToString((XrmQuark) list[i]->default_type);
X		dlist[dest].default_addr = list[i]->default_addr;
X		dest++;
X	    }
X	}
X	*num_resources = dest;
X}
X
X/*************** End source from X11R4 GetResList.c ***************/
X#endif /* MOTIF 1.0 */
X
X/*
X    The following implements XtNameToWidget() in a way which really works.
X
X    Note: the #if defined... assumes a FIXED version of R4.  The version
X    even as of 19 June 1990 still is not correct (dumps core on Gadgets).
X*/
X
X#if defined(XtSpecificationRelease) && XtSpecificationRelease > 4
X
XWidget WcChildNameToWidget( Widget ref, char* childName)
X{
X    return XtNameToWidget( ref, childName );
X}
X
X#else
X
X/* NOTE: The Motif 1.0 XtNameToWidget is broken: it cannot find
X** names with wild cards.  The R4 XtNameToWidget is also broken: it
X** cannot handle encounters with Gadgets.
X**
X** Below is the code extracted from the X11R4 distribution, with very
X** minor changes to make it independent from the rest of the R4 Intrinsics, 
X** and to fix the bug in encountering Gadgets.
X** 
X** Fixes: Added the two lines following this comment block.
X**	  Renamed XtNameToWidget to WcChildNameToWidget to avoid warning.
X**	  Removed "register" from arg type decls, as dbx does these
X**	  incorrectly, and a decent compiler (gcc) does this anyway.
X** -->	  Before looking for children, see if a widget is a gadget.
X**	     Gadgets can't have children, in fact those fields are
X**	     something else entirely!!!
X*/
X
X/*************** Begin source from X11R4 Xtos.h ***************/
X
X#ifndef ALLOCATE_LOCAL
X#define ALLOCATE_LOCAL(size) XtMalloc((unsigned long)(size))
X#define DEALLOCATE_LOCAL(ptr) XtFree((caddr_t)(ptr))
X#endif /* ALLOCATE_LOCAL */
X
X/*************** End source from X11R4 Xtos.h ***************/
X
X#define _XtAllocError		XtError
X
X/*************** Begin source from X11R4 lib/Xt/Intrinsics.c ***************/
X
Xstatic Widget NameListToWidget();
X
Xtypedef Widget (*NameMatchProc)();
X
Xstatic Widget MatchExactChildren(names, bindings, children, num,
X        in_depth, out_depth, found_depth)
X    XrmNameList     names;
X    XrmBindingList  bindings;
X    WidgetList children;
X    int num;
X    int in_depth, *out_depth, *found_depth;
X{
X    Cardinal   i;
X    XrmName    name = *names;
X    Widget w, result = NULL;
X    int d, min = 10000;
X
X    for (i = 0; i < num; i++) {
X        if (name == children[i]->core.xrm_name) {
X            w = NameListToWidget(children[i], &names[1], &bindings[1],
X                    in_depth+1, &d, found_depth);
X            if (w != NULL && d < min) {result = w; min = d;}
X        }
X    }
X    *out_depth = min;
X    return result;
X}
X
Xstatic Widget MatchWildChildren(names, bindings, children, num,
X        in_depth, out_depth, found_depth)
X    XrmNameList     names;
X    XrmBindingList  bindings;
X    WidgetList children;
X    int num;
X    int in_depth, *out_depth, *found_depth;
X{
X    Cardinal   i;
X    Widget w, result = NULL;
X    int d, min = 10000;
X
X    for (i = 0; i < num; i++) {
X        w = NameListToWidget(children[i], names, bindings,
X                in_depth+1, &d, found_depth);
X        if (w != NULL && d < min) {result = w; min = d;}
X    }
X    *out_depth = min;
X    return result;
X}
X
Xstatic Widget SearchChildren(root, names, bindings, matchproc,
X        in_depth, out_depth, found_depth)
X    Widget root;
X    XrmNameList     names;
X    XrmBindingList  bindings;
X    NameMatchProc matchproc;
X    int in_depth, *out_depth, *found_depth;
X{
X    Widget w1, w2;
X    int d1, d2;
X
X#if defined(MOTIF) && MOTIF == 1 && MOTIF_MINOR == 0
X    if (XmIsGadget(root)) {
X#else
X    if (!XtIsWidget(root)) {
X#endif
X	*out_depth = 10000;	/* I don't know what this should be */
X	return (Widget)NULL;
X    }
X    if (XtIsComposite(root)) {
X        w1 = (*matchproc)(names, bindings,
X                ((CompositeWidget) root)->composite.children,
X                ((CompositeWidget) root)->composite.num_children,
X                in_depth, &d1, found_depth);
X    } else d1 = 10000;
X    w2 = (*matchproc)(names, bindings, root->core.popup_list,
X            root->core.num_popups, in_depth, &d2, found_depth);
X    *out_depth = (d1 < d2 ? d1 : d2);
X    return (d1 < d2 ? w1 : w2);
X}
X
Xstatic Widget NameListToWidget(root, names, bindings,
X        in_depth, out_depth, found_depth)
X    Widget root;
X    XrmNameList     names;
X    XrmBindingList  bindings;
X    int in_depth, *out_depth, *found_depth;
X{
X    Widget w1, w2;
X    int d1, d2;
X
X    if (in_depth >= *found_depth) {
X        *out_depth = 10000;
X        return NULL;
X    }
X
X    if (names[0] == NULLQUARK) {
X        *out_depth = *found_depth = in_depth;
X        return root;
X    }
X
X    if (*bindings == XrmBindTightly) {
X        return SearchChildren(root, names, bindings, MatchExactChildren,
X                in_depth, out_depth, found_depth);
X
X    } else {    /* XrmBindLoosely */
X        w1 = SearchChildren(root, names, bindings, MatchExactChildren,
X                in_depth, &d1, found_depth);
X        w2 = SearchChildren(root, names, bindings, MatchWildChildren,
X                in_depth, &d2, found_depth);
X        *out_depth = (d1 < d2 ? d1 : d2);
X        return (d1 < d2 ? w1 : w2);
X    }
X} /* NameListToWidget */
X
XWidget WcChildNameToWidget( ref, name )  /* was XtNameToWidget */
X    Widget ref;
X    char*  name;
X{
X    XrmName *names;
X    XrmBinding *bindings;
X    int len, depth, found = 10000;
X    Widget result;
X
X    len = strlen(name);
X    if (len == 0) return NULL;
X
X    names = (XrmName *) ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmName));
X    bindings = (XrmBinding *)
X        ALLOCATE_LOCAL((unsigned) (len+1) * sizeof(XrmBinding));
X    if (names == NULL || bindings == NULL) _XtAllocError("alloca");
X
X    XrmStringToBindingQuarkList(name, bindings, names);
X    if (names[0] == NULLQUARK) {
X        DEALLOCATE_LOCAL((char *) names);
X        DEALLOCATE_LOCAL((char *) bindings);
X        return NULL;
X    }
X
X    result = NameListToWidget(ref, names, bindings, 0, &depth, &found);
X
X    DEALLOCATE_LOCAL((char *) names);
X    DEALLOCATE_LOCAL((char *) bindings);
X    return result;
X} /* WcChildNameToWidget */
X
X/*************** End of source from X11R4 lib/Xt/Intrinsics.c ***************/
X#endif
X
X/******************************************************************************
X** Public functions
X******************************************************************************/
X
X/*******************************************************************************
X** Allocate and return a lower case copy of the input string.
X** Caller must free output string!
X*******************************************************************************/
X
Xchar* WcLowerCaseCopy( in )
X    char* in;
X{
X    char* retVal = (char*)XtMalloc( 1 + strlen ( in ) );
X    char* cp = retVal;
X
X    while (*in)
X    {
X	*cp = (isupper(*in) ? tolower(*in) : *in );
X	cp++ ; in++ ;
X    }
X    *cp = NUL;
X    return retVal;
X}
X
X/******************************************************************************
X**  Return "clean" widget name, resource, or value from string
X*******************************************************************************
X    This function strips leading and trailing whitespace from the
X    passed in char*.  Note that the caller must allocate and free
X    the returned character buffer.
X******************************************************************************/
X
Xchar* WcSkipWhitespace( cp )
X    char* cp;
X{
X    while ( *cp && *cp <= ' ' )
X        cp++;
X    return cp;
X}
X
Xchar* WcSkipWhitespace_Comma( cp )
X    char* cp;
X{
X    while ( *cp && *cp <= ' ' )		/* cp = WcSkipWhitespace ( cp ); */
X        cp++;
X    if ( *cp == ',' )
X        cp++;
X    return cp;
X}
X
Xchar* WcCleanName( in, out )
X    char* in;
X    char* out;
X{
X    /* copy from in[] into out[],
X    ** ignore initial whitespace,
X    ** stop at trailing whitespace or comma.
X    ** Returns pointer to whitespace or comma following name.
X    */
X    while ( *in && *in <= ' ' )		/* in = WcSkipWhitespace( in ); */
X	in++;
X    for ( ; (*in > ' ' && *in != ',') ; in++ )
X        *out++ = *in;
X    *out = NUL;
X    return in;  /* this points at 1st whitespace or comma following "out" */
X}
X
X/* This function is necessary because XtNameToWidget cannot really
X** take a widget name which begins at the top level shell, but rather
X** only names which pretend the widget BELOW the top level shell is
X** the top level shell.  I have no idea why some thought the
X** Xt implementation is correct.  Quoting from the Xt manual:
X**
X**   XtNameToWidget returns the descendent [of root] ... according to
X**   the following rules, ... :
X**
X**   o	... qualifying the name of each object with the names of all
X**	its ancestors up to _but_not_including_ the reference widget.
X**
X** Since this is not useful for our purposes, we need to first do some 
X** screwing around to see if the user specified the widget name like one 
X** would specify any other widget name in the resource file.
X*/
X
Xchar* WcStripWhitespaceFromBothEnds( name )
X    char* name;
X{
X    char* first; 
X    char* last;
X    char* buff;
X    char* bp;
X
X    for ( first = name ; *first <= ' ' ; first ++ )
X	;
X    for ( last = first ; *last ; last++ )
X	;
X    for ( last-- ; *last <= ' ' ; last-- )
X	;
X    buff = (char*)XtMalloc( (last - first) + 2 );
X    for ( bp = buff ; first <= last ; bp++, first++ )
X	*bp = *first;
X    *bp = NUL;
X
X    return buff;
X}
X
X/*
X    -- Find the named widget
X*******************************************************************************
X
X    This function uses WcChildNameToWidget to search a widget tree for a
X    widget with the given name.  WcChildNameToWidget is basically
X    XtNameToWidget from X11R4, but hacked so it works when there are
X    Gadgets in the widget tree.
X
X    WcChildNameToWidget, like XtNameToWidget, starts searching for children
X    of a reference widget.  WcFullNameToWidget examines the first few
X    characters of the `name' argument in order to determine which widget is
X    the reference whidget where the search will begin.
X
X    The possibilities are these:  The `name' can begin with one or more of
X    the relative prefix characters: ^ or ~, which means the reference
X    widget will be some relative node in the widget tree, such as the
X    parent or the shell ancestor.  Otherwise, the  root widget will be the
X    starting point.
X*/
X
XWidget WcFullNameToWidget( w, name )
X    Widget w;
X    char*  name;
X{
X    Widget retWidget;
X    char  *widgetName;
X    char  *lowerName;
X    int    i;
X
X    widgetName = WcStripWhitespaceFromBothEnds( name );	/* must be XtFree'd */
X
X    if ( widgetName[0] == '*' )
X    {
X	retWidget = WcChildNameToWidget( WcRootWidget(w), widgetName );
X	XtFree( widgetName );
X	return retWidget;
X    }
X
X    if (widgetName[0] == '^' 
X     || widgetName[0] == '~' 
X     || widgetName[0] == '.')
X    {
X	i = 0;
X	while (widgetName[i] == '^' 	/* parent */
X	    || widgetName[i] == '~' 	/* shell ancestor */
X	    || widgetName[i] == '.')	/* eaten and ignored */
X	{
X	    if (widgetName[i] == '^')
X	    {
X		w = XtParent( w );
X	    }
X	    else if (widgetName[i] == '~')
X	    {
X		/* There is a bug in /usr/include/X11/IntrinsicP.h, in
X		** the XtIsShell() macro.  It does not parenthesize its
X		** argument when it uses it.  Therefore, the extra 
X		** parens are necessary here!
X		*/
X		while (! XtIsShell( (w = XtParent(w)) ) )
X		    ;
X	    }
X	    i++;
X	}
X	if (widgetName[i] == '\0')
X	    retWidget = w;
X	else
X	    retWidget = WcChildNameToWidget( w, &(widgetName[i]) );
X	XtFree( widgetName );
X	return retWidget;
X    }
X
X    lowerName  = WcLowerCaseCopy( widgetName );         /* must be XtFree'd */
X
X    if ( 0 == strcmp( "this", lowerName ) )
X    {
X	XtFree( widgetName );
X	XtFree( lowerName  );
X	return w;
X    }
X
X    /* Apparently, the widget name starts with a name.  We need to find
X    ** which root widget has this name.  We need to go down the list of
X    ** root widgets maintained by WcRootWidget().
X    */
X
X    {
X	Widget	root;
X	Widget  root_of_w;
X	char*	rootName;
X	char*	lowerRootName;
X	int     widgetNameLen = strlen(lowerName);
X	int	rootNameLen;
X	int	startsWithRootName;
X	char*	stripped;
X
X	/* most of the time, a widget names something else in its
X	** own widget heirarchy.  Therefore, see if the naming starts
X	** at the root widget of `w' but don't check that widget again.
X	*/
X	root_of_w = root = WcRootWidget( w ) ;
X	i = -1;
X
X	while(1)
X	{
X	    rootName = XrmQuarkToString( root->core.xrm_name );
X	    lowerRootName = WcLowerCaseCopy( rootName );       /* XtFree this */
X	    rootNameLen = strlen( lowerRootName );
X	    startsWithRootName = !strncmp(lowerName,lowerRootName,rootNameLen);
X
X	    if ( startsWithRootName && widgetName[rootNameLen] == '*' )
X	    {
X	        /* the root widget name is followed by a `*' so strip the
X		** root name, but keep the star as it implies loose binding.
X		*/
X		stripped = &widgetName[rootNameLen];
X                retWidget = WcChildNameToWidget( root, stripped );
X		XtFree( widgetName    );
X		XtFree( lowerName     );
X		XtFree( lowerRootName );
X		return retWidget;
X	    }
X
X	    else if ( startsWithRootName && widgetName[rootNameLen] == '.' )
X	    {
X		/* the root widget name is followed by a `.' so strip the
X		** root name and the period to imply tight binding.
X		*/
X		stripped = &widgetName[++rootNameLen];
X		retWidget = WcChildNameToWidget( root, stripped );
X		XtFree( widgetName    );
X		XtFree( lowerName     );
X		XtFree( lowerRootName );
X		return retWidget;
X	    }
X
X	    else if ( startsWithRootName && (widgetNameLen == rootNameLen) )
X	    {
X		/* widgetName is the root widget. */
X		XtFree( widgetName    );
X                XtFree( lowerName     );
X                XtFree( lowerRootName );
X                return root;
X	    }
X
X	    /* Did not find the root name.  Try the next, but skip the
X	    ** root_of_w which we checked first.
X	    */
X	    if (++i == numRoots)
X		break;
X	    if (root_of_w == (root = rootWidgets[i]) )
X	    {
X		if (++i == numRoots)
X		    break;
X	        root = rootWidgets[i];
X	    }
X	}
X
X	/* Completely unsucessful in parsing this name. */
X#ifdef DEBUG
X	sprintf( msg,
X	    "WcFullNameToWidget cannot convert `%s' to widget \n\
X	     Problem: Widget name must start with `*' or `.' or `~' or `^'\n\
X	              or `<aRoot>*' or `<aRoot>.' or be `this'" ,
X	     widgetName );
X	XtWarning( msg ); 
X#endif
X
X	XtFree( widgetName );
X	XtFree( lowerName );
X	XtFree( lowerRootName );
X	return NULL;
X    }
X}
X
X/*
X    -- Names to Widget List
X******************************************************************************
X    This routine converts a string of comma separated widget names
X    (or widget paths) into a list of widget id's. Blank space ignored.
X    If a NULL string is provided, NULL is put on the list.
X
X    The return value is the list of names which could NOT be
X    converted.  Note that this list is fixed size, and is re-used.
X*/
X
Xchar* WcNamesToWidgetList ( w, names, widget_list, widget_count )
X    Widget      w;                  /* reference widget */
X    char*       names;              /* string of widget names */
X    Widget      widget_list[];      /* returned widget list */
X    int	       *widget_count;       /* in widget_list[len], out widget count */
X{
X    static char ignored[MAX_XRMSTRING];
X    char*	next   = names;
X    int		max    = *widget_count;
X
X/*  -- parse the input names "widgetpath [, widgetpath] ..." */
X    ignored[0] = NUL;
X    *widget_count = 0;
X
X    do 
X    {
X	next = WcCleanName ( next, cleanName );
X
X	if ( widget_list[*widget_count] = WcFullNameToWidget ( w, cleanName ) )
X	    (*widget_count)++;
X	else
X	{
X	    if (ignored[0] == NUL)
X		strcpy(ignored, cleanName);
X	    else
X	    {
X		strcat(ignored, ", ");
X		strcat(ignored, cleanName);
X	    }
X	}
X	next = WcSkipWhitespace_Comma ( next );
X
X    } while ( *next && *widget_count < max) ;
X
X    return ignored;
X}
X
X/*
X    -- WidgetToFullName
X*******************************************************************************
X    Traverse up the widget tree, sprintf each name right up to
X    the root of the widget tree.  sprintf the names to buffer.  Use
X    recursion so order of names comes out right.  Client MUST free
X    the char string alloc's and returned by WcWidgetToFullName().
X
X    Note: If using the Motif widget set, it is likely (almost inavoidable)
X    that the "widget" may actually be a Gadget.  Well, Gadgets don't have
X    many things, particularly a core.name member.  Therefore, if using
X    Motif we must check to see if the "widget" is not actually an XmGadget.
X    If is it, then we must use XrmQuarkToString(w->core.xrm_name) rather
X    than core.name (unfortunately).  I'd rather not use the xrm name because
X    the case has been flattened: everything is lower case.  Name something
X    SomeComplexLongName and you get back somecomplexlongname.  The case
X    is always insignificant, but the mixed case name is easier to read.
X*/
X
Xstatic char* nextChar;
X
Xstatic int FullNameLen( w )
X    Widget w;
X{
X    int len;
X
X#if defined(MOTIF) && MOTIF == 1 && MOTIF_MINOR == 0
X    if (XmIsGadget(w))
X#else
X    if (XtIsWidget(w) == 0)
X#endif
X	len = 1 + strlen ( XrmQuarkToString(w->core.xrm_name) );
X    else
X	len = 1 + strlen ( w->core.name );
X
X    if (w->core.parent)
X	len += FullNameLen(w->core.parent);
X    return len;
X}
X
Xstatic void WidgetToFullName( w )
X    Widget w;
X{
X    char* cp;
X
X    if (w->core.parent)
X    {
X        WidgetToFullName( w->core.parent );	/* nextChar AFTER parent name */
X	*nextChar++ = '.';			/* inter-name `dot' */
X    }
X
X#if defined(MOTIF) && MOTIF == 1 && MOTIF_MINOR == 0
X    if (XmIsGadget(w))
X#else
X    if (XtIsWidget(w) == 0)
X#endif
X	cp = XrmQuarkToString(w->core.xrm_name);
X    else
X        cp = w->core.name;
X
X    while (*cp)
X	*nextChar++ = *cp++;
X}
X
Xchar* WcWidgetToFullName( w )
X    Widget w;
X{
X    char* buff = XtMalloc( FullNameLen( w ) );
X
X    nextChar = buff;
X
X    WidgetToFullName( w );
X    *nextChar = NUL;
X			
X    return buff;
X}
X
X/*
X    -- Search widget's resource list for resource_type
X*******************************************************************************
X    Gets the XtResourceList from the widget, searches the list for
X    the resource name to determine the type required, which is then
X    returned to the caller.
X*/
X
Xchar* WcGetResourceType( w, res_name )
X    Widget w;
X    char*  res_name;
X{
X    XtResource* res_list;
X    int         i, num;
X    char*	retstr;
X
X    XtGetResourceList( w->core.widget_class, &res_list, &num );
X
X    for ( i = 0 ; i < num ; i++ )
X    {
X        if (0 == strcmp( res_name, res_list[i].resource_name) 
X	 || 0 == strcmp( res_name, res_list[i].resource_class) )
X	{
X            retstr = XtNewString(res_list[i].resource_type);
X	    XtFree( res_list );
X	    return retstr;
X	}
X    }
X
X    w = XtParent( w );
X    if (XtIsConstraint( w ))
X    {
X	XtGetConstraintResourceList( w->core.widget_class, &res_list, &num );
X
X	for ( i = 0 ; i < num ; i++ )
X	{
X	    if (0 == strcmp( res_name, res_list[i].resource_name)
X	     || 0 == strcmp( res_name, res_list[i].resource_class) )
X            {
X                retstr = XtNewString(res_list[i].resource_type);
X                XtFree( res_list );
X                return retstr;
X            }
X	}
X    }
X
X    return NULL;
X}
X
X/*
X    -- Convert resource value from string to whatever the widget needs
X*******************************************************************************
X    Gets the XtResourceList from the widget, searches the list for
X    the resource name to determine the type required, then uses the
X    resource manager to convert from string to the required type.
X    Calls XtSetValue with converted type.
X
X    Note that if the widget does not have the specified resource
X    type, it is not set.  WcGetResourceType() checks for both
X    widget resources and constraint resources.
X
X    Note also that no converter-failed behavior is necessary,
X    because converters generally give their own error messages.
X*/
X
Xvoid WcSetValueFromString( w, res_name, res_val )
X    Widget w;		 /* MUST already be init'd */
X    char*  res_name;
X    char*  res_val;	/* NUL terminated, should NOT have whitespace */
X{
X    char*	res_type;	/* must be XtFree'd */
X
X    if ( res_type = WcGetResourceType( w, res_name ) )
X    {
X	/* This widget does know about this resource type */
X	WcSetValueFromStringAndType( w, res_name, res_val, res_type );
X    }
X    XtFree( res_type );
X}
X
Xvoid WcSetValueFromStringAndType( w, res_name, res_val, res_type )
X    Widget w;
X    char*  res_name;
X    char*  res_val;
X    char*  res_type;
X{
X    XrmValue    fr_val;
X    XrmValue    to_val;
X    Arg		arg[1];
X
X    fr_val.size = strlen(res_val) + 1;
X    fr_val.addr = (caddr_t)res_val;
X    to_val.size = 0;
X    to_val.addr = NULL;
X    XtConvert(
X            w,		/* the widget */
X            XtRString,	/* from type */
X            &fr_val,	/* from value */
X            res_type,	/* to type */
X            &to_val		/* the converted value */
X    );
X
X    if (to_val.addr)
X    {
X        /* Conversion worked.  */
X	if ( 0 == strcmp(res_type, "String"))
X	    XtSetArg( arg[0], res_name, to_val.addr );
X	else
X	{
X	    switch(to_val.size)
X            {
X            case sizeof(char):
X                XtSetArg( arg[0], res_name, *(char*)to_val.addr );
X                break;
X            case sizeof(short):
X                XtSetArg( arg[0], res_name, *(short*)to_val.addr );
X                break;
X            case sizeof(int):
X                XtSetArg( arg[0], res_name, *(int*)to_val.addr );
X                break;
X            default:
X	        XtSetArg( arg[0], res_name, to_val.addr );
X            }
X	}
X        XtSetValues( w, arg, 1 );
X    }
X}
X
X/*
X*******************************************************************************
X* Private Data involving the root widget list, declared at top of this file
X*	static int numRoots = 0;
X*	static Widget rootWidgets[MAX_ROOT_WIDGETS];
X*******************************************************************************
X*/
X
X
X/*
X    -- Forget about a root widget
X*******************************************************************************
X    When a root widget gets destroyed, we need to take that widget out
X    of our list of root widgets.  This is a destroy callback routine
X    which is added to a root widget's destroy callback list by WcRootWidget.
X*/
X
Xstatic void ForgetRoot ( w, client, call )
X    Widget  w;
X    caddr_t client;
X    caddr_t call;
X{
X    int i;
X    for (i = 0 ; i < numRoots ; i++ )
X    {
X        if ( w == rootWidgets[i] )
X	{
X	    /* move all following widgets up to close the gap */
X	    for ( ; i < numRoots ; i++ )
X	    {
X		rootWidgets[i] = rootWidgets[i+1];
X	    }
X	    numRoots-- ;
X	    return;
X	}
X    }
X    /* should never get here */
X}
X
X/*
X    -- Find root widget
X*******************************************************************************
X    If a widget is passed, then find the root of that widget.  See if
X    it is one of the root widgets we already know about.  Add to list
X    if not.  Return the root widget.
X
X    If no widget is passed, then return the first root widget we know
X    about.  If we know of no root widgets, then we will return a NULL
X    since the rootWidgets[] array starts out filled with nulls, and
X    gets re-filled as roots are destroyed.
X*/
X
XWidget WcRootWidget( w )
X    Widget w;
X{
X    int i;
X
X    if (w)
X    {
X	while ( XtParent(w) )
X	    w = XtParent(w);
X
X	for (i = 0 ; i < numRoots ; i++)
X	{
X	    if ( w == rootWidgets[i] )
X		return w;
X	}
X
X	rootWidgets[i] = w;
X	numRoots++;
X	XtAddCallback( w, XtNdestroyCallback, ForgetRoot, NULL );
X	return w;
X    }
X    else
X    {
X	return rootWidgets[0];
X    }
X}
X
X/*
X   -- Equivalent to ANSI C library function strstr()
X*******************************************************************************
X   This function is only necessary on systems which do not have
X   ANSI C libraries.  Soon, it looks like everybody will have
X   such libraries, what with the recent SVR4 and OSF efforts
X   to include everything for everybody.  In the meantime,
X   this will always be included in the library.  Why not put
X   #ifdef's around it?  because the problem really arises not
X   when the library is built, but when applications are built.
X   I can't very well require all application writers in the
X   world to know what this library uses...
X*/
X
Xchar* WcStrStr( s1, s2 )
X    char* s1;
X    char* s2;
X{
X    while (*s1)
X    {
X	if (*s1 == *s2)
X	{
X	    char* start = s1;
X	    char* c = s2;
X	    while (*++s1 & *++c && *s1 == *c)
X		;
X	    if (*c == '\0')
X		return start;
X	    else
X		s1 = ++start;
X	}
X	else
X	{
X	    s1++ ;
X	}
X    }
X    return (char*)0;
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david       31942 Oct 15 10:15 WcName.c    (as sent)'
chmod u=rw,g=r,o=r WcName.c
ls -l WcName.c
exit 0

dan
----------------------------------------------------
O'Reilly && Associates   argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.
--
dan
----------------------------------------------------
O'Reilly && Associates   argv at sun.com / argv at ora.com
Opinions expressed reflect those of the author only.



More information about the Comp.sources.x mailing list