v06i068: Motif Resource Interpreter, Part02/03
David E. Smyth
david at jpl-devvax.jpl.nasa.gov
Thu Apr 12 17:43:52 AEST 1990
Submitted-by: david at jpl-devvax.jpl.nasa.gov (David E. Smyth)
Posting-number: Volume 6, Issue 68
Archive-name: mri/part02
# to unbundle, "sh" this file -- DO NOT use csh
# SHAR archive format. Archive created Wed Apr 11 09:59:58 PDT 1990
echo x - MriCreate.c
sed 's/^X//' > MriCreate.c <<'+FUNKY+STUFF+'
X/*
X*******************************************************************************
X*
X* SCCS_data: %Z%%M% %I%(%G%)
X*
X* Module_name:
X*
X* MriCreate.c
X*
X* Subsystem_group:
X*
X* Motif Resource Interpreter, Widget tree creation from Xrm database
X*
X* Related_keywords:
X*
X* Widget, Creation
X*
X* Module_description:
X*
X* This module contains the functions and convenience callbacks
X* used to create and manage a widget tree using the Xrm databse.
X* The Xrm database format used to define widget's children is
X* as follows:
X*
X* toplevel...widget.managedChild_n: name,constructor[,n[onrecursive]]
X* toplevel...widget.unmangedChild_n: name,constructor[,n[onrecursive]]
X* toplevel...widget.dynamicChild_n: name,constructor[,n[onrecursive]]
X* toplevel...widget.unmDynamicChild_n: name,constructor[,n[onrecursive]]
X*
X* Example:
X* helloWorld.managedChild_0: box,XmCreateRowColumn
X* helloWorld.box.managedChild_0: label,XmCreateLabel
X* helloWorld.box.managedChild_1: button,XmCreatePushButton
X* helloWorld.box.label.labelString: Hello, World !
X* helloWorld.box.button.labelString: Bye Bye, World !
X* helloworld.box.button.activateCallback: push(EXIT)
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 MriCreateXrmChildren()
X* function, which descends the widget tree recursively until no more
X* children are found, or widget creation is flagged as "nonrecursive",
X* or a non-composite widget/object is found.
X*
X* Several convenience callbacks are provided here, more will probbably
X* follow.
X*
X* Module_interface_summary:
X*
X* Mri Public Functions:
X*
X* void MriCreateXrmChildren ( - create children from Xrm
X* Widget w) - root of tree
X*
X* Mri Private Functions:
X*
X* Widget CallCreateCallback ( w ) - invokes callbacks after creation
X* Boolean GetChildNameAndConstructor( - True if child found
X* Widget w, - parent
X* char* type - "managed", "unmanaged", "dynamic", or "unmDynamic"
X* int nn, - child to look for, ex: managedChild_2
X* char* name, - returned child name - caller alloc's storage
X* char* constr, - returned constructor name - caller alloc's storage
X* Boolean *recur) - returned recursive flag - caller's storage
X* Widget CreateDatabaseChild (
X* Widget w, - child's parent
X* String type, - "managed" or "unmanaged"
X* int nn ) - child to look for, ex: managedChild_2
X*
X* Module_history:
X*
X* mm/dd/yy initials function action
X* -------- -------- -------- ---------------------------------------------
X* 02/26/90 MarBru All Created
X* 02/16/90 MarBru Create.. Limited creation to composite widgets/objects
X* 04/03/90 d.smyth MriSetValueFromString new func
X* 04/05/90 d.smyth Dynamic Creation, rename to Mri
X* 04/09/90 d.smyth Now contains only funcs related to creation.
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/* -- Operating system includes */
X#include <stdio.h>
X#include <strings.h>
X#include <ctype.h>
X
X/* -- X Window System includes */
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X#include <X11/CoreP.h>
X#include <XmP.h>
X
X/* -- Motif Resource Interpreter Includes */
X#include "Mri.h"
X#include "MriP.h"
X
X/*
X -- Call Create Callback
X*******************************************************************************
X This function calls the CreateCallback defined for the widget in Xrm
X resource database.
X Note the xrmCreateCallback "resource" is NOT a true widget resource,
X there are no instance data associated with it, and only exists in the
X Xrm resource database, used ONLY at widget creation time.
X*/
XWidget CallCreateCallback ( w )
XWidget w; /* child's parent */
X{
X static XtResource res[] =
X {
X { MriNxrmCreateCallback, MriCXrmCreateCallback, XtRCallback,
X sizeof(XtCallbackList), 0, XtRImmediate, (caddr_t)NULL
X },
X };
X XtCallbackList callback = NULL;
X
X XtGetApplicationResources ( w, &callback, res, XtNumber(res), NULL, 0 );
X
X /* If there was any callback list defined, invoke all callbacks on list */
X if ( callback )
X {
X XtCallbackRec *cb = callback;
X for ( cb = callback; cb->callback; cb++ )
X (*cb->callback) ( w, cb->closure, NULL );
X
X }
X}
X
XBoolean GetChildNameAndConstructor( w, type, nn, name, constr, recur )
X Widget w; /* child's parent */
X char* type; /* "managed", "unmanaged", "dynamic", or "unmDynamic" */
X int nn; /* child number to look for ex: managedChild_2 */
X char* name; /* returned child name - caller alloc's storage */
X char* constr; /* returned constructor name - caller alloc's storage */
X Boolean *recur; /* returned recursive flag - caller's storage */
X{
X XtResource c_resource[1];
X Boolean recursive;
X char res_name[20]; /* unmDynamicChild_nnn is 20 char w/ null */
X char* string; /* will point into Xrm storage */
X
X /* update our resource list to look for typeChild_nn subresource */
X sprintf ( res_name, "%sChild_%d", type, nn );
X c_resource[0].resource_name = res_name;
X c_resource[0].resource_class = res_name; /* no class allowed / used */
X c_resource[0].resource_type = XtRString;
X c_resource[0].resource_size = sizeof(String);
X c_resource[0].resource_offset= 0;
X c_resource[0].default_type = XtRImmediate;
X c_resource[0].default_addr = (caddr_t)NULL;
X
X XtGetApplicationResources ( w, &string, c_resource, 1, NULL, 0 );
X
X /* Xrm query returned a string for [un]managedChild_n resource, process */
X if ( string == NULL )
X {
X /* No such resource stored in the database */
X return FALSE;
X }
X else
X {
X register char *s;
X register char *d;
X register int i;
X
X /* extract widget name */
X for ( d=name, s=string; (*s && *s!=','); )
X *d++ = *s++;
X *d = NUL;
X
X /* check for missing class/constructor name */
X if ( *s != ',' )
X {
X char msg [MAX_ERRMSG];
X sprintf ( msg,
X "Resource db error, missing constructor specifier for %s",
X *name ) ;
X XtWarning( msg );
X return FALSE;
X }
X s++;
X
X /* extract class/constructor name and force lowercase, no white space */
X for ( d=constr; (*s && *s!=','); )
X if (*s > ' ')
X *d++ = (isupper(*s)) ? tolower(*s++) : *s++;
X else
X s++;
X *d = NUL;
X
X /* check for non-recursive option */
X *recur = ( *s==',' && (s[1]=='n' || s[1]=='N') ) ? FALSE : TRUE;
X
X return TRUE;
X }
X}
X
Xtypedef struct
X{
X Widget (*const)(); /* pointer to func, i.e., &XmCreateForm() */
X WidgetClass class; /* pointer to WidgetClassRec */
X} Found;
X
XBoolean FindClassOrConstrFromCache( constr, found )
X char* constr;
X Found* found;
X{
X XrmQuark quark;
X int i;
X
X quark = XrmStringToQuark ( constr );
X for (i=0; i<classes_num; i++)
X {
X if ( classes_ptr[i].quark == quark )
X {
X found->class = classes_ptr[i].class;
X found->const = classes_ptr[i].constructor;
X return TRUE;
X }
X }
X return FALSE;
X}
X
XWidget CreateChildUsingCache( parent, child_name, constructor, recursive)
X Widget parent;
X char* child_name;
X char* constructor;
X Boolean recursive;
X{
X Found found;
X found.const = NULL;
X found.class = NULL;
X
X if ( FindClassOrConstrFromCache ( constructor, &found ) )
X {
X Widget child;
X
X if ( found.class )
X child = XtCreateWidget ( child_name, found.class, parent, NULL, 0 );
X else
X child = (*found.const) ( parent, child_name, NULL, 0 );
X
X if (debugging)
X MriDumpFullNameOfWidget(child);
X
X CallCreateCallback ( child );
X
X if ( recursive )
X MriCreateXrmChildren ( child );
X
X return child;
X }
X else
X {
X char msg[MAX_ERRMSG];
X sprintf ( msg,
X "Cannot create child %s using %s, unknown class/constructor",
X child_name, constructor );
X XtWarning( msg );
X return (Widget)NULL;
X }
X}
X
X/*
X -- Create Database Child
X*******************************************************************************
X This function checks the resource database for a presence of widget's
X subresource in a form:
X
X ...widget.managedChild_nn: name.constr_name[,n[onrecursive]]
X ...widget.unmanagedChild_nn: name.constr_name[,n[onrecursive]]
X
X If such a resource is present, the child is created and, if nonrecursive
X option is NOT present, the CreateDatabseChildren is called for this
X child causing recursive tree creation. Creation stops if child_0 or
X two subsequent children are not defined. Creation also stops at any
X non-composite widget/object. Thus, popup-shells etc. must be created
X as manager children.
X
X*/
Xstatic Widget CreateDatabaseChild ( w, type, nn )
XWidget w; /* child's parent */
XString type; /* child type: managed or unmanaged */
Xint nn; /* child # to look for */
X{
X char name [MAX_XRMSTRING];
X char constr[MAX_XRMSTRING];
X Boolean recursive;
X
X if (GetChildNameAndConstructor( w, type, nn, name, constr, &recursive))
X {
X /* if we'w found a class or constructor, create child, call callback */
X return CreateChildUsingCache( w, name, constr, recursive );
X }
X else
X {
X return (Widget)NULL;
X }
X}
X
X/*
X*******************************************************************************
X* Public_function_declarations.
X*******************************************************************************
X*/
X
X/*
X -- Create Xrm Database Children
X*******************************************************************************
X This routine creates widget children as defined in X resource database.
X We look for children defintion starting at child 0 (first looking
X for managed, then unmanaged child). The child lookup terminates if
X child_0 is not present, or two two subsequent child lookups failed
X (allowing to continue if one child was defined incorrectly).
X
X To reduce the database search overhead, we only attempt to create
X children for composite widgets and objects.
X*/
Xvoid MriCreateXrmChildren ( w )
XWidget w;
X{
X Widget child;
X Widget prev;
X Widget managed[MAX_CHILDREN];
X register int i,num;
X
X/* -- check if the requested widget is a manager ( composite ) */
X if (! ( XtIsSubclass( w, compositeWidgetClass )
X || XtIsSubclass( w, compositeObjectClass ) /* not in R3 intrinsics */
X ) ) return;
X
X
X/* -- look for children definition until we have 2 subsequent misses */
X child = (Widget) 1;
X prev = (Widget) 0; /* this makes the child_0 mandatory */
X
X for ( i=0, num=0; (prev || child) ;i++)
X {
X child = CreateDatabaseChild ( w, "managed", i );
X if ( child )
X managed[num++] = child;
X else
X child = CreateDatabaseChild ( w, "unmanaged", i );
X prev = child;
X }
X XtManageChildren(managed, num );
X}
+FUNKY+STUFF+
echo '-rw-r--r-- 1 david 11797 Apr 10 09:53 MriCreate.c (as sent)'
chmod u=rw,g=r,o=r MriCreate.c
ls -l MriCreate.c
echo x - MriCvts.c
sed 's/^X//' > MriCvts.c <<'+FUNKY+STUFF+'
X/*
X*******************************************************************************
X*
X* SCCS_data: %Z%%M% %I%(%G%)
X*
X* Module_name:
X*
X* MriCvts
X*
X* Subsystem_group:
X*
X* Motif Resource Interpreter
X*
X* Related_keywords:
X*
X* Create Motif Widgets from Xrm Database
X*
X* Module_description:
X*
X* This module contains the String To Callback X resource converter,
X* and the String To Widget X resource converter. These are "old
X* style converters, registered with XtAddConverters, and do not
X* get a Display as the first argument.
X*
X* The String to Callback converter parses the resource string in the
X* format:
X*
X* ...path: name[(args)][,name[(args)]]...
X*
X* where: name: specifies the registered callback function name
X* args: specifies the string passed to a callback as
X* "client data".
X*
X* Multiple callbacks can be specified for a single callback list
X* resource. Any callbacks must be "registered" by the application
X* prior converter invocation (.i.e.prior widget creation).
X* If no "args" string is provided, the default "client data"
X* specified at callback registration are used.
X*
X* The String to Widget converter parses the resource string which
X* matches any valid complete or wildcarded widget name to a widget
X* id. The search begins at the root. The first widget whose name
X* matches is "returned."
X*
X* Module_interface_summary:
X*
X*
X* Resource converters are invoked indirectly by the toolkit. The
X* converters are added to the toolkit by widgets by calling
X* MriAddStringToCallbackP() and MriAddStringToWidgetP() in the
X* widget intialization code (see main()).
X*
X* Module_history:
X*
X* mm/dd/yy initials function action
X* -------- -------- ---------------------- -----------------------------
X* 04/05/90 D.E.Smyth Renamed to Mri
X* 03/28/90 D.E.Smyth CvtStringToWidget Created
X* 02/26/90 MarBru CvtStringToCallback Created
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/* -- Operating system includes */
X#include <strings.h>
X#include <ctype.h>
X
X/* -- X Window System includes */
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X
X/* -- Motif Resource Interpreter Include */
X#include "Mri.h"
X#include "MriP.h"
X
X/*
X*******************************************************************************
X* Private_function_declarations.
X*******************************************************************************
X*/
X
X/*
X -- Convert String To Callback
X*******************************************************************************
X This conversion creates a callback list structure from the X resource
X database string in format:
X
X name(arg),name(arg).....
X
X Note "name" is not case sensitive, while "arg" may be - it is passed to
X a callback as client data as a null terminated string (first level
X parenthesis stripped off).
X*/
Xvoid CvtStringToCallback (args, num_args, fromVal, toVal)
X
XXrmValue *args;
XCardinal *num_args;
XXrmValue *fromVal;
XXrmValue *toVal;
X{
X typedef struct
X {
X char *nsta,*nend; /* callback name start, end */
X char *asta,*aend; /* argument string start, end */
X } Segment;
X
X static XtCallbackRec *cb;
X XtCallbackRec callback_list[MAX_CALLBACKS];
X int callback_num = 0;
X String string = (char *) fromVal->addr;
X Segment segs[MAX_CALLBACKS];
X Segment *seg;
X register char *s;
X register int i,ipar;
X
X/* -- assume error or undefined input argument */
X toVal->size = 0;
X toVal->addr = (caddr_t) NULL;
X if (string == NULL) return;
X
X/* -- parse input string finding segments "name(arg)" comma separated */
X ipar = 0;
X seg = segs;
X seg->nsta = string;
X seg->nend = seg->asta = seg->aend = (char*)NULL;
X
X for ( s=string; *s; s++ )
X {
X switch (*s)
X {
X case ',': if ( ipar > 0 ) break; /* commas in arguments ignored */
X if ( seg->nend == NULL ) seg->nend = s-1; /* no argument */
X seg++; /* start the next segment */
X seg->nsta = (s[1]) ? s+1 : (char*)NULL;
X seg->nend = seg->asta = seg->aend = (char*)NULL;
X break;
X
X case '(': if ( ipar++ == 0 ) { seg->nend = s-1; seg->asta = s+1; };
X break;
X
X case ')': if ( --ipar == 0 ) { seg->aend = s-1; };
X break;
X deafult: ;
X }
X }
X seg++; /* start the terminating segment */
X seg->nsta = (char*)NULL;
X
X if (ipar)
X {
X XtStringConversionWarning (string, "Callback, unbalanced parenthesis");
X return;
X }
X
X
X/* -- process individual callback string segments "name(arg)" */
X for( seg = segs; seg->nsta; seg++)
X {
X char cb_name[MAX_XRMSTRING];
X XtCallbackProc found = (XtCallbackProc)NULL;
X XrmQuark quark;
X register char *d;
X register char *end;
X
X /* our callback cache names are case insensitive, no white space */
X for ( s=seg->nsta, d=cb_name; s<=seg->nend; )
X if ( *s > ' ')
X *d++ = (isupper(*s) ) ? tolower (*s++) : *s++;
X else
X s++;
X *d = NUL;
X
X /* try to locate callback in our cache of callbacks */
X quark = XrmStringToQuark (cb_name);
X for (i=0; i<callbacks_num; i++)
X if ( callbacks_ptr[i].quark == quark )
X {
X register XtCallbackRec *rec = &callback_list[callback_num];
X rec->callback = found = callbacks_ptr[i].callback;
X rec->closure = callbacks_ptr[i].closure;
X break;
X }
X
X /* we have found a registered callback, process arguments */
X if (found)
X {
X register char *arg;
X register int alen;
X register XtCallbackRec *rec = &callback_list[callback_num];
X
X if ( seg->asta )
X {
X alen = (int)seg->aend - (int)seg->asta +1;
X arg = XtMalloc(alen+1);
X strncpy ( arg, seg->asta, alen );
X arg[alen+1] = NUL;
X rec->closure = (caddr_t)arg;
X }
X callback_num++;
X }
X else
X {
X XtStringConversionWarning (cb_name, "Callback, unknown callback name");
X }
X } /* end for seg loop */
X
X/* -- terminate the callback list */
X {
X register XtCallbackRec *rec = &callback_list[callback_num];
X rec->callback = NULL;
X rec->closure = NULL;
X callback_num++;
X }
X
X/* -- make a permanent copy of the new callback list, and return a pointer */
X cb = (XtCallbackRec*)XtMalloc( callback_num * sizeof (XtCallbackRec) );
X memcpy ( (char*)cb, (char*)callback_list,
X callback_num * sizeof (XtCallbackRec));
X toVal->size = sizeof (XtCallbackRec*);
X toVal->addr = (caddr_t)&cb;
X}
X
X/*
X -- Convert String To Widget
X*******************************************************************************
X This conversion simply makes use of XtNameToWidget().
X*/
X
Xvoid
XCvtStringToWidget (args, num_args, fromVal, toVal)
X XrmValue *args;
X Cardinal *num_args;
X XrmValue *fromVal;
X XrmValue *toVal;
X{
X toVal->addr = (caddr_t) XtNameToWidget(app_shellW, fromVal->addr);
X}
X
X/*
X*******************************************************************************
X* Public_function_declarations.
X*******************************************************************************
X*/
X
X/*
X -- Add String To Callback Convertor
X*******************************************************************************
X*/
X
Xvoid MriAddStringToCallbackP ()
X{
X static Boolean added = FALSE;
X if ( !added )
X {
X XtAddConverter (XtRString,
X XtRCallback,
X CvtStringToCallback,
X (XtConvertArgList)NULL,
X (Cardinal)0);
X added = TRUE;
X }
X}
X
Xvoid MriAddStringToWidgetP ()
X{
X static Boolean added = FALSE;
X if ( !added )
X {
X XtAddConverter (XtRString,
X "Window", /* wrong, but it works !?! */
X CvtStringToWidget,
X (XtConvertArgList)NULL,
X (Cardinal)0);
X added = TRUE;
X }
X}
+FUNKY+STUFF+
echo '-rw-r--r-- 1 david 8495 Apr 10 10:13 MriCvts.c (as sent)'
chmod u=rw,g=r,o=r MriCvts.c
ls -l MriCvts.c
echo x - MriDynCreate.c
sed 's/^X//' > MriDynCreate.c <<'+FUNKY+STUFF+'
X/*
X*******************************************************************************
X*
X* SCCS_data: %Z%%M% %I%(%G%)
X*
X* Module_name:
X*
X* MriDynCreate.c
X*
X* Subsystem_group:
X*
X* Motif Resource Interpreter, Widget tree creation from Xrm database
X*
X* Related_keywords:
X*
X* Widget, Creation
X*
X* Module_description:
X*
X* This module contains the functions and convenience callbacks
X* used to dynamically create and manage a widget tree using the
X* Xrm databse. The Xrm database format used to define widget's
X* children is as follows:
X*
X* toplevel...widget.managedChild_n: name,constructor[,n[onrecursive]]
X* toplevel...widget.unmangedChild_n: name,constructor[,n[onrecursive]]
X* toplevel...widget.dynamicChild_n: name,constructor[,n[onrecursive]]
X* toplevel...widget.unmDynamicChild_n: name,constructor[,n[onrecursive]]
X*
X* Only the dynamicChild_n and unmDynamicChild_n cases are
X* handled in this module.
X*
X* Example:
X* helloWorld.dynamicChild_n: box,XmCreateRowColumn
X* helloWorld.box.managedChild_0: label,XmCreateLabel
X* helloWorld.box.managedChild_1: button,XmCreatePushButton
X* helloWorld.box.label.labelString: Hello, World !
X* helloWorld.box.button.labelString: Bye Bye, World !
X* helloworld.box.button.activateCallback: push(EXIT)
X*
X* The widget tree, consisting of the box with a label and button
X* as its children, are created dynamically, generally as the result
X* of an ivocation of MriCreateDynamicWidgetCB().
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* Only the first widget is created herein. Any children of the first
X* (the label and button in the example) get created via the
X* MriCreateXrmChildren() function.
X*
X* Module_interface_summary:
X*
X* Creation and Private Functions:
X*
X* CreateDynamicChild()
X*
X* Module_history:
X*
X* mm/dd/yy initials function action
X* -------- -------- -------- ---------------------------------------------
X* 04/05/90 d.smyth Dynamic Creation
X* 04/09/90 d.smyth Now contains only funcs related to dynamic creation.
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/* -- Operating system includes */
X#include <stdio.h>
X#include <strings.h>
X#include <ctype.h>
X
X/* -- X Window System includes */
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X#include <X11/CoreP.h>
X#include <XmP.h>
X
X/* -- Motif Resource Interpreter Includes */
X#include "Mri.h"
X#include "MriP.h"
X
X/*
X -- Create Named Dynamic Child
X*******************************************************************************
X Get all the DynamicChild_xx and unmDynamicChild_xx resources
X for the parent, and create the widget whose name matches the
X child arg.
X*/
Xvoid CreateDynamicChild( parent, child_name )
X Widget parent;
X char *child_name;
X{
X int nn = 0;
X char name[MAX_XRMSTRING];
X char constr[MAX_XRMSTRING];
X Boolean recursive;
X
X while (GetChildNameAndConstructor( parent, "dynamic",
X nn, name, constr, &recursive))
X {
X if (strcmp(child_name, name))
X {
X /* Nope, this child is not the one we want, try the next... */
X nn++;
X }
X else
X {
X /* Yeah! we found the right child, create and manage it. */
X XtManageChild( CreateChildUsingCache(
X parent, name, constr, recursive));
X return;
X }
X }
X
X while (GetChildNameAndConstructor( parent, "unmDynamic",
X nn, name, constr, &recursive))
X {
X if (strcmp(child_name, name))
X {
X /* Nope, this child is not the one we want, try the next... */
X nn++;
X }
X else
X {
X /* Yeah! we found the right child, create it, but don't manage. */
X CreateChildUsingCache( parent, name, constr, recursive );
X return;
X }
X }
X}
X
+FUNKY+STUFF+
echo '-rw-r--r-- 1 david 4507 Apr 9 18:16 MriDynCreate.c (as sent)'
chmod u=rw,g=r,o=r MriDynCreate.c
ls -l MriDynCreate.c
echo x - MriMain.c
sed 's/^X//' > MriMain.c <<'+FUNKY+STUFF+'
X/*
X*******************************************************************************
X* MriMain.c
X*******************************************************************************
X This program uses the Xrm (X resource management) database
X for a widget tree definition and management.
X There is very little code in this program, since the entire user interface
X definition is stored in the Xrm database, preferably in the application
X class resource file: ~/apps-defaults/<application>
X/*
X*******************************************************************************
X* Include_files.
X*******************************************************************************
X All Motif things are included, so the interface
X may be arbitrarily complex.
X*/
X
X/******
X* Core (Object, RectObj, WindowObj), Gadget, Composite, Primitive,
X* Shell, OverrideShell, WMShell, VendorShell, TopLevelShell,
X* ApplicationShell, TransientShell, Constraint, and Manager :
X******/
X#include <Xm/Xm.h>
X
X/******
X* Primitive Widgets and Gadgets:
X******/
X#include <Xm/ArrowB.h>
X#include <Xm/ArrowBG.h>
X#include <Xm/CascadeB.h>
X#include <Xm/CascadeBG.h>
X#include <Xm/DrawnB.h>
X#include <Xm/Label.h>
X#include <Xm/LabelG.h>
X#include <Xm/List.h>
X#include <Xm/PushB.h>
X#include <Xm/PushBG.h>
X#include <Xm/ScrollBar.h>
X#include <Xm/SeparatoG.h>
X#include <Xm/Separator.h>
X#include <Xm/Text.h>
X#include <Xm/ToggleB.h>
X#include <Xm/ToggleBG.h>
X
X/******
X* Shell Widgets:
X******/
X#include <Xm/DialogS.h>
X#include <Xm/MenuShell.h>
X
X/******
X* Manager Widgets:
X******/
X#include <Xm/BulletinB.h>
X#include <Xm/Command.h>
X#include <Xm/DrawingA.h>
X#include <Xm/FileSB.h>
X#include <Xm/Form.h>
X#include <Xm/Frame.h>
X#include <Xm/MainW.h>
X#include <Xm/MessageB.h>
X#include <Xm/PanedW.h>
X#include <Xm/RowColumn.h>
X#include <Xm/Scale.h>
X#include <Xm/ScrolledW.h>
X#include <Xm/SelectioB.h>
X
X/******
X* Other Motif Includes
X******
X* #include <Xm/CutPaste.h>
X* #include <Xm/bitmaps.h>
X* #include <Xm/mwm.h>
X******/
X
X/******
X* Motif Resource Interpreter Xrm Creation and Callback routines
X******/
X#include "Mri.h"
X
XWidget app_shellW; /* application shell widget */
XXtAppContext app;
XBoolean debugging = 0;
X
Xstatic XtResource debugRes[] =
X{
X { /* set debugging from resource database and command line: */
X "debugging", "Debugging", /* resource name and class */
X XmRBoolean, sizeof(Boolean), /* resource type and size */
X 0, /* no offset - store directly */
X XmRString, "False" /* default value */
X }
X};
X
X/*
X*******************************************************************************
X* MAIN function
X*******************************************************************************
X*/
X
Xmain ( argc, argv )
Xint argc;
Xchar **argv;
X{
X UserInitialization( &argc, argv );
X
X/* -- Intialize Xt Toolkit creating the application shell */
X app_shellW = XtInitialize ( appName, appClass,
X appOptions, numOptions,
X &argc, argv );
X app = XtWidgetToApplicationContext(app_shellW);
X
X/* -- set debugging flag */
X XtGetApplicationResources( app_shellW,
X &debugging, /* set debugging from resources */
X debugRes, XtNumber(debugRes), /* app resource specification */
X NULL, 0); /* argv not checked here... */
X
X if ('D' == getopt(argc, argv, "D")) /* ... but here */
X debugging++;
X
X/* -- Register Converters */
X MriAddStringToWidgetP();
X MriAddStringToCallbackP();
X
X/* -- Register available Widget constructors - N.B. Case Insensitive */
X#define CON(n,c) MriRegisterConstructor(app,n,c)
X
X CON ( "xmArrowButton", XmCreateArrowButton );
X CON ( "xmArrowButtonGadget", XmCreateArrowButtonGadget );
X CON ( "xmBulletinBoard", XmCreateBulletinBoard );
X CON ( "xmBulletinBoardDialog", XmCreateBulletinBoardDialog );
X CON ( "xmCascadeButton", XmCreateCascadeButton );
X CON ( "xmCascadeButtonGadget", XmCreateCascadeButtonGadget );
X CON ( "xmCommand", XmCreateCommand );
X CON ( "xmDialogShell", XmCreateDialogShell );
X CON ( "xmDrawingArea", XmCreateDrawingArea );
X CON ( "xmDrawnButton", XmCreateDrawnButton );
X CON ( "xmErrorDialog", XmCreateErrorDialog );
X CON ( "xmFileSelectionBox", XmCreateFileSelectionBox );
X CON ( "xmFileSelectionDialog", XmCreateFileSelectionDialog );
X CON ( "xmForm", XmCreateForm );
X CON ( "xmFormDialog", XmCreateFormDialog );
X CON ( "xmFrame", XmCreateFrame );
X CON ( "xmInformationDialog", XmCreateInformationDialog );
X CON ( "xmLabel", XmCreateLabel );
X CON ( "xmLabelGadget", XmCreateLabelGadget );
X CON ( "xmList", XmCreateList );
X CON ( "xmMainWindow", XmCreateMainWindow );
X CON ( "xmMenuBar", XmCreateMenuBar );
X CON ( "xmMenuShell", XmCreateMenuShell );
X CON ( "xmMessageBox", XmCreateMessageBox );
X CON ( "xmMessageDialog", XmCreateMessageDialog );
X CON ( "xmOptionMenu", XmCreateOptionMenu );
X CON ( "xmPanedWindow", XmCreatePanedWindow );
X CON ( "xmPopupMenu", XmCreatePopupMenu );
X CON ( "xmPromptDialog", XmCreatePromptDialog );
X CON ( "xmPushButton", XmCreatePushButton );
X CON ( "xmPushButtonGadget", XmCreatePushButtonGadget );
X CON ( "xmPulldownMenu", XmCreatePulldownMenu );
X CON ( "xmQuestionDialog", XmCreateQuestionDialog );
X CON ( "xmRadioBox", XmCreateRadioBox );
X CON ( "xmRowColumn", XmCreateRowColumn );
X CON ( "xmScrollBar", XmCreateScrollBar );
X CON ( "xmScrolledList", XmCreateScrolledList );
X CON ( "xmScrolledText", XmCreateScrolledText );
X CON ( "xmScrolledWindow", XmCreateScrolledWindow );
X CON ( "xmScale", XmCreateScale );
X CON ( "xmSelectionBox", XmCreateSelectionBox );
X CON ( "xmSelectionDialog", XmCreateSelectionDialog );
X CON ( "xmSeparator", XmCreateSeparator );
X CON ( "xmSeparatorGadget", XmCreateSeparatorGadget );
X CON ( "xmText", XmCreateText );
X CON ( "xmToggleButton", XmCreateToggleButton );
X CON ( "xmToggleButtonGadget", XmCreateToggleButtonGadget );
X CON ( "xmWarningDialog", XmCreateWarningDialog );
X CON ( "xmWorkingDialog", XmCreateWorkingDialog );
X
X#undef CON
X
X/* -- Register Classes */
X /* An equivalent way of registering constructors: Registering classes
X ** means XtCreateWidget() is called instead of XmCreate...().
X ** Above, we've defined all the Motif constructors, so we don't
X ** need any Motif classes registered. However, custom widgets
X ** might not provide convenience functions, and simply rely on
X ** XtCreateWidget. Such classes of widgets must be registered below.
X */
X#define CLASS(n,c) MriRegisterObjectClass(app, n, c)
X/* CLASS ( "xmBulletinBoard", xmBulletinBoardWidgetClass); */
X#undef CLASS
X
X/* -- Register available callbacks:
X ** Register Mri callbacks, including manage, unmanage, setResource
X */
X MriRegisterMriCallbacks ( app );
X
X /* Application provided function, registers appl specific callbacks
X */
X RegisterApplicationCallbacks( &argc, argv, app );
X
X
X/* -- Create children of the toplevel shell defined by the Xrm database */
X
X MriCreateXrmChildren ( app_shellW );
X
X/* -- Realize the widget tree and enter the main application loop */
X
X XtRealizeWidget ( app_shellW );
X XtMainLoop ( );
X}
+FUNKY+STUFF+
echo '-rw-r--r-- 1 david 7250 Apr 10 14:00 MriMain.c (as sent)'
chmod u=rw,g=r,o=r MriMain.c
ls -l MriMain.c
echo x - MriMisc.c
sed 's/^X//' > MriMisc.c <<'+FUNKY+STUFF+'
X/*
X*******************************************************************************
X*
X* SCCS_data: %Z%%M% %I%(%G%)
X*
X* Module_name:
X*
X* MriMisc.c
X*
X* Subsystem_group:
X*
X* Motif Resource Interpreter, Widget tree creation from Xrm database
X*
X* Related_keywords:
X*
X* Widget Name to Widget
X*
X* Module_description:
X*
X* This module contains the functions which seem generally useful
X* for application writers when using Mri.
X*
X* Module_interface_summary:
X*
X* MriSetValueFromString( - converts string to val, calls XtSetValue()
X* Widget w, - widget to which resources apply
X* String res_name, - name or class name of resource
X* String res_value ) - string to convert from
X*
X* MriNameToWidgetList( - converts a string to separate widgets
X* String names, - typ client data as rcvd by a callback
X* Widget widgets[], - returned array or widgets
X* int *num ) - returned number of widgets
X*
X* MriDumpFullNameOfWidget( - dump to stderr
X* Widget w ) - the full name of this widget
X*
X* Module_history:
X*
X* mm/dd/yy initials function action
X* -------- -------- -------- ---------------------------------------------
X* 04/03/90 d.smyth MriSetValueFromString new func
X* 04/05/90 d.smyth moved to this file.
X*
X* Design_notes:
X
X/*
X*******************************************************************************
X* Include_files.
X*******************************************************************************
X*/
X
X/* -- Operating system includes */
X#include <stdio.h>
X#include <strings.h>
X#include <ctype.h>
X
X/* -- X Window System includes */
X#include <X11/IntrinsicP.h>
X#include <X11/StringDefs.h>
X#include <X11/CoreP.h>
X#include <XmP.h>
X
X/* -- Motif Resource Interpreter Includes */
X#include "Mri.h"
X#include "MriP.h"
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*/
Xvoid
XMriSetValueFromString( w, res_name, res_val)
X Widget w; /* MUST already be init'd */
X char* res_name;
X char* res_val;
X{
X XtResource* res_list;
X int i, num;
X char msg[256];
X char* ret_val;
X char* ta;
X XrmValue fr_val;
X XrmValue to_val;
X Arg arg[1];
X
X /* Motif returns an un-quarkified resource list - R4's is quarkified */
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 XmRString, /* 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 MriSetValueFromString: %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 -- Names to Widget List
X******************************************************************************
X This routine converts a string of comma separated widget names
X (or widget pathes) into a list of widget id's. Blank space ignored
X If a NULL string is provided, the widget ID of reference widget
X is put on the list
X
X The name "this" means the reference widget.
X
X The widget search starts at the TOP of widget hierarchy (using the
X top level shell as a reference widget). The name of the top level
X shell is NOT specified.
X
X The widget path name can include wildcards. See XtNameToWidget()
X in manual for discussion on how it resolves ambiguities.
X*/
Xvoid
XMriNamesToWidgetList ( w, client, widget_list, widget_count )
X Widget w; /* reference widget */
X caddr_t client; /* callback client data - string of names */
X Widget *widget_list; /* returned widget list */
X Cardinal *widget_count; /* returned widget count */
X{
X Widget top;
X char *string = (String)client;
X char name[MAX_XRMSTRING];
X register char *s;
X register char *d;
X
X/* -- default case, no string provided, return the calling widget */
X if (!string)
X {
X widget_list[0] = w;
X *widget_count = 1;
X return;
X }
X
X/* -- find the reference widget as the toplevel shell */
X top = w;
X while ( XtParent(top) ) top = XtParent(top);
X
X/* -- parse the input string "name.name,name.name,name.name.name" */
X *widget_count = 0;
X for ( d = name, s = string; ; s++ )
X {
X if ( *s == ',' || *s == NUL )
X {
X Widget widget;
X if ( *s == NUL && d == name )
X return;
X *d = NUL;
X if (strcmp("this",name) == 0)
X {
X widget_list[*widget_count] = w;
X (*widget_count)++;
X }
X else
X {
X widget = XtNameToWidget ( top, name );
X if ( widget )
X {
X widget_list[*widget_count] = widget;
X (*widget_count)++;
X }
X else
X XtStringConversionWarning (name, "Widget");
X }
X if ( *s == NUL )
X return;
X d = name;
X }
X else if ( *s > ' ' )
X {
X *d++ = *s;
X }
X else
X ;
X }
X}
X
X/*
X -- Dump Full Name of Widget
X*******************************************************************************
X Traverse up the widget tree, print out each name right up to
X the root of the widget tree. Print the names to stderr. Use
X recursion so order of names comes out right.
X*/
X
Xstatic void DumpNameOfWidget(w)
X Widget w;
X{
X if (w->core.parent)
X DumpNameOfWidget(w->core.parent);
X fprintf(stderr,"%s.",w->core.name);
X}
X
Xvoid MriDumpFullNameOfWidget(w)
X Widget w;
X{
X if (w->core.parent)
X DumpNameOfWidget(w->core.parent);
X fprintf(stderr,"%s of class %s\n",
X w->core.name,
X w->core.widget_class->core_class.class_name);
X}
X
+FUNKY+STUFF+
echo '-rw-r--r-- 1 david 7185 Apr 10 17:26 MriMisc.c (as sent)'
chmod u=rw,g=r,o=r MriMisc.c
ls -l MriMisc.c
exit 0
dan
-----------------------------------------------------------
O'Reilly && Associates
argv at sun.com / argv at ora.com
632 Petaluma Ave, Sebastopol, CA 95472
800-338-NUTS, in CA: 800-533-NUTS, FAX 707-829-0104
Opinions expressed reflect those of the author only.
More information about the Comp.sources.x
mailing list