v10i050: wcl -- widget creation library, Part02/11

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


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

# to unbundle, "sh" this file -- DO NOT use csh
#  SHAR archive format.  Archive created Fri Oct 19 09:32:06 PDT 1990
echo x - 7thREADME
sed 's/^X//' > 7thREADME <<'+FUNKY+STUFF+'
XWriting Callback Functions
X--------------------------
X
XYour application will consist of two fairly independent parts: the
Xresource file which describes the look and alot of the feel of the
Xapplication, and the callbacks which you write in C (of course,
Xyou can use languages other than C, but C is probably the easiest).
X
XIn order to bind the widgets created due to resource specifications
Xto your callbacks implemented in C, you need to write the callbacks
Xso they adhere to the standard Xt callback proc typedef, and you
Xneed to register your callbacks with the Widget Creation Library's
Xstring-to-callback converter.
X
XXtCallbackProc
X--------------
X
XAs defined by the XtIntrinsics, widget callback procedures must match
Xthis typedef:
X
Xtypedef void (*XtCallbackProc)(
X#if NeedFunctionPrototypes
X    Widget              /* widget */,
X    XtPointer           /* closure */,  /* data the application registered */
X    XtPointer           /* call_data */ /* callback specific data */
X#endif
X);
X
XHere is an example callback proc which does nothing with its
Xarguments:
X
Xvoid MyExitCB ( w, ignored, unused )
X    Widget      w;
X    caddr_t     ignored;
X    caddr_t     unused;
X{
X    exit();
X}
X
XYou must register this function with the Widget Creation Library
Xbefore creating any widgets which might want to bind to it.
XIn general, register your callbacks after calling XtInitialize()
Xand before calling WcCreateWidgets().  Here is an example of
Xhow you register a callback:
X
X#define RCALL( name, func ) WcRegisterCallback ( app, name, func, NULL )
X
X    RCALL( "MyExitCB", MyExitCB );
X
XAll registered callbacks can be bound to widget callback resources
Xwithin the resource database.  For example:
X
X    *foo.activateCallback: MyExitCB
X
XMost callbacks really want to do something with the data they
Xget as arguments.  The closure data, often called client data,
Xcan be specified as a string within the resource database.
XThe string is passed as the second argument.  For example:
X
Xvoid WcSystemCB ( w, shellCmdString, unused )
X    Widget      w;
X    char*       shellCmdString;
X    caddr_t     unused;
X{
X    system( shellCmdString );
X}
X
XNote that leading and trailing whitespace is NOT filtered out before
Xthe callback gets it.  For example, the resource specification:
X
X    *foo.activateCallback: WcSystemCB( echo Howdy )
X
Xpasses the string " echo Howdy " to the callback.  The resource 
Xspecification:
X
X    *foo.activateCallback: WcSystemCB( echo Howdy \
X				and hello thar)
X
Xpasses the string " echo Howdy \t\t\t\tand hello thar" (where `\t' means
Xthe tab character) to the callback.  Since the callbacks usually need
Xto parse these argument strings, several Widget Creation Library
Xfunctions are provided in the hope of making your life easier:
X
Xchar* WcCleanName( char* src, char* clean )
X-------------------------------------------
X
XThis takes two pointers to char as arguments.  The leading whitespace
Xcharacters from src are skipped, and then all characters up to but
Xnot including a whitespace are copied into the buffer pointed to by
Xclean.  Note the caller must provide storage for clean.  The function
Xreturns a pointer to the first whitespace following what got copied
Xto clean, so this function may be used in a loop.
X
XWidget WcFullNameToWidget ( Widget ref, char* name )
X----------------------------------------------------
X
XThis function uses the reference Widget for relative naming, and to
Xdetermine the widget tree for converting full pathnames to a widget.
XFor example, one may need to get the actual widget which is named by
X"*Foo*bar.glorp"  The ref widget is used to find the root of the widget
Xtree, and start the name search from there.
X
XThe last component MUST be a widget instance name, it cannot be a
Xwidget class name.
X
XAmbiguous names are resolved as done by XtNameToWidget() upon which
XWcFullNameToWidget() is derived.
X
XVery frequently, one gets a name from an argument list using
XWcCleanName() and then passes that name on to WcFullNameToWidget in
Xorder to manipulate that widget.  For example:
X
Xvoid MyPopupCB( w, name, unused )
X    Widget  w;
X    char*   name;
X    caddr_t unused;
X{
X    Widget widget;
X    char   clean[MAX_XRMNAME];
X
X    (void)WcCleanName ( name, cleanName );
X    widget = WcFullNameToWidget ( w, cleanName );
X
X    if (XtIsShell(widget))
X	 XtPopup  ( widget, XtGrabNonexclusive );
X}
X
XEfficiency Considerations
X-------------------------
X
XI know parsing string arguments on every callback invocation is not so
Xincredibly efficient.  When Motif runs on Xt release 4, then I will
Xre-write the string-to-widget converter so it caches the results, and
Xthen callbacks can invoke the caching converter.
X
XAlso, if you are very interested in performance for a real application
X(after you have fleshed out the interface using Ari or Mri), you
Xshould write additional callbacks which are more intelligent, and
Xdetect being called repeatedly from the same widget with the same
Xargument.
X
XYou may want to consider using the XrmQuark functions for keeping
Xtrack of strings as well.  XrmQuarks are effectively indexes into
Xa string symbol table kept by Xrm (part of Xlib).  Doing comparisions
Xand assingments using Quarks is substantially faster at run-time than
Xusing character strings.  XrmQuarkToString() and XrmStringToQuark()
Xare used to convert between Quarks and Strings.
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        5304 Aug  6 09:36 7thREADME    (as sent)'
chmod u=rw,g=r,o=r 7thREADME
ls -l 7thREADME
echo x - A01.Hello
sed 's/^X//' > A01.Hello <<'+FUNKY+STUFF+'
X  This resource file represents a very basic application: a single
X  button which, when pressed, causes the application to exit.
X
XAri.wcChildren:		command
XAri.title:		Ari using A1.Hello
X
X*command.wcClass:	commandWidgetClass
X*command.Label:		Click the left mouse button here
X*command.callback:	WcExitCB
+FUNKY+STUFF+
echo '-rw-r--r--  1 david         302 Aug  6 09:36 A01.Hello    (as sent)'
chmod u=rw,g=r,o=r A01.Hello
ls -l A01.Hello
echo x - A02.Scrollbar
sed 's/^X//' > A02.Scrollbar <<'+FUNKY+STUFF+'
X  This provides similar functionality as that shown by the Xaw example
X  named xscroll, which demonstrates how to use the Scrollbar widget.
X
XAri.wcChildren:		box
XAri.title:		Ari using A2.Scrollbar
X
X*box.wcClassName:	Box
X*Box*allowResize:	True
X*box.wcChildren:	quit, scrollbar
X
X*quit.wcClass:		commandWidgetClass
X*quit.Label:		Quit
X*quit.callback:		WcExitCB
X
X*scrollbar.wcClass:	scrollbarWidgetClass
X*scrollbar.orientation:	horizontal
X*scrollbar.topOfThumb:  0.5
X*scrollbar.length:	300
X*scrollbar.jumpProc:	WcSystemCB(echo Jumped)
X*scrollbar.scrollProc:	WcSystemCB( echo Scrolled)
X
+FUNKY+STUFF+
echo '-rw-r--r--  1 david         581 Aug  6 09:36 A02.Scrollbar    (as sent)'
chmod u=rw,g=r,o=r A02.Scrollbar
ls -l A02.Scrollbar
echo x - A03.Box
sed 's/^X//' > A03.Box <<'+FUNKY+STUFF+'
X  This provides similar functionality as that shown by the Xaw example
X  named xbuttonbox.  The Box widget is used to introduce the programmer to
X  a widget hierarchy.
X
X  Unlike the Shell widget a Box widget can accept more than one child.
X  By using boxes and other composites it is possible to create an
X  arbitrarily complex application with hundreds or event thousands of
X  widgets.
X
XAri.wcChildren:		box
XAri.title:		Ari using A3.Box
X
X*box.wcClassName:	Box
X*box.wcChildren:	quit, \
X			lab1, lab2, lab3, lab4, lab5, \
X			lab6, lab7, lab8, lab9, lab10
X
X*quit.wcClassName:	Command
X*quit.callback:		WcExitCB
X*Command.Label:    Click the left mouse button here to quit
X
X*lab1.wcClass:		labelWidgetClass
X*lab2.wcClass:          labelWidgetClass
X*lab3.wcClass:          labelWidgetClass
X*lab4.wcClass:          labelWidgetClass
X*lab5.wcClass:          labelWidgetClass
X*lab6.wcClass:          labelWidgetClass
X*lab7.wcClass:          labelWidgetClass
X*lab8.wcClass:          labelWidgetClass
X*lab9.wcClass:          labelWidgetClass
X*lab10.wcClass:         labelWidgetClass
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        1071 Aug  6 09:36 A03.Box    (as sent)'
chmod u=rw,g=r,o=r A03.Box
ls -l A03.Box
echo x - A04.Paned
sed 's/^X//' > A04.Paned <<'+FUNKY+STUFF+'
XAri.wcChildren:	paned
X
X*paned.wcClassName:	Paned
X*paned.wcChildren:	quit, label
X
X*quit.wcClassName:	Command
X*quit.callback:		WcExitCB
X*quit.font:		*-courier-bold-r-*-240-*
X*quit.translations:	<EnterWindow>:	highlight()		\n\
X			<LeaveWindow>:	reset()			\n\
X			<Btn1Down>:	set()			\n\
X			<Btn1Up>:	notify() unset()	\n\
X			<Key>Return:	WcSetValueACT(*quit.label:Quit) \n\
X			<Key>Tab:	WcSetValueACT(*quit.label: Go)
X
X*label.wcClassName:	Label
X*label.label:		Paned, Command, & Label
X*label.font:		*lucida-bold-i-*-240-*
X*label.translations:	
+FUNKY+STUFF+
echo '-rw-rw-r--  1 david         538 Oct  9 19:38 A04.Paned    (as sent)'
chmod u=rw,g=rw,o=r A04.Paned
ls -l A04.Paned
echo x - A05.Menu
sed 's/^X//' > A05.Menu <<'+FUNKY+STUFF+'
X! Example showing how to use Athena Menus
X
XAri.wcChildren:	menuButton, menu
X
X*menuButton.wcClass:	menuButtonWidgetClass
X
X*menu.wcClass:		simpleMenuWidgetClass
X*menu.wcManaged:	False
X*menu.wcChildren:	menuEntry1, menuEntry2, menuLine, \
X			menuEntry3, menuEntry4, menuEntry5
X
X*menuLine.wcClass:      smeLineObjectClass
X*menuEntry1.wcClass:    smeBSBObjectClass
X*menuEntry2.wcClass:    smeBSBObjectClass
X*menuEntry3.wcClass:    smeBSBObjectClass
X*menuEntry4.wcClass:    smeBSBObjectClass
X*menuEntry5.wcClass:    smeBSBObjectClass
X*menuEntry5.label:	quit
X*menuEntry5.callback:	WcExitCB
X
+FUNKY+STUFF+
echo '-rw-rw-r--  1 david         584 Sep 30 10:15 A05.Menu    (as sent)'
chmod u=rw,g=rw,o=r A05.Menu
ls -l A05.Menu
echo x - A06.Dialog
sed 's/^X//' > A06.Dialog <<'+FUNKY+STUFF+'
XAri.wcChildren:		dialog
X
X*dialog.wcClassName:	Dialog
X*dialog.wcChildren:	ok
X*dialog*Font:		*times-bold-i-*-80-*
X
X*dialog.label:		I am a Dialog widget.
X*dialog.label.font:	*new century schoolbook-bold-r-*-140-*
X
X*dialog.value:		Enter new value here.
X
X*ok.wcClassName:	Command
X*ok.callback:		WcExitCB
+FUNKY+STUFF+
echo '-rw-rw-r--  1 david         299 Oct  9 19:44 A06.Dialog    (as sent)'
chmod u=rw,g=rw,o=r A06.Dialog
ls -l A06.Dialog
echo x - A07.Form
sed 's/^X//' > A07.Form <<'+FUNKY+STUFF+'
XAri.wcChildren:		form
X
X*font:			*times-bold-i-*-140-*
X
X*form.wcClassName:	Form
X*form.wcChildren:	label, one, two, three, go
X
X*label.wcClassName:	Label
X*label.label:		Form with Buttons
X
X*one.wcClassName:	Command
X*one.fromVert:		*label
X
X*two.wcClassName:	Command
X*two.fromHoriz:		*label
X
X*three.wcClassName:	Command
X*three.fromHoriz:	*one
X*three.fromVert:	*label
X
X*go.wcClassName:	Command
X*go.fromHoriz:		*three
X*go.fromVert:		*two
X*go.callback:		WcExitCB
+FUNKY+STUFF+
echo '-rw-rw-r--  1 david         454 Oct  9 19:49 A07.Form    (as sent)'
chmod u=rw,g=rw,o=r A07.Form
ls -l A07.Form
echo x - A08.ClkLogo
sed 's/^X//' > A08.ClkLogo <<'+FUNKY+STUFF+'
XAri.wcChildren:		box
X
X*box.wcClassName:	Box
X*box.wcChildren:	clock, logo, label
X*box.translations:	<Key>Return:	WcExitACT() \n\
X			<Key>Tab:	WcSystemACT( echo Yo Dude! ) \n\
X			<Key>Delete:	WcSystemACT( Ari & )
X
X*clock.wcClassName:	ClockWidget
X
X*logo.wcClassName:	LogoWidget
X
X*label.wcClassName:	Label
X*label.label:		Try hitting Delete, Tab, and Return
+FUNKY+STUFF+
echo '-rw-rw-r--  1 david         353 Oct 15 16:21 A08.ClkLogo    (as sent)'
chmod u=rw,g=rw,o=r A08.ClkLogo
ls -l A08.ClkLogo
echo x - A09.Text
sed 's/^X//' > A09.Text <<'+FUNKY+STUFF+'
XAri.wcChildren:			paned
X
X*paned.wcClassName:		Paned
X*paned.wcChildren:		quit, textFile
X
X*quit.wcClassName:		Command
X*quit.callback:			WcExitCB
X
X*textFile.wcClassName:		AsciiText
X*textFile*type:			file
X*textFile*string:		/etc/motd
X*textFile.scrollVertical:	whenNeeded
X*textFile.scrollHorizontal:	whenNeeded
X*textFile.height:		100
X*textFile*font:			*clean-medium-r-*-150-*
+FUNKY+STUFF+
echo '-rw-rw-r--  1 david         371 Oct  9 20:26 A09.Text    (as sent)'
chmod u=rw,g=rw,o=r A09.Text
ls -l A09.Text
echo x - App.c
sed 's/^X//' > App.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**
X** SCCS_data: @(#)Ari.c 1.0 ( 19 June 1990 )
X**
X** Description:	This file contains a sample application which uses
X**		Athena widgets.  The example functionally mimics the
X**		xwidgets.c example provided in examples/Xaw on the
X**		X11R4 tape from MIT.  The Widget Creation library
X**		is used.
X**
X**              Several application specific callbacks are registered
X**		with the Wc library, and bound to the interface by
X**		specifications within the application resource file.
X**
X**		Note that this application has NO fallback resources.
X**		Since the resource file actually defines the complete
X**		widget tree, the resource file(s) MUST be found,
X**		eliminating the raison d'etre of the fallbacks.
X**
X** Notes:	This program uses the Xrm (X resource management) database
X**		for widget tree definition and management.
X**
X******************************************************************************/
X
X/******************************************************************************
X**   Include_files.
X******************************************************************************/
X
X/*  -- Minimum include files to use WidgetCreate Library */
X#include <X11/Intrinsic.h>
X#include <WcCreate.h>
X
X/*  -- application specific include files */
X#include <stdio.h>
X#include <ctype.h>
X#include <X11/Xaw/Dialog.h>
X#include <X11/StringDefs.h>
X
X/******************************************************************************
X**  Private Functions
X******************************************************************************/
X
Xextern void AriRegisterAthena ();
X
X/*
X    -- Tied to Dialog `Okay' button
X******************************************************************************
X    Adds an entry to the List widget whose name is passed as clientData.
X*/
X
Xstatic void MyOkayCB( widget, widgetName, unused )
X    Widget  widget;
X    char*   widgetName;
X    caddr_t unused;
X{
X    Widget list_widget = WcFullNameToWidget( widget, widgetName );
X    static String * list = NULL;
X    static int num_items = 0, allocated_items = 0;
X
X    if (num_items == allocated_items) {
X        allocated_items += 10;
X        list = (String *) XtRealloc(list, sizeof(String) * allocated_items);
X    }
X
X    /*
X     * The value returned by XawDialogGetValueString() does not remain good
X     * forever so we must store is somewhere.  This creates a memory leak
X     * since I don't remember these values, and free them later.  I know about
X     * it, but it doesn't seem worth fixing in this example.
X     */
X
X    list[num_items++] = XtNewString(XawDialogGetValueString(XtParent(widget)));
X    XawListChange(list_widget, list, num_items, 0, True);
X}
X
X/*
X    -- MyQuitCB
X******************************************************************************
X    This function destroys the widget tree.
X*/
X
Xstatic void MyQuitCB( widget, widgetName, ignored )
X    Widget  widget;
X    char*   widgetName;
X    caddr_t ignored;
X{
X    Widget condemmed = WcFullNameToWidget( widget, widgetName );
X    fprintf(stderr, "MyQuitCB(%s)\n", widgetName );
X    if (condemmed == NULL)
X        XtDestroyWidget( WcRootWidget( widget ) );
X    else
X	XtDestroyWidget( condemmed );
X}
X
X/*
X    -- MyTimeSinceTouchedCB  Tied to the strip chart widget.
X******************************************************************************
X    This function returns the number of 10s of seconds since the user
X    caused an event in this application.  
X    Note that the StripChart requires a return value.
X*/
X
Xstatic void MyTimeSinceTouchedCB( widget, ignored, value_ptr )
X    Widget  widget;
X    caddr_t ignored;
X    double* value_ptr;
X{
X    double *value = (double *) value_ptr;
X    static double old_value = 0.0;
X    static Time old_stamp = 1;
X    Time new_stamp;
X
X    new_stamp = XtLastTimestampProcessed( XtDisplay( widget ) );
X
X    if (old_stamp != new_stamp) 
X    {
X        old_stamp = new_stamp;
X        old_value = 0.0;
X    }
X    else 
X    {
X        Arg args[1];
X        int update;
X
X        XtSetArg(args[0], XtNupdate, &update);
X        XtGetValues(widget, args, 1);
X        old_value += (double) update / 10.0;
X    }
X
X    *value = old_value;
X}
X
X/*
X    -- MyCountCB  Tied to button, increments counter and displays.
X******************************************************************************
X   The argument is interpreted as a widget which must be a label.
X   The count, after being incremented, is displayed in this label
X   widget.  (Actually, it may be anything derived from Label).
X*/
X
Xstatic void MyCountCB( widget, widgetName, ignored )
X    Widget  widget;
X    char*   widgetName;
X    caddr_t ignored;
X{
X    Arg arg[1];
X    char text[10];
X    static int count = 0;
X
X    sprintf( text, " %d ", ++count );
X    XtSetArg( arg[0], XtNlabel, text );
X    XtSetValues( WcFullNameToWidget( widget, widgetName ), arg, 1 );
X}
X
X/*
X    -- MyThumbedCB  Tied to scrollbar's jumpProc
X******************************************************************************
X    Prints location of the thumb as a percentage of the height of the
X    scrollbar into the labe widget named by the widgetName argument.
X*/
X
Xstatic void MyThumbedCB( widget, widgetName, top_ptr )
X    Widget  widget;
X    char*   widgetName;	/* string from resource database (resource file) */
X    float*  top_ptr;	/* scrollbar callback call data:  a pointer to a float
X			** containing the location of the scrollbar's thumb.
X			*/
X{
X    Widget label = WcFullNameToWidget( widget, widgetName );
X    Arg args[1];
X    char message[BUFSIZ];
X
X    sprintf( message, " Thumbed to %d%% ", (int)((*top_ptr)*100) );
X    XtSetArg( args[0], XtNlabel, message );
X    XtSetValues( label, args, 1 );
X}
X
X/*
X    -- MyScrolledCB  Tied to scrollbar's scrollProc
X******************************************************************************
X    Prints location of the pointer into the named label widget.
X*/
X
Xstatic void MyScrolledCB( widget, widgetName, num_pixels )
X    Widget  widget;
X    char*   widgetName; /* string from resource database (resource file) */
X    int*    num_pixels;	/* scrollbar callback call data:  the number of
X			** pixels the bar has been scrolled.
X			*/
X{
X    Widget label = WcFullNameToWidget( widget, widgetName );
X    Arg args[1];
X    char message[BUFSIZ];
X
X    sprintf( message, " Scrolled at %d pixels", num_pixels);
X    XtSetArg( args[0], XtNlabel, message );
X    XtSetValues( label, args, 1 );
X}
X
X/*
X    -- MyDestroyedCB  Destroy callback of application shell
X******************************************************************************
X    This is a Destroy callback that prints the name of the destroyed widget.
X*/
X
Xstatic void MyDestroyedCB( widget, client, unused )
X    Widget widget;
X    char*  client;	/* as registered or from resource database */
X    caddr_t unused;
X{
X    fprintf( stderr, "%s : Widget %s now destroyed.\n", 
X	client, WcWidgetToFullName(widget));
X}
X
X/*
X    -- RegisterApplicationCallbacks
X******************************************************************************
X    Register all the callbacks which define the application's behaviors.
X*/
X
Xstatic void RegisterApplicationCallbacks ( app )
X    XtAppContext app;
X{
X#define RCALL(name, func, client) WcRegisterCallback(app, name, func, client)
X
X    RCALL( "MyOkayCB",			MyOkayCB,		NULL	  );
X    RCALL( "MyQuitCB",			MyQuitCB,		NULL	  );
X    RCALL( "MyTimeSinceTouchedCB",	MyTimeSinceTouchedCB,	NULL	  );
X    RCALL( "MyCountCB",			MyCountCB,		NULL	  );
X    RCALL( "MyThumbedCB",		MyThumbedCB,		NULL	  );
X    RCALL( "MyScrolledCB",		MyScrolledCB,		"Scroll"  );
X    RCALL( "MyDestroyedCB",		MyDestroyedCB,		"Destroy" );
X}
X
X/******************************************************************************
X*   MAIN function
X******************************************************************************/
X
Xmain ( argc, argv )
X    int argc;
X    char* argv[];
X{   
X    char*        appClass;
X    XtAppContext app;
X    Widget       appShell;
X
X    appClass = (char*) XtMalloc ( strlen ( argv[0] ) + 1 );
X    strcpy (appClass, argv[0]);
X    /* initialize first letter to make class, or first two if
X    ** first is already capitalized, or don't worry about it.
X    */
X    if (islower(appClass[0]))
X	appClass[0] = toupper(appClass[0]);
X    else if (islower(appClass[1]))
X        appClass[1] = toupper(appClass[1]);
X    
X    /* With the Athena widgets, we MUST register the Wc
X    ** converters first, so WcCvtStringToWidget is invoked
X    ** instead of the far less useful XmuCvtStringToWidget.
X    */
X    WcAddConverters(NULL);
X
X    /*  -- Intialize Toolkit creating the application shell */
X    appShell = XtInitialize ( 
X	argv[0], appClass,		/* app name and class */
X	NULL, 0, 			/* description of cmd line options */
X	&argc, argv 
X    );
X    app = XtWidgetToApplicationContext(appShell);
X
X    /*  -- Register all application specific callbacks and widget classes */
X    RegisterApplicationCallbacks ( app );
X
X    /*  -- Register all Athena widget classes */
X    AriRegisterAthena ( app );
X
X    /*  -- Create widget tree below toplevel shell using Xrm database */
X    WcWidgetCreation ( appShell );
X
X    /*  -- Realize the widget tree and enter the main application loop */
X    XtRealizeWidget ( appShell );
X    XtMainLoop ( );
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        9941 Oct  9 17:05 App.c    (as sent)'
chmod u=rw,g=r,o=r App.c
ls -l App.c
echo x - App1.All
sed 's/^X//' > App1.All <<'+FUNKY+STUFF+'
X#ifdef Xrm_COMMENT
X----------------------------------------------------------------------
X
XThis demos is intended to show something about every single
XAthena widget.  At least one of each is instantiated.  This
Xexample is derived from xwidgets.c in X11R4/examples/Xaw
X
XNote that we do not bind the destroy callback to the application
Xshell.  This is because the Wc converters are not registered yet
Xwhen the application shell is created by XtInitialize.  We get
Xfunctionally identical results by binding the destroyCallback of
Xthe application shell's only child.
X
XThere is nothing which prevents the Wc converters from being
Xregistered early, except that most programmers would rather take
Xadvantage of XtInitialize() rather than programming an equivalent
Xsequence of Xt... calls themselves.
X
X----------------------------------------------------------------------
X#endif
X
X# Think of these as fallback resources
X#
X
X*input:                  True
X
XApp.wcChildren:		paned
XApp.title:		App using App1.All
X
XApp*label.destroyCallback: MyDestroyedCB(Gone)
XApp.paned.quit.destroyCallback: MyDestroyedCB()
XApp.paned.dialog.destroyCallback: MyDestroyedCB
X#
X# Most of the widgets are children of the paned window.
X#
X
X*paned.wcClass:		panedWidgetClass
X*paned.wcChildren:	quit, label, dialog, viewport, form, \
X			box, stripChart, text, box2, textFile
X*Paned.width:           350
X
X*quit.wcClass:		commandWidgetClass
X*quit.callback:		MyQuitCB( App )
X*quit.font:		-*-courier-bold-r-*-240-*
X
X*label.wcClass:		labelWidgetClass
X*label.label:           At least one of each Athena Widget.
X*label.font:		*lucida-bold-i-*-240-*
X
X#
X# A Dialog with an Ok button which changes the list
X# contents when pressed via the MyOkayCB() callback.
X#
X
X*dialog.wcClass:	dialogWidgetClass
X*dialog.wcChildren:	command
X*Dialog*Font:		*times-bold-i-*-180-*
X*Dialog.label:          I am a Dialog widget.
X*Dialog.label.font:	*new century schoolbook-bold-r-*-180-*
X*Dialog.value:          Enter new value here.
X*Dialog*resizable:      True
X
X*Dialog.command.wcClass:	commandWidgetClass
X*Dialog*command*label:		ok
X*Dialog*command*callback:	MyOkayCB( *list )
X
X#
X# A Viewport with a List child
X#
X
X*viewport.wcClass:	viewportWidgetClass
X*viewport.wcChildren:	list
X*Viewport*allowVert:	True
X
X*list.wcClass:		listWidgetClass
X*list*Font:		*new century schoolbook-bold-i-*-140-*
X
X#
X# Create a Form with Buttons Including a MenuButton with Menu
X#
X
X#*form*wcTrace:		True
X
X*form.wcClass:		formWidgetClass
X*form.wcChildren:	formLabel, command, toggle, menuButton, menu
X*Form*resizable:	True
X*form*Font:		*lucidabright-demibold-*-180-*
X
X*form.formLabel.wcClass:	labelWidgetClass
X*Form*formLabel.label:		0
X
X*form.command.wcClass:		commandWidgetClass
X*form.command.fromHoriz:	*formLabel
X*form.command.callback:		MyCountCB( *formLabel )
X
X*form.toggle.wcClass:		toggleWidgetClass
X*form.toggle.fromHoriz:		*form.command
X*form.toggle.callback:		MyCountCB( *formLabel )
X
X*form.menuButton.wcClass:	menuButtonWidgetClass
X*form.menuButton.fromHoriz:	*form.toggle
X
X*menu.wcClass:			simpleMenuWidgetClass
X*menu.wcManaged:		False
X*menu.wcChildren:		menuEntry1, menuEntry2, menuLine, \
X				menuEntry3, menuEntry4, menuEntry5
X
X*menuEntry1.wcClass:	smeBSBObjectClass
X*menuEntry2.wcClass:	smeBSBObjectClass
X*menuEntry3.wcClass:	smeBSBObjectClass
X*menuEntry4.wcClass:	smeBSBObjectClass
X*menuEntry5.wcClass:	smeBSBObjectClass
X*menuLine.wcClass:	smeLineObjectClass
X
X#
X# Create a box with a clock and a logo.
X#
X
X*Box*allowResize:        True
X*box.wcClass:		boxWidgetClass
X*box.wcChildren:	clock, logo
X
X*clock.wcClass:		clockWidgetClass
X*logo.wcClass:		logoWidgetClass
X
X#
X# Create a Box widget with a label and a scrollbar.
X#
X
X*box2.wcClass:		boxWidgetClass
X*box2.wcChildren:	scrollbar, scroll_label
X
X*scrollbar.wcClass:	scrollbarWidgetClass
X*scrollbar.jumpProc:	MyThumbedCB(*scroll_label)
X*scrollbar.scrollProc:	MyScrolledCB(*scroll_label)
X*scrollbar*orientation:  horizontal
X*scrollbar*length:       100
X
X*scroll_label.wcClass:	labelWidgetClass
X*scroll_label.Font:	*-charter-bold-i-*-180-*
X
X#
X# Create a strip chart  Note that we
X# need to exit, not destroy, with SriptCharts,
X# because there is a bug in StripChart`DestroyGC.
X#
X
X*stripChart.wcClass:	stripChartWidgetClass
X*stripChart.getValue:	MyTimeSinceTouchedCB
X*StripChart*update:      1
X*StripChart*jumpScroll:  1
X*StripChart.destroyCallback: WcExitCB
X
X#
X# Text widget
X#
X
X*text.wcClass:		asciiTextWidgetClass
X*text*height:            75
X*text*string:            Look ma, a text widget!
X*text*editType:          edit
X*text*scrollVertical:    whenNeeded
X*text*scrollHorizonal:   whenNeeded
X*text*Font:		 *-lucidatypewriter-bold-r-*-190-*
X
X#
X# Text widget tied to a file
X#
X
X*textFile.wcClass:	asciiTextWidgetClass
X*textFile*type:          file
X*textFile*string:        /etc/motd
X*textFile*scrollVertical:    whenNeeded
X*textFile*scrollHorizonal:   whenNeeded
X*textFile*height:        75
X*textFile*Font:          *clean-medium-r-*-150-*
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        4911 Oct  9 16:42 App1.All    (as sent)'
chmod u=rw,g=r,o=r App1.All
ls -l App1.All
echo x - Ari.c
sed 's/^X//' > Ari.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**
X** SCCS_data: @(#)Ari.c 1.0 ( 19 June 1990 )
X**
X** Description:	This file contains main() for a Athena Resource Interpreter
X**		which allows prototype interfaces to be built from
X**		resource files.  The Widget Creation library is used.
X**
X**              Besides the Athena widgets, Ari also knows about Table
X**              widgets, simply because they are so dang useful!
X**
X** Notes:	This program uses the Xrm (X resource management) database
X**		for widget tree definition and management.  This program
X**		is dependent on the Athena widget set only because the
X**		Athena classes and constructors are registered, which
X**		causes the Athena libs to be linked in.  Someday I'll
X**		get a shared lib version of Motif and the Athena widgets,
X**		and even the OpenLook widget set, and then there will
X**		be no reason that widgets could not be mixed and matched.
X**		Doing that without shared libs makes for a HUGE executable.
X**
X******************************************************************************/
X
X/******************************************************************************
X**   Include_files.
X******************************************************************************/
X
X#include <X11/Intrinsic.h>
X#include <ctype.h>
X#include <WcCreate.h>
X
X#include <Table.h>
X
X/******************************************************************************
X**  Private Functions
X******************************************************************************/
X
Xextern void AriRegisterAthena ();
X
Xstatic void RegisterTable ( app )
X    XtAppContext app;
X{
X#define RCN( name, class ) WcRegisterClassName ( app, name, class );
X#define RCP( name, class ) WcRegisterClassPtr  ( app, name, class );
X
X    RCN( "Table",		tableWidgetClass );
X    RCP( "tableWidgetClass",	tableWidgetClass );
X
X#undef  RCN
X#undef  RCP
X}
X
X/******************************************************************************
X*   MAIN function
X******************************************************************************/
X
Xmain ( argc, argv )
X    int   argc;
X    char* argv[];
X{   
X    char*        appClass;
X    XtAppContext app;
X    Widget       appShell;
X
X    appClass = (char*) XtMalloc ( strlen ( argv[0] ) + 1 );
X    strcpy (appClass, argv[0]);
X    /* initialize first letter to make class, or first two if
X    ** first is already capitalized, or don't worry about it.
X    */
X    if (islower(appClass[0]))
X	appClass[0] = toupper(appClass[0]);
X    else if (islower(appClass[1]))
X        appClass[1] = toupper(appClass[1]);
X    
X    /*  -- Intialize Toolkit creating the application shell */
X    appShell = XtInitialize ( 
X	argv[0], appClass,		/* app name and class */
X	NULL, 0, 			/* description of cmd line options */
X	&argc, argv 
X    );
X    app = XtWidgetToApplicationContext(appShell);
X
X    /*  -- Register all application specific callbacks and widget classes */
X    RegisterTable ( app );
X
X    /*  -- Register all Athena widget classes */
X    AriRegisterAthena ( app );
X
X    /*  -- Create widget tree below toplevel shell using Xrm database */
X    WcWidgetCreation ( appShell );
X
X    /*  -- Realize the widget tree and enter the main application loop */
X    XtRealizeWidget ( appShell );
X    XtMainLoop ( );
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        4022 Aug  6 09:36 Ari.c    (as sent)'
chmod u=rw,g=r,o=r Ari.c
ls -l Ari.c
echo x - AriRegAll.c
sed 's/^X//' > AriRegAll.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: @(#)AriRegAll.c 1.0 ( 19 June 1990 )
X*
X* Subsystem_group:
X*
X*     Widget Creation Library - Athena Resource Interpreter
X*
X* Module_description:
X*
X*     This module contains registration routine for all Athena
X*     widget constructors and classes.  
X*
X* Module_interface_summary: 
X*
X*     void AriRegisterAthena ( 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/Xatom.h>
X#include <X11/Intrinsic.h>
X#include <X11/StringDefs.h>
X
X#include <X11/Xaw/AsciiText.h>
X#include <X11/Xaw/Box.h>
X#include <X11/Xaw/Clock.h>
X#include <X11/Xaw/Command.h>
X#include <X11/Xaw/Dialog.h>
X#include <X11/Xaw/Form.h>
X#include <X11/Xaw/Grip.h>
X#include <X11/Xaw/Label.h>
X#include <X11/Xaw/List.h>
X#include <X11/Xaw/Logo.h>
X#include <X11/Xaw/MenuButton.h>
X#include <X11/Xaw/Scrollbar.h>
X#include <X11/Xaw/SimpleMenu.h>
X#include <X11/Xaw/SmeBSB.h>
X#include <X11/Xaw/SmeLine.h>
X#include <X11/Xaw/StripChart.h>
X#include <X11/Xaw/Paned.h>
X#include <X11/Xaw/Toggle.h>
X#include <X11/Xaw/Viewport.h>
X
X#include <X11/Xaw/Cardinals.h>
X
Xvoid AriRegisterAthena ( 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
X    /* -- register all Athena widget classes */
X    /* Simple Widgets (Chapt 3) */
X    RCN("Command",			commandWidgetClass	);
X    RCP("commandWidgetClass",		commandWidgetClass	);
X    RCN("Grip",				gripWidgetClass		);
X    RCP("gripWidgetClass",		gripWidgetClass		);
X    RCN("Label",			labelWidgetClass	);
X    RCP("labelWidgetClass",		labelWidgetClass	);
X    RCN("List",				listWidgetClass		);
X    RCP("listWidgetClass",		listWidgetClass		);
X    RCN("Scrollbar",			scrollbarWidgetClass	);
X    RCP("scrollbarWidgetClass",		scrollbarWidgetClass	);
X    RCN("Simple",			simpleWidgetClass	);
X    RCP("simpleWidgetClass",		simpleWidgetClass	);
X    RCN("StripChart",			stripChartWidgetClass	);
X    RCP("stripChartWidgetClass",	stripChartWidgetClass	);
X    RCN("Toggle",			toggleWidgetClass	);
X    RCP("toggleWidgetClass",		toggleWidgetClass	);
X
X    /* Menus (Chapt 4) */
X    RCN("SimpleMenu",			simpleMenuWidgetClass	);
X    RCP("simpleMenuWidgetClass",	simpleMenuWidgetClass	);
X    RCN("SmeBSB",			smeBSBObjectClass	);
X    RCP("smeBSBObjectClass",		smeBSBObjectClass	);
X    RCN("SmeLine",			smeLineObjectClass	);
X    RCP("smeLineObjectClass",		smeLineObjectClass	);
X    RCN("Sme",				smeObjectClass		);
X    RCP("smeObjectClass",		smeObjectClass		);
X    RCN("MenuButton",			menuButtonWidgetClass	);
X    RCP("menuButtonWidgetClass",	menuButtonWidgetClass	);
X
X    /* Text Widgets (Chapt 5) */
X    RCN("AsciiText",			asciiTextWidgetClass	); /* NB name */
X    RCP("asciiTextWidgetClass",		asciiTextWidgetClass	);
X    RCN("AsciiSrc",			asciiSrcObjectClass	);
X    RCP("asciiSrcObjectClass",		asciiSrcObjectClass	);
X    RCN("AsciiSink",			asciiSinkObjectClass	);
X    RCP("asciiSinkObjectClass",		asciiSinkObjectClass	);
X    RCN("Text",				textWidgetClass		);
X    RCP("textWidgetClass",		textWidgetClass		);
X
X    /* Composite and Constraint Widgets (Chapt 6) */
X    RCN("Box",				boxWidgetClass		);
X    RCP("boxWidgetClass",		boxWidgetClass		);
X    RCN("Dialog",			dialogWidgetClass	);
X    RCP("dialogWidgetClass",		dialogWidgetClass	);
X    RCN("Form",				formWidgetClass		);
X    RCP("formWidgetClass",		formWidgetClass		);
X    RCN("Paned",			panedWidgetClass	);
X    RCP("panedWidgetClass",		panedWidgetClass	);
X    RCN("Viewport",			viewportWidgetClass	);
X    RCP("viewportWidgetClass",		viewportWidgetClass	);
X
X    /* Other Interestng Widgets (not in ref manual) */
X    RCN("ClockWidget",			clockWidgetClass	);
X    RCP("clockWidgetClass",		clockWidgetClass	);
X    RCN("LogoWidget",			logoWidgetClass		);
X    RCP("logoWidgetClass",		logoWidgetClass		);
X
X#undef RCN
X#undef RCP
X}
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        5023 Aug  6 09:36 AriRegAll.c    (as sent)'
chmod u=rw,g=r,o=r AriRegAll.c
ls -l AriRegAll.c
echo x - COPY
sed 's/^X//' > COPY <<'+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*/
+FUNKY+STUFF+
echo '-rw-r--r--  1 david         746 Aug  6 09:36 COPY    (as sent)'
chmod u=rw,g=r,o=r COPY
ls -l COPY
echo x - COPY_DERIVED
sed 's/^X//' > COPY_DERIVED <<'+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*/
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        2102 Aug  6 09:36 COPY_DERIVED    (as sent)'
chmod u=rw,g=r,o=r COPY_DERIVED
ls -l COPY_DERIVED
echo x - Imakefile
sed 's/^X//' > Imakefile <<'+FUNKY+STUFF+'
X# Assumes that your Imake site.cf defines -DHAVE_MOTIF if you have motif.
X# Otherwise, you will have to add a line which says:
X#	#define HAVE_MOTIF
X#
X# Note how Motif version numbers are defined: Motif 1.1 or Motif 1.1.1
X# is defined:
X#	MOTIF_VER = -DMOTIF=1 -DMOTIF_MINOR=1
X# and when Motif 2.7 comes out, MOTIF_VER gets define as:
X#	MOTIF_VER = -DMOTIF=2 -DMOTIF_MINOR=7
X#
X# If your C compiler does not know how to use prototypes, you may
X# need to add -D_NO_PROTO to the MOTIF_VER macros.  This may be
X# needed because many sites do not put Motif specific defines
X# in their site.cf files used by Imake.
X#
X# Some Table.c and Table_m.c both include Xmu.h.  If you are using
X# Motif 1.0 and you have installed the X11R4 Xmu libraries, then
X# you musr provide the XT_VER macro as shown.  In all other cases,
X# I think that the XT_VER macro is not needed.
X#
X# Also, if you have Motif installed in a non-standard place, set MOTIFDIR to
X# point to it.  The value of MOTIFDIR gets pre-pended to /include and /lib.
X#
X# Motif 1.0 required a special Xt Intrinsics, commonly named libXtm.  If
X# you are building for 1.0, MOTIFLIB should be -lXtm
X
X#
X# typical for Motif 1.0
X#
X      MOTIF_VER = -DMOTIF=1 -DMOTIF_MINOR=0 
X         XT_VER = -DXtSpecificationRelease=4
X       MOTIFDIR = /usr
X        MOTIFXT = -lXtm
X     MOTIFXTLIB = $(MOTIFDIR)/lib/libXtm.a
X
X#
X# typical for Motif 1.1:
X#
X#     MOTIF_VER = -DMOTIF=1 -DMOTIF_MINOR=1 -D_NO_PROTO
X#      MOTIFDIR = /usr
X#       MOTIFXT = -lXt
X#    MOTIFXTLIB = $(MOTIFDIR)/lib/libXt.a
X
X  IMAKE_DEFINES = -DHAVE_MOTIF
X
X        SYSLIBS = -lm
X  INSTALLLIBDIR = UsrLibDir
X  INSTALLINCDIR = $(INCDIR)/Wc
X
X          WCLIB = -L. -lWc
X       DEPWCLIB = ./libWc.a
X
X         WCMLIB = -L. -lWcm
X      DEPWCMLIB = ./libWcm.a
X
X   STD_INCLUDES = -I.
X    CDEBUGFLAGS = -g -Bstatic -DDEBUG
X
XAllTarget(libWc.a App Ari MDathena libWcm.a Mri MDmotif)
X
X#
X# Rules for App
X#
X
X       APP_LIBS = $(WCLIB) XawClientLibs
X    APP_DEPLIBS = $(DEPWCLIB) XawClientDepLibs
X
X       APP_OBJS = App.o AriRegAll.o
X
XNormalProgramTarget(App, $(APP_OBJS), $(APP_DEPLIBS), $(APP_LIBS), $(SYSLIBS))
X
X#
X# Rules for MDathena
X#
X
XMDA_OBJS = MDathena.o AriRegAll.o Table.o
X
XMDathena.o: MD.c
X	$(RM) $@
X	$(CC) -c $(CFLAGS) MD.c -o MDathena.o
X
XNormalProgramTarget(MDathena, $(MDA_OBJS), $(APP_DEPLIBS), \
X				$(APP_LIBS), $(SYSLIBS))
X
X#
X# Rules for Ari
X#
X
X       ARI_LIBS = $(WCLIB) XawClientLibs
X    ARI_DEPLIBS = $(DEPWCLIB) XawClientDepLibs
X
X       ARI_OBJS = Ari.o AriRegAll.o Table.o
X
XNormalProgramTarget(Ari, $(ARI_OBJS), $(ARI_DEPLIBS), $(ARI_LIBS), $(SYSLIBS))
X
X#
X# Rules for libWc.a
X#
X
X     LIBWC_INCS = WcCreate.h WcCreateP.h
X     LIBWC_OBJS = WcCreate.o WcCallb.o WcConvert.o WcName.o \
X		  WcReg.o WcActions.o WcRegXt.o
X
XNormalLibraryObjectRule()
X
XNormalLibraryTarget(Wc, $(LIBWC_OBJS))
XMakeDirectories(install, $(INSTALLIBDIR))
XInstallLibrary(Wc, $(INSTALLLIBDIR))
XMakeDirectories(install, $(INSTALLINCDIR))
XInstallMultiple($(LIBWC_INCS), $(INSTALLINCDIR))
X
X###############################################################################
X#ifdef HAVE_MOTIF
X###############################################################################
X# Note that Motif doesn't provide Xmu, so pick it up from R4
X#
X# Rules for Mri
X#
X
X       MRI_LIBS = $(WCMLIB) $(MOTIFLIB) 
X    MRI_DEPLIBS = $(DEPWCMLIB) $(DEPMOTIFLIB) 
X
X       MOTIFLIB = -L$(MOTIFDIR)/lib -lXm $(MOTIFXT) $(XLIB)
X    DEPMOTIFLIB = $(MOTIFDIR)/lib/libXm.a $(MOTIFXTLIB) $(DEPXLIB)
X
X       MRI_OBJS = Mri.o MriRegAll.o Table_m.o
X   MRI_INCLUDES = -I$(MOTIFDIR)/include/Xm -I$(MOTIFDIR)/include
X
X    MRI_DEFINES = $(MOTIF_VER) $(MRI_INCLUDES)
X
XTable_m.o: Table_m.c
X	$(RM) $@
X	$(CC) -c $(XT_VER) $(MRI_DEFINES) $(CFLAGS) $*.c
XMri.o: Mri.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) $*.c
XMriRegAll.o: MriRegAll.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) $*.c
X
XNormalProgramTarget(Mri, $(MRI_OBJS), $(MRI_DEPLIBS), $(MRI_LIBS), $(SYSLIBS))
X
X#
X# Rules for MDmotif
X#
X
XMDM_OBJS = MDmotif.o MriRegAll.o Table_m.o
X
XMDmotif.o: MD.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) MD.c -o MDmotif.o
X
XNormalProgramTarget(MDmotif, $(MDM_OBJS), $(MRI_DEPLIBS), \
X				$(MRI_LIBS), $(SYSLIBS))
X
X
XMDM_OBJS = MDmotif.o MriRegAll.o Table_m.o
X#
X# Rules for libWcm.a
X#
X
X    LIBWCM_OBJS = WcmCreate.o WcmCallb.o WcmConvert.o \
X		  WcmName.o WcmReg.o WcmActions.o WcmRegXt.o
X
XWcmCreate.o: WcCreate.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) WcCreate.c  -o WcmCreate.o
XWcmCallb.o: WcCallb.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) WcCallb.c   -o WcmCallb.o
XWcmConvert.o: WcConvert.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) WcConvert.c -o WcmConvert.o
XWcmName.o: WcName.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) WcName.c    -o WcmName.o
XWcmReg.o: WcReg.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) WcReg.c     -o WcmReg.o
XWcmActions.o: WcActions.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) WcActions.c -o WcmActions.o
XWcmRegXt.o: WcRegXt.c
X	$(RM) $@
X	$(CC) -c $(MRI_DEFINES) $(CFLAGS) WcRegXt.c   -o WcmRegXt.o
X
XNormalLibraryTarget(Wcm, $(LIBWCM_OBJS))
XInstallLibrary(Wcm, $(INSTALLLIBDIR))
X
X#endif
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        5054 Oct 18 16:44 Imakefile    (as sent)'
chmod u=rw,g=r,o=r Imakefile
ls -l Imakefile
echo x - M1.Hello
sed 's/^X//' > M1.Hello <<'+FUNKY+STUFF+'
X  This resource file represents a very basic application: a single
X  button which, when pressed, causes the application to exit.
X
XMri.wcChildren:		push
X
X*push.wcClass:		xmPushButtonWidgetClass
X*push.labelString:	Hello World
X*push.activateCallback:	WcExitCB
+FUNKY+STUFF+
echo '-rw-r--r--  1 david         257 Aug  6 09:36 M1.Hello    (as sent)'
chmod u=rw,g=r,o=r M1.Hello
ls -l M1.Hello
echo x - M2.Goodbye
sed 's/^X//' > M2.Goodbye <<'+FUNKY+STUFF+'
X  This resource file represents a very basic application: a single button
X  which changes its own behavior and label.  The first time it is
X  pressed, it changes its label and its activate callback.  Subsequent
X  presses cause a confirmation dialog to pop-up.
X
X  This example uses WcSetValueCB().  The argument looks exactly like a
X  resource specification.  The WcSetValueCB() callback actually does an
X  XtSetValue to set the value in the target (named) widget.
X
X  This example also uses WcManageCB().  The argument is the name of a
X  widget.  Wildcards work in names exactly as in resource
X  specifications.  The name resoultion search begins at the root widget.
X
X  Note that if there are multiple callbacks being invoked in a callback
X  list, as in the button's activateCallback resource below, then each
X  specification is separated by a comma.  In the below example, the
X  specifications are also put on separate lines (the `\' escapes the
X  newline in resource files just like in C), with additional whitepspace
X  (tabs and blanks) for stylistic reasons.
X
X  Note also that the dialog is created using one of the Motif
X  constructors, and the constructor introduces a dialogShell.  Since we
X  want the button to manage the child of the shell, not simply the shell,
X  we must use the seemingly redundant specification:
X
X	*push.activateCallback: WcManageCB( *exitDialog.exitDialog )
X
X  If we had used the more intuitive but wrong:
X
X	*push.activateCallback: WcManageCB( *exitDialog )
X
X  then a small, empty dialog shell would appear at the upper left corner
X  of the display.  This is a VERY common mistake made by Mri beginners.
X
X  Finally, note that the dialog is created unmanaged.  If you forget to
X  do this, the dialog will show up in the upper left corner of the screen
X  at start-up.  This is another VERY common mistake made by Mri
X  beginners.
X
XMri.wcChildren:		exitDialog, push
XMri.title:		Mri using M2.Goodbye
X
X*exitDialog.wcConstructor:	XmCreateQuestionDialog
X*exitDialog.wcManaged:		False
X*exitDialog.messageString:	Do you really want to exit?
X*exitDialog.okCallback:		WcExitCB(1)
X
X*push.wcClass:		xmPushButtonWidgetClass
X*push.labelString:	Hello World, I'm Mri.  Please Push Me!
X*push.activateCallback: WcSetValueCB( *push.activateCallback: \
X					WcManageCB( *exitDialog.exitDialog )),\
X			WcSetValueCB( *push.labelString:      Goodbye! )
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        2358 Aug  6 09:36 M2.Goodbye    (as sent)'
chmod u=rw,g=r,o=r M2.Goodbye
ls -l M2.Goodbye
echo x - M3.Menubar
sed 's/^X//' > M3.Menubar <<'+FUNKY+STUFF+'
X  Ordering
X  --------
X
X  The order of the lines in the resource file are completely stylistic: a
X  matter of taste.  The ordering is lost when the resources are loaded
X  into the Xrm database, and the Widget Creation library works only from
X  the database, not directy from the resource files.
X
X  Note that the ordering of the names within the wcChildren resources is
X  significant: it is the order the children will be created, from left to
X  right, depth first.  One needs to consider this in several cases:
X  pulldown menus are a good example.
X
X  Pulldown Menus
X  --------------
X
X  The pulldowns can be created before or after their activating cascade
X  button: as an example, lets look at the difference between the
X  menuBar.file and menuBar.fileMenu specifications versus the
X  menuBar.help and menuBar.helpMenu specifications.  
X
X  The *menuBar.wcChildren resource specifies that the first of its
X  children to be created is `file' (which has no children), then
X  `fileMenu' and all its children, then `helpMenu' and all its children,
X  and finally `help'.
X
X    *menuBar.wcChildren:	file, fileMenu, helpMenu, help
X
X  The `fileMenu', being created after the `file' cascade, sets the subMenuId
X  resource on the `file' cascade when it is created:
X
X    *fileMenu.wcCallback:	WcSetValueCB(*file.subMenuId: this)
X
X  The `help' cascade is created after the `helpMenu', so it can specify the
X  `helpMenu' as its subMenuId directly:
X
X    *help.subMenuId:		*helpMenu
X
X  Note that the pulldown menus must be explicitly NOT managed when they 
X  are created. They are automagically managed by the cascade buttons.  
X
X  Note also that the separator types are NOT XmSHADOW_ETCHED_IN and
X  XmDOUBLE_DASHED_LINE as one might guess from Motif documents, but
X  instead one must leave the Xm off the front.  Motif 1.1 is supposed to
X  support both spellings, so XmSHADOW_ETCHED_IN and SHADOW_ETCHED_IN will
X  work eventually.  Also, the values are case insensitive.
X
X  Multiple Level Cascading Menus
X  ------------------------------
X
X  The saveAsMenu pulldown connected to the saveAs button demonstrates 
X  this.  See the discussion below.
X
X----------------------------------------------------------------------
X#endif
X
X#*wcTrace:		True
X
XMri.wcChildren:		menuBar
XMri.title:		Mri using M3.Menubar
X
X*menuBar.wcConstructor:	XmCreateMenuBar
X*menuBar.wcChildren:	file, fileMenu, helpMenu, help
X
X*file.wcConstructor:	XmCreateCascadeButton
X*file.labelString:	File Pulldown Menu
X*file.mnemonic:		F
X
X*fileMenu.wcConstructor: XmCreatePulldownMenu
X*fileMenu.wcManaged:	 False
X*fileMenu.wcCallback:	 WcSetValueCB(*file.subMenuId: this)
X*fileMenu.wcChildren:    load, sep1, save, saveAsMenu, saveAs, sep2, quit
X
X*helpMenu.wcConstructor: XmCreatePulldownMenu
X*helpMenu.wcManaged:	 False
X*helpMenu.wcChildren:    mbHelp, cpHelp, daHelp, tHelp
X
X*helpMenu.mbHelp.wcConstructor:	XmCreateCascadeButton
X*helpMenu.mbHelp.labelString:	on Menu Bar
X*helpMenu.mbHelp.mnemonic:	M
X
X*helpMenu.cpHelp.wcConstructor:	XmCreateCascadeButton
X*helpMenu.cpHelp.labelString:	on Control Panel
X*helpMenu.cpHelp.mnemonic:	C
X
X*helpMenu.daHelp.wcConstructor:	XmCreateCascadeButton
X*helpMenu.daHelp.labelString:	on Drawing Area
X*helpMenu.daHelp.mnemonic:	D
X
X*helpMenu.tHelp.wcConstructor:	XmCreateCascadeButton
X*helpMenu.tHelp.labelString:	on Text Area
X*helpMenu.tHelp.mnemonic:	T
X
X*help.wcConstructor:	XmCreateCascadeButton
X*help.subMenuId:	*helpMenu
X*help.labelString:	Help Pulldown Menu
X*help.mnemonic:		H
X
X*load.wcConstructor:	XmCreateCascadeButton
X*load.labelString:	Load ...
X*load.mnemonic:		L
X
X*sep1.wcConstructor:	XmCreateSeparator
X*sep1.separatorType:	Shadow_Etched_In
X
X*save.wcConstructor:	XmCreateCascadeButton
X*save.labelString:	Save
X*save.mnemonic:		S
X
X#
X# The saveAsMenu has already been created. 
X# It is specified at the bottom of this file.
X#
X*saveAs.wcConstructor:	XmCreateCascadeButton
X*saveAs.labelString:	Save As
X*saveAs.mnemonic:	A
X*saveAs.subMenuId:	*saveAsMenu
X
X*sep2.wcConstructor:	XmCreateSeparator
X*sep2.separatorType:	DOUBLE_DASHED_LINE
X
X*quit.wcConstructor:	XmCreateCascadeButton
X*quit.labelString:	Quit
X*quit.mnemonic:		Q
X*quit.activateCallback:	WcExitCB
X
X  ----------------------------------------------------------------------
X
X  More on Callback Functions
X  --------------------------
X
X  One does not strictly need to specify any arguments to callbacks, nor
X  the parenthesis.  For example:
X
X    *quit.activateCallback:     WcExitCB
X
X  In this situation, a NULL string is passed to the callback function as
X  client data.  WcExitCB invokes exit(0) when it gets a NULL argument.
X
X  It is up to the callback to decide the appropriate action when a NULL
X  string is received as client data.  The Wc library does guarantee that
X  the callback will receive a NULL string (the first character is a
X  '\0'), and not a null pointer (pointer == 0).
X
X  Multiple Level Cascading Menus
X  ------------------------------
X
X  ----------------------------------------------------------------------
X
X# All of the nested menus in this example have two buttons:
X# Go and More to come.  Note that we must be specific about
X# which pulldown menu gets tied to each one!
X#
X
X*go.wcConstructor:	XmCreateCascadeButton
X*go.labelString:	Go
X
X*more.wcConstructor:	XmCreateCascadeButton
X*more.labelString:	More to come
X
X*saveAsMenu.wcConstructor:	XmCreatePulldownMenu
X*saveAsMenu.wcManaged:		False
X*saveAsMenu.wcChildren:		level3, go, more
X*saveAsMenu.more.subMenuId:	*level3
X
X*level3.wcConstructor:	XmCreatePulldownMenu
X*level3.wcManaged:	False
X*level3.wcChildren:	level4, go, more
X*level3.more.subMenuId:	*level4
X
X*level4.wcConstructor:	XmCreatePulldownMenu
X*level4.wcManaged:	False
X*level4.wcChildren:	level5, go, more
X*level4.more.subMenuId:	*level5
X
X*level5.wcConstructor:	XmCreatePulldownMenu
X*level5.wcManaged:	False
X*level5.wcChildren:	level6, go, more
X*level5.more.subMenuId:	*level6
X
X*level6.wcConstructor:	XmCreatePulldownMenu
X*level6.wcManaged:	False
X*level6.wcChildren:	level7, go, more
X*level6.more.subMenuId:	*level7
X
X*level7.wcConstructor:	XmCreatePulldownMenu
X*level7.wcManaged:	False
X*level7.wcChildren:	go, more
X*level7.go.labelString:		You could go on forever like this...
X*level7.more.labelString:	But please don't!
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        6184 Aug  6 09:36 M3.Menubar    (as sent)'
chmod u=rw,g=r,o=r M3.Menubar
ls -l M3.Menubar
echo x - M4.OptMenu
sed 's/^X//' > M4.OptMenu <<'+FUNKY+STUFF+'
X  Option Menus
X  ------------
X
X  Option Menus are a topic which deserves special consideration, because
X  they are abit different from what you might expect.  As the Pulldown
X  example resource file demonstrates, one may create a cascade button
X  before or after the menu which is controlled by the cascade.  One might
X  reasonably assume that the same is true for option menus.
X
X  Unfortunately, this is an incorrect assumption.  One MUST first create
X  the pulldown menu which displays the available options, and THEN invoke
X  the convenience function XmCreateOptionMenu.  This may or may not be a
X  bug, depending on your point of view.
X
X  The widget called an OptionMenu is really a row column with two managed
X  children: a label, and a cascade.  The significant issue is the size of
X  the cascade: it is forced to be wide enough for the longest selection
X  on the pulldown menu.  One cannot after the fact set the subMenuId on
X  the cascade, because the cascade does not generally size itself based
X  on the subMenu elements: normally cascade buttons size themselves based
X  on their label.
X
X  One might assume that the RowColumn created by XmCreateOptionMenu would
X  have a special set_values() method which does the appropriate thing
X  when subMenuId is set, but this is clearly not the case: the set_values() 
X  method does something, but it certainly is not appropriate.  Expect a 
X  core dump if you try it.
X
X  So, if you want to use option menus, do it as shown in this example:
X  first create the pulldown menu using XmCreatePulldownMenu, then create
X  the `OptionMenu' using XmCreateOptionMenu.  The order of creation is
X  determined by the order of the widget names in the parent's wcChildren
X  resource:
X
X    *com.wcChildren:        doMenu, undoMenu, doOption, undoOption
X
X  Here is a trouble shooting tip: if you use XmCreateOptionMenu and the
X  cascade button's label is `<optMenName>_cascadeBtn' then you do not
X  have the subMenuId set properly on the option menu.  Check for spelling
X  on the resource name, on the resource value, and possibly use
X  `*wcTrace: True' to make sure you give the right name for the pulldown
X  menu.
X
X  Also, remember to make the menu's initially unmanaged by setting
X  wcManaged: False on each menu.  You can't do this globally,
X  unfortunately, because there is no actual Motif widget class named
X  XmPulldownMenu.  Sigh.
X
X----------------------------------------------------------------------
X
X#*wcTrace:		True
X
XMri.wcChildren:		com
XMri.title:		Mri using M4.OptMenu
X
X*com.wcClassName: XmRowColumn
X*com.wcChildren:  quit, doMenu, undoMenu, nextMenu, doOption, undoOption, next
X
X*quit.wcClassName:		XmPushButton
X*quit.labelString:		Push this button to quit the Option Menu demo
X*quit.activateCallback:		WcExitCB
X
X*doOption.wcConstructor:	XmCreateOptionMenu
X*doOption.labelString:		Do It
X*doOption.subMenuId:		*doMenu
X
X*undoOption.wcConstructor:	XmCreateOptionMenu
X*undoOption.labelString:	Undo It
X*undoOption.subMenuId:		*undoMenu
X
X*next.wcConstructor:		XmCreateOptionMenu
X*next.subMenuId:		*nextMenu
X
X*doMenu.wcConstructor:		XmCreatePulldownMenu
X*doMenu.wcManaged:		False
X*doMenu.wcChildren:		opt1, opt2
X
X*undoMenu.wcConstructor:	XmCreatePulldownMenu
X*undoMenu.wcManaged:		False
X*undoMenu.wcChildren:		opt1, opt2, opt3
X
X*nextMenu.wcConstructor:	XmCreatePulldownMenu
X*nextMenu.wcManaged:		False
X*nextMenu.wcChildren:		opt2, opt1, opt2, opt3, opt1
X
X! Note that the specification for buttons opt1 and opt2 are actually used
X! twice each: both menus have children named opt1 and opt2, so the
X! children of both menus will have these same resources, and thus, will
X! use the following resource specifications:
X
X*opt1.wcClassName:	XmPushButton
X*opt1.labelString:	Now
X
X*opt2.wcClassName:	XmPushButton
X*opt2.labelString:	Wat's the rush!!
X
X*opt3.wcClassName:	XmPushButton
X*opt3.labelString:	My Mistake...
+FUNKY+STUFF+
echo '-rw-r--r--  1 david        3848 Aug  6 09:36 M4.OptMenu    (as sent)'
chmod u=rw,g=r,o=r M4.OptMenu
ls -l M4.OptMenu
exit 0

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



More information about the Comp.sources.x mailing list