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