david@jpl-devvax.jpl.nasa.gov (David E. Smyth) (04/12/90)
Submitted-by: david@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@sun.com / argv@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.