v08i035: wcl - Widget Creation Library, Part05/06

David E. Smyth david at devvax.Jpl.Nasa.Gov
Fri Jul 6 17:41:00 AEST 1990


Submitted-by: david at devvax.Jpl.Nasa.Gov (David E. Smyth)
Posting-number: Volume 8, Issue 35
Archive-name: wcl/part05

# to unbundle, "sh" this file -- DO NOT use csh
#  SHAR archive format.  Archive created Tue Jul 3 16:49:35 PDT 1990
echo x - WcCreateFunc.c
sed 's/^X//' > WcCreateFunc.c <<'+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: @(#)WcCreateFunc.c 1.0 ( 19 June 1990 )
X*
X* Subsystem_group:
X*
X*     Widget Creation Library
X*
X* Module_description:
X*
X*     This module contains the functions used to create and manage 
X*     a widget tree using the Xrm database.
X
X*     The Xrm database format used to prescribe widget's children
X*     is as follows:
X*
X*     ...parent.wcChildren:         childName1, childName2, ...
X*
X*     The type of each child must be specified.  There are three
X*     ways of doing this: (1) by widget class (class pointer name),
X*     (2) by widget class name, and (3) by widget constructor 
X*     function name.  The resource value given is case insensitive,
X*     although one is encouraged to use the capitalization given
X*     in the reference manuals simply on stylistic grounds.  The 
X*     three examples below are effectively equivalent:
X*
X*     ...drawing.wcClass:	xmDrawingAreaWidgetClass
X*     ...drawing.wcClassName:	XmDrawingArea
X*     ...drawing.wcConstructor: XmCreateDrawingArea
X*
X*     Since there are multiple ways of specifying the widget type,
X*     a precedence is defined: wcClass is the highest precedence,
X*     and wcClass > wcClassName > wcConstructor.
X*
X*     Currently, the Motif widget set defines many constructors, such 
X*     as XmCreateForm or XmCreateFileSelectionBox.  Constructors are 
X*     somtimes called Convenience Functions or even Confusion Functions.  
X*     It is highly recommended that you use the WcTrace resource when
X*     first using Constructors in order to see the resulting widget
X*     heirarchy more clearly.  The WcTrace resource is specified as:
X*
X*     ...drawing.wcTrace:	True
X*
X*     By default, all widgets created from the Xrm resource database
X*     are managed.  In some cases, this is not what is desired: for
X*     example, pop-up menus are generally not managed when they are
X*     created, rather they are managed due to some mouse event.  In
X*     such cases, the WcManaged resource should be set False, as below:
X*
X*     *fileMenu.wcManaged:	False
X*
X*     It is possible to bind one or more callback functions to the
X*     creation of a widget by using the WcCallback resource.  For 
X*     example, using the Motif widget set, when a menu bar is created 
X*     as a child of an XmMainWindow, the menuBar resource of the 
X*     XmMainWindow needs to be set to refer to the menu bar.  For 
X*     example:
X*
X*     App.main.wcClassName:	XmMainWindow
X*     App.main.wcChildren:	mbar
X*     *mbar.wcConstructor:	XmCreateMenuBar
X*     *mbar.wcCallback:		WcSetResourceCB( *main.menuBar: this)
X*
X*     Sometimes widget heirarchies are dynamic: many of the widgets
X*     are created at initialization time, but others need to be created
X*     at run time.  The WcDeferred resource allows widget heirarchies to
X*     be created after the initial widget tree - their creation is
X*     deferred.  Only the root of a deferred heirarchy has its
X*     WcDeferred resource set True.  For example, let's say your interface
X*     includes a box world, where the user can create an arbitrary number
X*     of various types of boxes:
X*
X*     *box_world.wcClass:	MyBoxWorldWidgetClass
X*     *box_world.wcChildren:	box_type1, box_type2, box_type3
X*     *box_type1.wcClass:	MyBoxType1WidgetClass
X*     *box_type1.WcDeferred:	True
X*     *box_type2.wcClass:	MyBoxType2WidgetClass
X*     *box_type2.WcDeferred:	True
X*     *box_type3.wcClass:	MyBoxType3WidgetClass
X*     *box_type3.wcClass:	True
X*     *box_type3.wcChildren:	child1, child2, child3, child4
X*     *button1.callback:	WcCreateCB( *box_type1 )
X*     *button2.callback:	WcCreateCB( *box_type2 )
X*     *button3.callback:	WcCreateCB( *box_type3 )
X*
X*     Initially, when box_world is created, it will have no children.
X*     Each time button1 is pressed, another instance of box_type1 will
X*     be created as a child of box_world, and managed (since wcManaged
X*     is by default True).  Similarly, everytime button2 is pressed
X*     another box_type2 will be created, and everytime button3 is
X*     pressed another box_type3 will be created, along with children
X*     named child1, child2, child3, and child4, and their children as 
X*     applicable.
X
X*     The following is the complete set of resources which are 
X*     interpreted by the Widget Creation Library:
X*
X*     ...widget.wcChildren:	childName1, childName2, ...
X*     ...widget.wcClass:	classPointerName
X*     ...widget.wcClassName:	className
X*     ...widget.wcConstructor:  constructorFunctionName
X*     ...widget.wcTrace:	true/false (default = false)
X*     ...widget.wcManaged:	true/false (default = true)
X*     ...widget.wcCallback:	callback1(args), callback2(args), ...
X*     ...widget.wcDeferred:	true/false (default = false)
X*
X*     In all cases, the Widget Creation resource names can be
X*     specified as Wc<name> or wc<name>, with the capitalized
X*     form having looser binding (representing the resource class).
X
X*     Example:
X*
X*		HelloWorld.wcChildren:  push
X*
X*		*push.wcClass:          xmPushButtonWidgetClass
X*		*push.labelString:      Hello World
X*		*push.activateCallback: WcExitCB(1)
X
X*     Since (for portability reasons) we can not assume runtime binding,
X*     all widget classes or creation routines (constructors) must be 
X*     "registered"  by the application BEFORE widget tree creation.
X*
X*     The widget tree creation is performed by the WcCreateDatabaseChild()
X*     function, which descends the widget tree recursively until no more
X*     children are found, or a "wcDeferred" resource is TRUE, or a 
X*     non-composite widget/object is found.
X*
X*     Several convenience callbacks are provided with the package, allowing 
X*     deferred widget creation, control (manage/unmanage) and other utility
X*     functions.  These are found in WcCallbacks.c
X*
X* Module_history:
X                                                  
X*   mm/dd/yy  initials  function  action
X*   --------  --------  --------  ---------------------------------------------
X*   30Jun90   R.Whitby	WcWidgetCreation added call to WcRegisterWcActions
X*   19Jun90   D.Smyth	Version 1.0
X*   04/18/90  MarBru    many..    Changed w->core.name to XrmQuarkToString...
X*   03/27/90  MarBru    Creation  Converted to a completely new syntax
X*   02/16/90  MarBru    Create..  Limited creation to composite widgets/objects
X*
X* Design_notes:
X*
X*******************************************************************************
X*/
X/*
X*******************************************************************************
X* Include_files.
X*******************************************************************************
X*/
X
X/*  -- Operating system includes */
X#include <stdio.h>
X
X/*  -- X Window System includes */
X#include <X11/StringDefs.h>
X
X/*  -- Widget Creation Includes */
X#include "WidgetCreate.h"
X#include "WidgetCreateP.h"
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X*/
X
Xstatic char     msg[MAX_ERRMSG];
X
X/*  -- Creation resources 
X	NOTE: The WcClass and WcClassName resources are both converted to
X        a class pointer, as we can construct useful error messages using:
X		class->core_class.class_name
X	However, the Constructor must be the entire constructor cache
X	record so we have the name of the constructor for the error
X	messages.
X	NOTE: WcClass and WcClassName write to different ResourceRec
X	members, so we can provide better error messages.
X*/
X
XXtResource wc_resources[] =
X  {
X    { WcNwcChildren,	WcCWcChildren,		XtRString,	sizeof(String),
X      XtOffset(ResourceRecPtr, children ),	XtRImmediate,	(caddr_t) NULL
X    },
X    { WcNwcClass,	WcCWcClass,		WcRClassPtr,	sizeof(caddr_t),
X      XtOffset(ResourceRecPtr, class ),		XtRImmediate,	(caddr_t) NULL
X    },
X    { WcNwcClassName,	WcCWcClassName,		WcRClassName,	sizeof(caddr_t),
X      XtOffset(ResourceRecPtr, classFromName ),	XtRImmediate,	(caddr_t) NULL
X    },
X    { WcNwcConstructor,	WcCWcConstructor, 	WcRConstructor,	sizeof(caddr_t),
X      XtOffset(ResourceRecPtr, constructor ),	XtRImmediate,	(caddr_t) NULL
X    },
X    { WcNwcManaged,	WcCWcManaged,		XtRBoolean,	sizeof(Boolean),
X      XtOffset(ResourceRecPtr, managed),	XtRImmediate,	(caddr_t) TRUE
X    },
X    { WcNwcDeferred,	WcCWcDeferred,		XtRBoolean,	sizeof(Boolean),
X      XtOffset(ResourceRecPtr, deferred),	XtRImmediate,	(caddr_t) FALSE
X    },
X    { WcNwcTrace,	WcCWcTrace,		XtRBoolean,	sizeof(Boolean),
X      XtOffset(ResourceRecPtr, trace),		XtRImmediate,	(caddr_t) FALSE
X    },
X    { WcNwcCallback,	WcCWcCallback,	XtRCallback,	sizeof(XtCallbackList),
X      XtOffset(ResourceRecPtr, callback ),	XtRImmediate,	(caddr_t) NULL
X    }
X  };
X
X/*
X*******************************************************************************
X* Private_function_declarations.
X*******************************************************************************
X*/
X
X/*
X    -- Create Database Child
X*******************************************************************************
X    This function checks the resource database for creation resources
X    of the named widget. If found, the child is created using the specified
X    class, and the creation callbacks are called.
X
X    Unless the force flag is TRUE, this function will NOT create widgets
X    whose  WcDeferred resource is TRUE.  The force flag is only true on
X    the initial widget when a tree of widgets is being created.
X*/
X
Xstatic Widget WcCreateDatabaseChild ( pw, name, force, managed  )
X    Widget      pw;         /* child's parent */
X    char*       name;       /* child name to create */
X    int         force;      /* T/F: force creation of deferred widget? */
X    int        *managed;    /* returned T/F: this child to be managed ? */
X{
X    char*	parentName;		   /* for err msgs, must be XtFree'd */
X    ResourceRec res;			   /* child's creation resources */
X    Widget	child;			   /* what we create */
X
X    /* Cobble together the child name from the parent's full path name
X    ** and the child's name.
X    */
X    parentName = WcWidgetToFullName( pw );
X
X    /* Get creation resources for the child to be created.
X    ** After this XtGetSubresources() call, the resource structure `res'
X    ** contains resources specified in the Xrm database or the defaults.
X    */
X    XtGetSubresources ( pw, &res, name, name, 
X       wc_resources, XtNumber(wc_resources), NULL, 0 );
X
X    /*  Don't create widgets with WcDeferred resource unless forced */
X    if ( res.deferred && !force )
X    {
X	child = (Widget)NULL;
X    }
X
X    else if ( !res.class && !res.classFromName && !res.constructor )
X    {
X        sprintf( msg,
X            "WcCreateDatabaseChild (%s.%s) - Failed \n\
X             Problem: No %s, %s, nor %s specified,  \n\
X                      Child `%s' could not be created.",
X             parentName, name, 
X	     WcCWcClass, WcCWcClassName, WcCWcConstructor,
X	     name );
X        XtWarning( msg );
X	child = (Widget)NULL;
X    }
X
X    else if ( res.class || res.classFromName )
X    {
X	if ( res.class && res.classFromName && res.constructor )
X	{
X	    sprintf( msg,
X            "WcCreateDatabaseChild (%s.%s) \n\
X             Problem: %s, %s, and %s resources specified, \n\
X		      `%s.%s: %s' and \n\
X		      `%s.%s: %s' ignored.",
X             parentName, name, 
X	     WcCWcClass, WcCWcClassName, WcCWcConstructor,
X	     name, WcCWcClassName, res.classFromName->core_class.class_name,
X	     name, WcCWcConstructor, res.constructor->name );
X            XtWarning( msg );
X	}
X	else if ( res.class && res.classFromName )
X	{
X            sprintf( msg,
X            "WcCreateDatabaseChild (%s.%s) \n\
X             Problem: %s and %s resources specified, \n\
X                      `%s.%s: %s' ignored.",
X             parentName, name,
X             WcCWcClass, WcCWcClassName, 
X             name, WcCWcClassName, res.classFromName->core_class.class_name);
X            XtWarning( msg );
X        }
X        else if ( res.class && res.constructor )
X        {
X            sprintf( msg,
X            "WcCreateDatabaseChild (%s.%s) \n\
X             Problem: %s and %s resources specified, \n\
X                      `%s.%s: %s' ignored.",
X             parentName, name,
X             WcCWcClass, WcCWcConstructor,
X             name, WcCWcConstructor, res.constructor->name );
X            XtWarning( msg );
X        }
X        else if ( res.classFromName && res.constructor )
X        {
X            sprintf( msg,
X            "WcCreateDatabaseChild (%s.%s) \n\
X             Problem: %s and %s resources specified, \n\
X                      `%s.%s: %s' ignored.",
X             parentName, name,
X             WcCWcClassName, WcCWcConstructor,
X             name, WcCWcConstructor, res.constructor->name );
X            XtWarning( msg );
X        }
X
X	if ( res.class )
X	    child = XtCreateWidget ( name, res.class, pw, NULL, 0 );
X	else
X	    child = XtCreateWidget ( name, res.classFromName, pw, NULL, 0 );
X
X	if ( !child )
X	{
X            sprintf( msg,
X            "WcCreateDatabaseChild (%s.%s) - Failed \n\
X             Problem: XtCreateWidget ( %s, %s ) failed.",
X             parentName, name, name, res.class->core_class.class_name );
X            XtWarning( msg );
X	}
X    }
X
X    else if ( res.constructor )
X    {
X	child = res.constructor->constructor( pw, name, NULL, 0 );
X
X	if ( !child )
X        {
X            sprintf( msg,
X            "WcCreateDatabaseChild (%s.%s) - Failed \n\
X             Problem: %s ( %s ) failed.",
X             parentName, name, res.constructor->name, name );
X            XtWarning( msg );
X        }
X    }
X
X    if ( child )
X    {
X	/* A child widget was created.
X	** print out creation trace, if required 
X	*/
X	if ( res.trace )
X	{
X	    char* name = WcWidgetToFullName( child );
X	    fprintf(stderr,"Wc %s: %s of class %s\n",
X		((res.managed) ? "  managed" : "unmanaged"), name, 
X		child->core.widget_class->core_class.class_name);
X	    XtFree(name);
X	}
X
X	/* call creation callbacks */
X	if ( res.callback )
X	{
X	    XtCallbackRec *cb = res.callback;
X	    for ( ; cb->callback; cb++ )
X		(*cb->callback)( child, cb->closure, NULL );
X	}
X
X	if ( res.children )
X	{
X	    if  ( XtIsSubclass( child, compositeWidgetClass ) )
X	    {
X		/* child is a manager widget, create its children */
X	        WcCreateNamedChildren ( child, res.children );		
X	    }
X	    else
X	    {
X                sprintf( msg,
X            "WcCreateDatabaseChild (%s.%s) - children ignored \n\
X             Problem: %s is not a composite, cannot have children.",
X             parentName, name, name );
X                XtWarning( msg );
X	    }
X	}
X    }
X
X    XtFree( parentName );
X    *managed = res.managed;
X    return (child);
X}
X
X/*
X    -- Create And Manage Named Children from Xrm Database
X*******************************************************************************
X    This function creates widget's children specified by names list,
X    by calling WcCreateDatabaseChild() for each of the names provided.
X
X    All the children are then managed, unless WcManaged resource is FALSE.
X
X    The force flag is passed to WcCreateDatabaseChild() and is used to
X    indicate that children are to be created even if their WcDeferred
X    resource is TRUE. 
X*/
X
Xstatic void WcCreateAndManageChildren ( pw, names, force )
X    Widget      pw;         /* children's parent                            */
X    char*       names;      /* (list of) widget names to create             */
X    int		force;	    /* force creation of deferred widgets	    */
X{
X    Widget	child;
X    int		widget_count = 0;
X    Widget	widget_list[MAX_CHILDREN];
X    char	cleanName[MAX_XRMSTRING];
X    char*	next;
X    int		managed;
X
X    if  ( !names ) return;
X
X    next = WcCleanName( names, cleanName );
X
X    while ( cleanName[0] )
X    {
X	child = WcCreateDatabaseChild ( pw, cleanName, force, &managed );
X	if ( child && managed )
X	    widget_list[widget_count++] = child;
X	next = WcSkipWhitespace_Comma( next );
X	next = WcCleanName( next, cleanName );
X    }
X
X    if ( widget_count ) 
X	XtManageChildren( widget_list, widget_count );
X}
X
X/*
X*******************************************************************************
X* Public_function_declarations.
X*******************************************************************************
X*/
X
X/*
X    -- Create Widget Tree from Xrm Database
X*******************************************************************************
X    This routine creates widget children as defined in Xrm database.
X    It checks the widget resource "WcChildren", which is a list of
X    names of children to create. Each child must then be further defined
X    in the databse.
X
X    This function is frequently called from an application's main()
X    procedure after the application shell is created via XtInitialize().
X
X    Note that this function registers the converters for StringToWidget,
X    StringToCallback, and so forth.
X*/
X
Xvoid WcWidgetCreation ( root )
X    Widget       root;
X{
X    XtAppContext app = XtWidgetToApplicationContext( root );
X    char*	 fullName = WcWidgetToFullName( root );	/* must be XtFree'd */
X    ResourceRec  res;
X
X    /* register the root of this widget */
X    (void)WcRootWidget(root);
X
X    /* register the Wc converters */
X    WcAddConverters( app );
X
X    /* register the Wc callbacks */
X    WcRegisterWcCallbacks ( app );
X
X    /* register the Wc actions */
X    WcRegisterWcActions ( app );
X
X    if ( XtIsSubclass( root, compositeWidgetClass ) )
X    {
X        XtGetApplicationResources ( root, &res,
X              wc_resources, XtNumber(wc_resources), NULL, 0 );
X    
X        if ( res.children )
X           WcCreateNamedChildren ( root, res.children );
X        else
X        {
X            sprintf( msg,
X            "WcWidgetCreation (%s) - Failed \n\
X             Problem: No children defined in Xrm database.",
X             fullName );
X            XtWarning( msg );
X	}
X    }
X
X     else
X    {
X        sprintf( msg,
X            "WcWidgetCreation (%s) - Failed \n\
X             Problem: %s is not a composite widget, cannot have children.",
X             fullName );
X        XtWarning( msg );
X    }
X
X    XtFree ( fullName );
X}
X
X/*
X    -- Create Named Children from Xrm Database
X*******************************************************************************
X    These functions create widget's children specified by names list, using
X    information contained in X resource database. After creation, children
X    are managed (unless WcManaged resource is FALSE).
X
X    Children whose WcDeferred resource is True are NOT created by
X    WcCreateNamedChildren().  They are only created with an explicit call 
X    to WcCreateDeferredChildren().
X*/
X
Xvoid WcCreateDeferredChildren ( pw, names )
X    Widget      pw;         /* children's parent                            */
X    char*       names;      /* (list of) widget names to create             */
X{
X    WcCreateAndManageChildren ( pw, names, TRUE ); /* create even if deferred */
X}
X
Xvoid WcCreateNamedChildren ( pw, names )
X    Widget      pw;         /* children's parent                            */
X    char*       names;      /* (list of) widget names to create             */
X{
X    WcCreateAndManageChildren ( pw, names, FALSE ); /* don't create deferred */
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david       21152 Jul  3 10:26 WcCreateFunc.c    (as sent)'
chmod u=rw,g=r,o=r WcCreateFunc.c
ls -l WcCreateFunc.c
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 <Xm/X11/ShellP.h>
X#include <Xm/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        2054 Jun 28 09:13 WcMotifP.h    (as sent)'
chmod u=rw,g=r,o=r WcMotifP.h
ls -l WcMotifP.h
echo x - WcNameFuncs.c
sed 's/^X//' > WcNameFuncs.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: @(#)WcNameFuncs.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** 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 "WidgetCreate.h"
X#include "WidgetCreateP.h"
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X*/
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/*
X*******************************************************************************
X* Private_function definitions.
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 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#include "Xtos.h"
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;
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#ifdef MOTIF
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
XWidget WcFullNameToWidget( w, name )
X    Widget w;
X    char*  name;
X{
X    Widget retWidget;
X    char  *widgetName;	/* name stripped of whitespace at both ends */
X    char  *lowerName;
X    Widget root;
X    char  *rootName;
X    char  *lowerRootName;
X    int    rootNameLen;
X    int    startsWithRootName;
X
X    widgetName = WcStripWhitespaceFromBothEnds( name );	/* must be XtFree'd */
X    lowerName  = WcLowerCaseCopy( widgetName );		/* must be XtFree'd */
X
X    root = WcRootWidget( w );
X    rootName = XrmQuarkToString( root->core.xrm_name );
X    lowerRootName = WcLowerCaseCopy( rootName );	/* must be XtFree'd */
X    rootNameLen = strlen( lowerRootName );
X    startsWithRootName = !strncmp( lowerName, lowerRootName, rootNameLen );
X
X    if ( startsWithRootName && widgetName[rootNameLen] == '*' )
X    {
X	/* the first component of the widget name is the application shell
X	** name, and it is followed by a `*' so strip the root name,
X	** but keep the star as it implies loose binding.
X	*/
X	retWidget = WcChildNameToWidget( root, &(widgetName[rootNameLen]) );
X    }
X
X    else if ( startsWithRootName && widgetName[rootNameLen] == '.' )
X    {
X	/* the first component of the widget name is the application shell
X	** name, and it is followed by a `.' so strip the root name,
X	** and strip the period to imply tight binding.
X	*/
X	retWidget = WcChildNameToWidget( root, &(widgetName[++rootNameLen]) );
X    }
X
X    else if ( widgetName[0] == '*' )
X    {
X	retWidget = WcChildNameToWidget( root, widgetName );
X    }
X
X    else if ( 0 == strcmp( "this", lowerName ) )
X    {
X	retWidget = w;
X    }
X
X    else
X    {
X#ifdef DEBUG
X	sprintf( msg, 
X	    "WcFullNameToWidget cannot convert `%s' to widget \n\
X	     Problem: Widget name must start with `*' or `%s' or be `this'",
X	     widgetName, rootName );
X	XtWarning( msg ); 
X#endif
X	retWidget = (Widget)NULL;
X    }
X
X    XtFree( widgetName );
X    XtFree( lowerName );
X    XtFree( lowerRootName );
X    return retWidget;
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    Cardinal   *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#ifdef MOTIF
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#ifdef MOTIF
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* cp;
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    -- 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
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, but may have whitespace */
X{
X    XtResource* res_list;
X    int         i, num;
X    char*       ret_val;
X    char*       ta;
X    XrmValue    fr_val;
X    XrmValue    to_val;
X    Arg         arg[1];
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            break;
X        else if (0 == strcmp( res_name, res_list[i].resource_class))
X            break;
X    }
X    if ( i == num )
X    {
X        if (w->core.parent)
X            sprintf(msg,"%s is not a resource of %s.%s",
X                    res_name, w->core.parent->core.name, w->core.name );
X        else
X            sprintf(msg,"%s is not a resource of %s",
X                    res_name, w->core.name );
X        XtWarning(msg);
X        return;
X    }
X    else
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_list[i].resource_type,      /* to type */
X                &to_val                         /* the converted value */
X        );
X
X        if (to_val.addr)
X        {
X            /* Conversion worked.  */
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                sprintf(msg,
X                        "Bizarre Resource Size in SetValueFromString: %d",
X                        to_val.size);
X                XtWarning(msg);
X                return;
X            }
X            XtSetValues( w, arg, 1 );
X            return;
X        }
X        else
X        {
X            /* conversion failed - assume converter called XtWarning */
X            return;
X        }
X    }
X}
X
X
X/*
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    -- 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	    for ( ; i < numRoots ; i++ )
X	    {
X	    }
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}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david       21635 Jul  3 10:24 WcNameFuncs.c    (as sent)'
chmod u=rw,g=r,o=r WcNameFuncs.c
ls -l WcNameFuncs.c
echo x - WcRegIntrinsic.c
sed 's/^X//' > WcRegIntrinsic.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: @(#)WcRegIntrinsic.c 1.0 ( 19 June 1990 )
X*
X* Subsystem_group:
X*
X*     Widget Creation Library - Intrinsic Resource Interpreter
X*
X* Module_description:
X*
X*     This module contains registration routine for all Intrinsic
X*     widget constructors and classes.  
X*
X* Module_interface_summary: 
X*
X*     void WcRegisterIntrinsic ( XtAppContext app )
X*
X* Module_history:
X*                                                  
X*   mm/dd/yy  initials  function  action
X*   --------  --------  --------  ---------------------------------------------
X*   06/19/90  D.Smyth   all	  create.
X*
X* Design_notes:
X*
X*******************************************************************************
X*/
X/*
X*******************************************************************************
X* Include_files.
X*******************************************************************************
X*/
X
X#include <X11/Intrinsic.h>
X
X#include <X11/Object.h>
X#include <X11/RectObj.h>
X#include <X11/Shell.h>
X#include <X11/Vendor.h>
X
X/* -- Widget constructor routines */
X
XWidget WcCreateApplicationShell	();
XWidget WcCreateOverrideShell	();
XWidget WcCreateShell		();
XWidget WcCreateTopLevelShell	();
XWidget WcCreateTransientShell	();
XWidget WcCreateVendorShell	();
XWidget WcCreateWMShell		();
X
X
Xvoid WcRegisterIntrinsic ( app )
X    XtAppContext app;
X{
X
X#define RCN( name, class ) WcRegisterClassName ( app, name, class );
X#define RCP( name, class ) WcRegisterClassPtr  ( app, name, class );
X#define RCR( name, func )  WcRegisterConstructor(app, name, func  );
X
X    /* -- register all Intrinsic widget classes */
X
X    RCN("Object",			objectClass );
X    RCP("objectClass",			objectClass );
X    RCN("RectObj",			rectObjClass );
X    RCP("rectObjClass",			rectObjClass );
X    RCN("Core",				coreWidgetClass );
X    RCP("coreWidgetClass",		coreWidgetClass );
X    RCN("Composite",			compositeWidgetClass );
X    RCP("compositeWidgetClass",		compositeWidgetClass );
X    RCN("Constraint",			constraintWidgetClass );
X    RCP("constraintWidgetClass",	constraintWidgetClass );
X    RCN("ApplicationShell",		applicationShellWidgetClass );
X    RCP("applicationShellWidgetClass",	applicationShellWidgetClass );
X    RCN("OverrideShell",		overrideShellWidgetClass );
X    RCP("overrideShellWidgetClass",	overrideShellWidgetClass );
X    RCN("Shell",			shellWidgetClass );
X    RCP("shellWidgetClass",		shellWidgetClass );
X    RCN("TopLevelShell",		topLevelShellWidgetClass );
X    RCP("topLevelShellWidgetClass",	topLevelShellWidgetClass );
X    RCN("TransientShell",		transientShellWidgetClass );
X    RCP("transientShellWidgetClass",	transientShellWidgetClass );
X    RCN("VendorShell",			vendorShellWidgetClass );
X    RCP("vendorShellWidgetClass",	vendorShellWidgetClass );
X    RCN("WmShell",			wmShellWidgetClass );
X    RCP("wmShellWidgetClass",		wmShellWidgetClass );
X
X    /* -- register all Intrinsic constructors */
X
X    RCR("XtCreateApplicationShell",	WcCreateApplicationShell);
X    RCR("XtCreateOverrideShell",	WcCreateOverrideShell);
X    RCR("XtCreateShell",		WcCreateShell);
X    RCR("XtCreateTopLevelShell",	WcCreateTopLevelShell);
X    RCR("XtCreateTransientShell",	WcCreateTransientShell);
X    RCR("XtCreateWMShell",		WcCreateWMShell);
X    RCR("XtCreateVendorShell",		WcCreateVendorShell);
X
X#undef RCN
X#undef RCP
X#undef RCR
X}
X
X/*
X    -- Create Application Shell
X*******************************************************************************
X    This function creates an application shell widget.
X    
X*/
XWidget WcCreateApplicationShell ( pw, name, args, nargs )
XWidget	    pw;		/* children's parent 				*/
XString      name;	/* widget name to create 			*/
XArg        *args;	/* args for widget				*/
XCardinal    nargs;	/* args count					*/
X{
X
X  XtCreatePopupShell(name, applicationShellWidgetClass, pw, args, nargs);
X  return;
X}
X
X/*
X    -- Create Override Shell
X*******************************************************************************
X    This function creates an override shell widget.
X    
X*/
XWidget WcCreateOverrideShell ( pw, name, args, nargs )
XWidget	    pw;		/* children's parent 				*/
XString      name;	/* widget name to create 			*/
XArg        *args;	/* args for widget				*/
XCardinal    nargs;	/* args count					*/
X{
X
X  return(XtCreatePopupShell(name, overrideShellWidgetClass, pw, args, nargs));
X}
X
X/*
X    -- Create Shell
X*******************************************************************************
X    This function creates a shell widget.
X    
X*/
XWidget WcCreateShell ( pw, name, args, nargs )
XWidget	    pw;		/* children's parent 				*/
XString      name;	/* widget name to create 			*/
XArg        *args;	/* args for widget				*/
XCardinal    nargs;	/* args count					*/
X{
X
X  return(XtCreatePopupShell(name, shellWidgetClass, pw, args, nargs));
X}
X
X/*
X    -- Create TopLevel Shell
X*******************************************************************************
X    This function creates a top level shell widget.
X    
X*/
XWidget WcCreateTopLevelShell ( pw, name, args, nargs )
XWidget	    pw;		/* children's parent 				*/
XString      name;	/* widget name to create 			*/
XArg        *args;	/* args for widget				*/
XCardinal    nargs;	/* args count					*/
X{
X
X  return(XtCreatePopupShell(name, topLevelShellWidgetClass, pw, args, nargs));
X}
X
X/*
X    -- Create Transient Shell
X*******************************************************************************
X    This function creates an transient shell widget.
X    
X*/
XWidget WcCreateTransientShell ( pw, name, args, nargs )
XWidget	    pw;		/* children's parent 				*/
XString      name;	/* widget name to create 			*/
XArg        *args;	/* args for widget				*/
XCardinal    nargs;	/* args count					*/
X{
X
X  return(XtCreatePopupShell(name, transientShellWidgetClass, pw, args, nargs));
X}
X
X/*
X    -- Create Vendor Shell
X*******************************************************************************
X    This function creates a vendor shell widget.
X    
X*/
XWidget WcCreateVendorShell ( pw, name, args, nargs )
XWidget	    pw;		/* children's parent 				*/
XString      name;	/* widget name to create 			*/
XArg        *args;	/* args for widget				*/
XCardinal    nargs;	/* args count					*/
X{
X
X  return(XtCreatePopupShell(name, vendorShellWidgetClass, pw, args, nargs));
X}
X
X/*
X    -- Create WM Shell
X*******************************************************************************
X    This function creates an WM shell widget.
X    
X*/
XWidget WcCreateWMShell ( pw, name, args, nargs )
XWidget	    pw;		/* children's parent 				*/
XString      name;	/* widget name to create 			*/
XArg        *args;	/* args for widget				*/
XCardinal    nargs;	/* args count					*/
X{
X
X  return(XtCreatePopupShell(name, wmShellWidgetClass, pw, args, nargs));
X}
X
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        7396 Jul  2 12:22 WcRegIntrinsic.c    (as sent)'
chmod u=rw,g=r,o=r WcRegIntrinsic.c
ls -l WcRegIntrinsic.c
echo x - WcRegister.c
sed 's/^X//' > WcRegister.c <<'+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: @(#)WcRegister.c 1.0 ( 19 June 1990 )
X*
X* Subsystem_group:
X*
X*     Widget Creation Library
X*
X* Module_description:
X*
X*     Since (for portability reasons) we can not assume runtime binding,
X*     all widget classes, creation routines (constructors), and callbacks
X*     must be "registered"  by the application BEFORE widget tree creation.
X*
X*     All four of the functions defined in this module load dynamically
X*     allocated and extended arrays of structures.  The size increment
X*     of the arrays starts at a reasonably small size (INCR_REGISTRY,
X*     initially 32), and is doubled in size everytime a given registry is
X*     filled.  This allows registries to be small, yet to not have to be
X*     realloc'd frequently when they grow large.  
X*
X*     The registries are arrays of structs.  In all four cases, the
X*     structs are very similar: they contain a name string which holds the
X*     class, constructor, or callback name as it was registered; a quark
X*     which is based on an all lower case representation of the name, and
X*     class, constructor, or callback specific information.  The name
X*     as registered should be as shown in reference documents and source
X*     code, as it is used for user error messages.
X*
X*     The registries are intended to be used by string-to-whatever converters.
X*
X*     All four registration functions currently check for duplicate
X*     entries, but do no fancy hashing scheme, nor any ties to the
X*     application context.  Assumming a relatively small number of
X*     entries in these regestries, it is assumed that a sequential
X*     search using quarks will be adequate and simple.
X
X* Module_interface_summary: 
X*
X*       WcRegisterClassPtr(
X*	    XtAppContext  app,	    - application context
X*	    String	  name,	    - class ptr name, as in ref manuals
X*	    WidgetClass   class )   - class record pointer
X*
X*       WcRegisterClassName(
X*	    XtAppContext  app,	    - application context
X*	    String	  name,	    - class name, as in ref manuals
X*	    WidgetClass   class )   - class record pointer
X*
X*       WcRegisterConstructor(
X*	    XtAppContext  app,	    - application context
X*	    String	  name,	    - constructor name, as in ref manuals
X*	    (*Widget)()   const )   - constructor function pointer
X*
X*	WcRegisterCallback(
X*	    XtAppContext  app,      - application context
X*           String        name,     - callback name, "nice" capitalization
X*	    void (*func)() )        - pointer to callback function
X*
X* Module_history:
X
X*   mm/dd/yy  initials  function  action
X*   --------  --------  --------  ---------------------------------------------
X*   19Jun90   D.Smyth   Version 1.0 Widget Creation Library
X*   06/08/90  D.Smyth   All Added "name" member for better user msgs.
X*   02/26/90  MarBru    All       Created
X*   02/16/90  MarBru    Create..  Limited creation to composite widgets/objects
X*
X* Design_notes:
X*
X*   For VMS, we could have used LIB$FIND_IMAGE_SYMBOL and use dynamic
X*   (runtime) binding. But since most UNIX systems lack such capability,
X*   we stick to the concept of "registration" routines.
X*
X*******************************************************************************
X*/
X/*
X*******************************************************************************
X* Include_files.
X*******************************************************************************
X*/
X
X/*  -- Widget Creation Includes */
X#include "WidgetCreate.h"
X#include "WidgetCreateP.h"
X
X/*
X*******************************************************************************
X* Private_data_definitions.
X*******************************************************************************
X    The following cache/registry of known widget classes, contructors, 
X    and callbacks are initially empty, and are loaded by the application 
X    using "registration" routines.
X*/
X
Xstatic char     msg[MAX_ERRMSG];
X
X/*  -- Named class pointer cache, intially empty */
X
Xint         classes_num = 0;
Xint         classes_max = 0;
XClCacheRec *classes_ptr = NULL;
X
X/*  -- Class name cache, intially empty */
X
Xint             cl_nm_num = 0;
Xint             cl_nm_max = 0;
XClNameCacheRec* cl_nm_ptr = NULL;
X
X/*  -- Named object constructor cache, intially empty */
X
Xint          constrs_num = 0;
Xint          constrs_max = 0;
XConCacheRec *constrs_ptr = NULL;
X
X/*  -- Named callback procedures cache, intially empty */
X
Xint         callbacks_num = 0;
Xint         callbacks_max = 0;
XCBCacheRec *callbacks_ptr = NULL;
X
X/*
X*******************************************************************************
X* Private_function_declarations.
X*******************************************************************************
X*/
X
X/*
X*******************************************************************************
X* Public_function_declarations.
X*******************************************************************************
X*/
X
X/*
X    -- Register Class Pointer Name
X*******************************************************************************
X    This procedure adds class pointer name to our list of registered
X    classes. Note that the class ptr name is effectively case insensitive
X    as it is being quarkified.  However, one should register the class ptr
X    names using the "standard" capitalization (whatever is in the reference
X    manual for the widget set) as the name as registered is used for error
X    messages.
X
X   The registry is primarily used by CvtStringToClassPtr().
X*/
X
Xvoid WcRegisterClassPtr ( app, name, class )
X    XtAppContext        app;    /* not used (yet), must be present      */
X    char*               name;   /* class ptr name, case insensitive     */
X    WidgetClass         class;  /* Xt object class pointer              */
X{
X    char          *lowerCaseName;
X    XrmQuark       quark;
X    ClCacheRec    *rec;
X    int            i;
X
X    /* Might need to grow cache.  Note that growth increment is exponential:
X    ** if lots of classes, don't need to keep realloc'ing so often.
X    */
X    if (classes_num >= classes_max )
X    {
X        classes_max += (classes_max ? classes_max : INCR_REGISTRY);
X        classes_ptr  = (ClCacheRec*) XtRealloc((char*)classes_ptr,
X                             sizeof(ClCacheRec) * classes_max);
X    }
X
X    /* See if this object has been registered.  Compare quarks.
X    */
X    lowerCaseName = WcLowerCaseCopy( name );
X    quark = XrmStringToQuark ( lowerCaseName );
X    XtFree ( lowerCaseName );
X
X    for (i = 0 ; i < classes_num ; i++ )
X    {
X        if (classes_ptr[i].quark == quark)
X        {
X            /* already registered this class */
X            sprintf(msg,
X            "WcRegisterClassPtr (%s) - Failed \n\
X             Problem: Duplicate class registration ignored.",
X             name );
X            XtWarning( msg );
X            return;
X        }
X    }
X
X    rec = &classes_ptr[classes_num++];          /* ClCacheRec to be filled */
X    rec->quark = quark;
X    rec->class = class;
X    rec->name  = XtMalloc( strlen(name) + 1 );
X    strcpy ( rec->name, name );
X}
X
X/*
X    -- Register Class Name
X*******************************************************************************
X    This procedure adds a class name to our list of registered
X    classes. Note that the class name is effectively case insensitive
X    as it is being quarkified.  However, one should register the class
X    names using the "standard" capitalization (whatever is in the reference
X    manual for the widget set) as the name as registered is used for error
X    messages.
X
X   The registry is primarily used by CvtStringToClassName().
X*/
X
Xvoid WcRegisterClassName ( app, name, class )
X    XtAppContext	app;	/* not used (yet), must be present      */
X    char*		name;	/* class name, case insensitive   	*/
X    WidgetClass		class;	/* Xt object class pointer              */
X{
X    char           *lowerCaseName;
X    XrmQuark	    quark;
X    ClNameCacheRec *rec;
X    int		    i;
X
X    /* Might need to grow cache.  Note that growth increment is exponential:
X    ** if lots of classes, don't need to keep realloc'ing so often.
X    */
X    if (cl_nm_num >= cl_nm_max )
X    {
X	cl_nm_max += (cl_nm_max ? cl_nm_max : INCR_REGISTRY);
X	cl_nm_ptr  = (ClNameCacheRec*) XtRealloc((char*)cl_nm_ptr, 
X                             sizeof(ClNameCacheRec) * cl_nm_max);
X    }
X
X    /* See if this object has been registered.  Compare quarks.
X    */
X    lowerCaseName = WcLowerCaseCopy( name );
X    quark = XrmStringToQuark ( lowerCaseName );
X    XtFree ( lowerCaseName );
X
X    for (i = 0 ; i < cl_nm_num ; i++ )
X    {
X	if (cl_nm_ptr[i].quark == quark)
X	{
X	    /* already registered this class */
X	    sprintf(msg, 
X            "WcRegisterClassName (%s) - Failed \n\
X             Problem: Duplicate class registration ignored.",
X             name );
X            XtWarning( msg );
X	    return;
X	}
X    }
X
X    rec = &cl_nm_ptr[cl_nm_num++];	/* ClNameCacheRec to be filled */
X    rec->quark = quark;
X    rec->class = class;
X    rec->name  = XtMalloc( strlen(name) + 1 );
X    strcpy ( rec->name, name );
X}
X
X/*
X    -- Register constructor
X*******************************************************************************
X    This procedure adds constructor procedure/name to our list of registered
X    constructors. Note that the name is effectively case insensitive
X    as it is being quarkified.  However, one should register the 
X    names using the "standard" capitalization (whatever is in the reference
X    manual for the widget set) as the name as registered is used for error
X    messages.
X
X    Note the constructor is a "Motif Style" widget creation routine,
X    commonly called a "confusion function."  
X
X   The registry is primarily used by CvtStringToConstructor().
X*/
X
Xvoid WcRegisterConstructor ( app, name, constructor )
X    XtAppContext app;	        /* not used (yet), must be present      */
X    char*        name;	        /* constructor name, case insensitive   */
X    Widget (*constructor) ();   /* pointer to a widget creation routine */
X{
X    char          *lowerCaseName;
X    XrmQuark       quark;
X    ConCacheRec   *rec;
X    int		   i;
X
X    /* Might need to grow cache.  Note that growth increment is exponential:
X    ** if lots of constructors, don't need to keep realloc'ing so often.
X    */
X    if (constrs_num >= constrs_max )
X    {
X        constrs_max += (constrs_max ? constrs_max : INCR_REGISTRY);
X        constrs_ptr  = (ConCacheRec*) XtRealloc((char*)constrs_ptr,
X                             sizeof(ConCacheRec) * constrs_max);
X    }
X
X    /* See if this object has been registered.  Compare quarks.
X    */
X    lowerCaseName = WcLowerCaseCopy( name );
X    quark = XrmStringToQuark ( lowerCaseName );
X    XtFree ( lowerCaseName );
X
X    for (i = 0 ; i < constrs_num ; i++ )
X    {
X        if (constrs_ptr[i].quark == quark)
X        {
X            /* already registered this class */
X            sprintf(msg,
X            "WcRegisterConstructor (%s) - Failed \n\
X             Problem: Duplicate constructor registration ignored.",
X             name );
X            XtWarning( msg );
X            return;
X        }
X    }
X
X    rec = &constrs_ptr[constrs_num++];		/* ClCacheRec to be filled */
X    rec->quark       = quark;
X    rec->constructor = constructor;
X    rec->name        = XtMalloc( strlen(name) + 1 );
X    strcpy ( rec->name, name );
X}
X
X/*
X  -- Register Callbacks
X*******************************************************************************
X    Register callback functions which can then be bound to widget
X    callback lists by the string-to-callback converter 
X    CvtStringToCallback().
X*/
X
Xvoid WcRegisterCallback ( app, name, callback, closure )
X    XtAppContext    app;        /* not used (yet), must be present      */
X    String          name;       /* callback name, case insensitive      */
X    XtCallbackProc  callback;   /* callback function pointer            */
X    caddr_t         closure;    /* default client data                  */
X{
X    char          *lowerCaseName;
X    XrmQuark       quark;
X    CBCacheRec    *rec;
X    int		   i;
X
X    /* Might need to grow cache.  Note that growth increment is exponential:
X    ** if lots of constructors, don't need to keep realloc'ing so often.
X    */
X    if (callbacks_num >= callbacks_max )
X    {
X        callbacks_max += (callbacks_max ? callbacks_max : INCR_REGISTRY);
X        callbacks_ptr  = (CBCacheRec*) XtRealloc((char*)callbacks_ptr,
X                             sizeof(CBCacheRec) * callbacks_max);
X    }
X
X    /* See if this callback has been registered.  Compare quarks.
X    */
X    lowerCaseName = WcLowerCaseCopy( name );
X    quark = XrmStringToQuark ( lowerCaseName );
X    XtFree ( lowerCaseName );
X
X    for (i = 0 ; i < callbacks_num ; i++ )
X    {
X        if (callbacks_ptr[i].quark == quark)
X        {
X            /* already registered this callback */
X            sprintf(msg,
X            "WcRegisterCallback (%s) - Failed \n\
X             Problem: Duplicate callback registration ignored.",
X             name );
X            XtWarning( msg );
X            return;
X        }
X    }
X
X    rec = &callbacks_ptr[callbacks_num++];   /* ClCacheRec to be filled */
X    rec->quark    = quark;
X    rec->callback = callback;
X    rec->closure  = closure;
X    rec->name     = XtMalloc( strlen(name) + 1 );
X    strcpy ( rec->name, name );
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david       15306 Jun 28 09:13 WcRegister.c    (as sent)'
chmod u=rw,g=r,o=r WcRegister.c
ls -l WcRegister.c
exit 0

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