Motif/Lesstif Application Development
The application and the widgets used within that application are presented on the display, based on their resource values. Even a simple text label has a set of resources used by X to determine its appearance. It is probably best to think of resources as data members for a specific instance of a widget. Some examples of resources are colors, the text of a label or text-entry widget, size, location, font and callback routines for events. Widgets are constructed in a hierarchy: each widget has a parent widget, and each widget may have zero or more children. Each resource is a name,value pair. The name is comprised of the application class, the name of each widget in the hierarchy and the actual resource name, in that order.
X and Motif define a number of primitive types which can be used as values for resources such as XmString (the Motif display string), Widget (any widget), Position (location) and XtPointer (used for passing data of any type to callback functions). Resource values can be retrieved and set using XtSetValue and XtGetValue. (There are also the XtVa* versions of these functions.) If you specify the wrong type for a value, you won't find out until runtime, so it is a good idea to verify the types using a man page or the reference manual. It is also important to keep an eye on your application's STDERR output for messages from the X libraries.
An example of a name for a Widget resource would be “.xtxtvw.title” (the text in the application window title bar). It could be specified in the ~/.Xdefaults file as the application resource “XTxtVw.xtxtvw.title”. I encourage you to explore resource names using editres (see the section on debugging). The X server maintains a database of resource names for all applications. These specifications come from a number of sources, including the initialization file for your window manager (such as ~/.fvwmrc), the X defaults (~/.Xdefaults), application-specific defaults (on Linux /usr/X11R6/lib/X11/app-defaults, on Solaris /usr/openwin/lib/app-defaults) and runtime specification by the application.
The xrdb command provides a means for viewing and changing the resource settings in the database at runtime (changes affect only widgets created afterward), although editres is far easier to use for applications which support it. Take a look at the manual page for xrdb, but note it typically replaces the database settings. If you want to merge additional settings, you must specify this using the -merge option.
I specify some application resources in the fallback resources passed to the initialize function. A simple example of setting some widget resources can be seen in the setMainTitle routine.
Some widgets are designed to handle layout and event management for other widgets. These are called manager widgets and include XmForm, XmBulletinBoard and XmRowColumn. A number of widgets derived from the manager widgets provide enhanced behavior, such as the XmSimpleMenubar.
XmBulletinBoard provides the means for placement of widgets at specific locations—you must specify the X and Y offsets within the bulletin board. This widget is generally not used alone, but instead to derive other more useful widgets such as XmForm. XmForm allows you to specify the placement of widgets relative to others within a form. This is probably the most useful and commonly used manager, since it automatically handles resizing and dynamic changes in its children widgets at run-time.
When a widget is created, it is not actually displayed until it and every widget in the hierarchy above it is managed. Widgets created as children of an XmForm widget will not appear on the screen until the form widget is managed via a call to XtManageChild. This will cause every managed widget in the form to suddenly appear. Typically, you will want to create a manager widget as the single child of the top-level shell, then use that widget as a parent for the remaining GUI components (line 103).
Another widget used in the application is XmLabel (line 157). This is used for simple output of text strings and images that typically do not interact with the user. Thus, labels are often created as Gadgets, a special sort of widget that defers much of its event handling to its parent. This means fewer callbacks are registered, fewer events get dispatched and generally helps improve performance. I try to use gadgets when I do not expect a widget to interact with the user or when there are many instances of a particular widget (such as rows in a table). Push buttons (line 173) are derived from XmLabel.
The XmTextField widget (line 164) is used to provide a single-line data entry field or a more flexible output mechanism. The text field is a specialized sort of text widget intended for situations where the more fully featured XmText widget would be overkill. The XmText widget can do everything the XmTextField can, and more. The XmScrolledText widget (line 202) is used to display large amounts of text and is actually packed with enough features to be used as a nice text editor. In fact, you could implement a text editor using the example application by adding fewer than 20 lines of code.