[comp.windows.x] How to Structure X programs

larryc@poe.jpl.nasa.gov (Larry Carroll) (02/28/91)

I've been reading a number of X Windows programs as part of my efforts to
learn how to program X applications.  One thing I've been trying to figure
out is how to structure C programs.  For instance, can I create a generic
'main' program that I can reuse with little or no modification?  How much 
(or little) global variables should I use, and for what?  And so on.

david@jpl-devvax.JPL.NASA.GOV (David E. Smyth) (03/01/91)

larryc@poe.jpl.nasa.gov (Larry Carroll) writes:
>I've been reading a number of X Windows programs as part of my efforts to
>learn how to program X applications.  One thing I've been trying to figure
>out is how to structure C programs.  For instance, can I create a generic
>'main' program that I can reuse with little or no modification?  How much 
>(or little) global variables should I use, and for what?  And so on.

Real easy, Larry.  First, copy Mri.c or Ari.c or (soon to be released ;^)
Ori.c into your development directory.  Those files each consist of the
main() procedures you will need.  Add into those main() proc's a call
to your application code to initialize the applications object classes
(you are using object-oriented programming, right?).  Each class should
register its callbacks with Wcl (what else!) and its action procs with Xt.
main() finishes up by calling WcWidgetCreation() to create the UI, and
XtMainLoop() to start reading events.

The rest of your application consists of event handlers in the form of
callbacks and actions.  That is it.

For example, this is the main() to one of the applications I've done:

#include <Xm/Xm.h>		/* also includes X11/Intrinsic.h */
#include <Wc/WcCreate.h>
#include <ctype.h>

main ( argc, argv )
    int argc;
    char* argv[];
{
    char* appName;
    char* appClass;

    ...		/* application specific stuff here */

    /* "appName" is the last (filename) component of argv[0] which may be a
    ** complete path.  By capitalizing the 1st character, we make the
    ** "appClass" as per Xt conventions.
    */
    for ( slash = 0, appName = argv[0] ; *appName ; appName++)
        if (*appName == '/')
            slash++;
    if (slash)
    {
        for ( ; *appName != '/' ; appName-- )
            ;
        *appName++;
    }
    else
        appName = argv[0];
    appClass  = (char*) NEW ( strlen ( appName ) + 1 );
    strcpy( appClass, appName );
    if (islower(appClass[0]))
        appClass[0] = toupper(appClass[0]);

    /*  -- Intialize Toolkit creating the application shell */
    appShell = XtInitialize (
        appName, appClass,              /* app name and class */
        NULL, 0,                        /* description of cmd line options */
        &argc, argv
    );
    app = XtWidgetToApplicationContext(appShell);

    /*  -- Register all application specific callbacks and widget classes */
    TotRegistration ( app, &argc, argv );

    /*  -- Register all Motif classes and constructors */
    XmpRegisterAll ( app );

#ifdef ATHENA
    /*  -- Register all Athena classes and constructors */
    XpRegisterAll( app );
#endif

    /*  -- Create widget tree below toplevel shell using Xrm database */
    WcWidgetCreation ( appShell );

    /*  -- Realize the widget tree and enter the main application loop */
    XtRealizeWidget ( appShell );

    XtMainLoop ( );
}

-------------------------------------------------------------------------
David Smyth				david@jpl-devvax.jpl.nasa.gov
Senior Software Engineer,		seismo!cit-vax!jpl-devvax!david
X and Object Guru.			(818)393-0983
Jet Propulsion Lab, M/S 230-103, 4800 Oak Grove Drive, Pasadena, CA 91109
------------------------------------------------------------------------- 
	One of these days I'm gonna learn:  Everytime I throw
	money at a problem to make it disappear, the only thing
	that disappears is my money...
-------------------------------------------------------------------------