Motif/Lesstif Application Development

A tutorial designed to help you build your own GUI.
Getting Started

Figure 2. Simple Text Viewer

A good way to get a grip on a new technology is by looking at something built with it. Motif provides a rich and extensible environment, and it would take far too long to explain all the details behind the steps I will take; in fact, I will just scratch the surface of what can be done using Motif. The application I will use to illustrate Motif is a simple text-file viewer (see Figure 2). You should download the source (it's long) from I will refer to specific line numbers as I explain different aspects of the Motif API.

Motif (and X) development takes advantage of “Event-Driven Programming” using an event-dispatch loop. An application must set up the interface (or at least some minimal components) before turning control over to the loop that handles events (via XtAppMainLoop). Once the event loop is invoked, your code will be called only in response to an event. The important thing to remember is that as long as your code is running, your application is not communicating with the X server. You must take care to return control to the event loop regularly, especially during time-intensive operations. Callbacks, which are functions intended to be invoked by the event loop in response to a specific message, are used heavily. Motif and the Xt library (upon which Motif is built) take care of the vast majority of the events an application might receive—the only ones you must handle are those for which the default behavior is inadequate.

Compiling a Motif application is not too involved—you must ensure the Motif header files are available and the libraries are listed in the correct order on the link command. The following command will build the sample application on Linux using Lesstif or Motif:

gcc -o xtxtvw xtxtvw.c -I/usr/X11R6/include\
-L/usr/X11R6/lib -lXm -lXmu -lXt -lX11

To build the application on Solaris, issue the following command:

gcc -o xtxtvw xtxtvw.c -I/usr/dt/include\
-L/usr/openwin/lib -lXm -lXmu -lXt -lX11
If these don't work, look for a directory called /include/Xm in the directory tree containing your X Window System and specify that directory. The libraries are typically in the X library directory—search for a file named libXm*. Motif is most often made available as a shared library; the version will vary depending on your system. If you cannot find one or the other (especially the headers), you might not have loaded the X or Motif development package.

Setting Up the Application

Let's start by examining the code used to initialize the application, in order to cover some of the essentials. A fair amount of work has been done to make life easier on developers of international software; localization and internationalization are addressed by a number of features available in the X and Motif libraries. I will avoid treating this issue at all, except to say that you should make a habit of including a call to XtSetLanguageProc in all of your X applications.

The second toolkit function I call is XtAppInitialize (line 85), which has a few interesting calling arguments. This function is responsible for initializing the Xt library, evaluating any command-line arguments meant for the toolkit (such as geometry) and initializing X resources used by your application. context is a return parameter used by the X toolkit; you will not typically do much with this argument, apart from passing it to the main event loop. It is a work area for the libraries—a place for them to store state information about instances of widgets in your application. The second parameter is the class of your application. It is used to refer to resources that belong to the application by both internal and external clients, such as editres.

Listing 1.

The fifth and sixth arguments to XtAppInitialize are the argument count and argument list passed on the command line. The X toolkit will consume any command-line options intended for it, for example the location and initial size of the application's main window and the default background color. See the X11 man page to get a better idea of exactly which options are accepted. After this call, the remaining options can be processed by your application.

The other parameter of interest is the fallback resource string array. This is optional, but a good idea, as it specifies default values for resources used by the widgets in the application. Command-line options and any hard-coded values will override the settings listed here, but you should make a habit of specifying at least the background and foreground colors (and arguably the fonts) to help keep the interface appearance consistent.

The widget that gets created by XtAppInitialize is the application shell, containing the window that appears on the desktop as the application. This is a special widget which provides interaction with the window manager. Applications can have multiple shells if more than one primary window is required. This sample application has a single shell that ultimately parents all other widgets.