25 Creating a User Interface With UIL
This chapter expands upon the overview of UIL and Mrm presented earlier. The syntax and usage of UIL are
described in detail, along with the Mrm functions associated with the various UIL constructs.
Now that you have a basic understanding of how UIL and Mrm are used to define and create a user interface, we can
turn to the details of using UIL and Mrm. Recall that a UIL module can contain five different types of sections: the
object section for defining widgets; the value section for defining resource values and callback arguments; the
identifier section for declaring application variables exported to UIL; the procedure section for declaring
callbacks; and the list section for defining lists of widgets, resource settings, callback settings, and callback
routines.
An application accesses UIL definitions using the Mrm library. Mrm functions serve three basic purposes: file
handling, importing information from UIL, and exporting information to UIL. Examples of each of these types of
functionality appear in the hello_world.c program in Chapter 22, Introduction to UIL. The functions that import
information create widgets that are defined in object sections and retrieve data that is defined in value sections.
The functions that export information register callbacks that are declared in procedure sections and application
data that is declared in identifier sections. There are no Mrm functions that work with UIL lists, because unlike
other UIL entities, lists are strictly internal to a module.
In this chapter, we describe the role of UIL in each major step of creating an application:
Defining and creating the widgets that make up an interface
Defining and fetching values (resources)
Working with widget callbacks
We also talk about two other related topics:
Using lists of widgets, resources, and callbacks
Exporting application−created data to UIL
The vast amount of information that is covered in this chapter makes it impractical to illustrate all of the UIL and Mrm
concepts with a single UIL module or application. Such an application would be quite large and unrealistic. Therefore,
we demonstrate the features of UIL and Mrm with many small, self−contained examples. To facilitate this approach,
we've put together a small C program that you can use to try out the various UIL modules and callback functions we
discuss.
25.1 Viewing UIL Examples
The showuid.c program is designed to display a portion of a user interface that is defined in a UID file. The idea is to
allow you to examine the output of different UIL modules without needing a separate program for every module. The
complete source code of this program appears in the source code
/* showuid.c −−
* Program to show the interface defined in a UID file.
*/
#include <stdio.h>
#include <Mrm/MrmAppl.h>
655
void quit();
void print();
static MrmRegisterArg callback_list[] = {
{ "quit", (XtPointer) quit },
{ "print", (XtPointer) print },
/* Add additional callback procedures here... */
};
typedef struct {
String root_widget_name;
} app_data_t;
static app_data_t app_data;
static XtResource resources[] = {
{ "root", "Root", XmRString, sizeof(String),
XtOffsetOf (app_data_t,root_widget_name), XmRString,
(XtPointer) "root" },
};
static XrmOptionDescRec options[] = {
{ "−root", "root", XrmoptionSepArg, NULL },
};
void
quit (w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
exit (0);
}
void
print (w, client_data, call_data)
Widget w;
XtPointer client_data;
XtPointer call_data;
{
char *message = (char *) client_data;
puts (message);
}
main (argc, argv)
int argc;
char *argv[];
{
XtAppContext app_context;
Widget toplevel;
Widget root_widget;
Cardinal status;
MrmHierarchy hierarchy;
MrmType class_code;
XtSetLanguageProc (NULL, NULL, NULL);
MrmInitialize();
toplevel = XtVaAppInitialize (&app_context, "Demos", options,
25 Creating a User Interface With UIL25 Creating a User Interface With UIL
656
XtNumber(options), &argc, argv, NULL, NULL);
XtGetApplicationResources (toplevel, &app_data, resources,
XtNumber(resources), NULL, 0);
/* Check number of args after Xt and App have removed their options. */
if (argc < 2) {
fprintf (stderr,
"usage: showuid [Xt options] [−root name] uidfiles ...0);
exit (1);
}
/* Use argc and arv to obtain UID file names from the command line.
(Most applications use an internal static array of names.) */
status = MrmOpenHierarchyPerDisplay (XtDisplay (toplevel), argc − 1,
argv + 1, NULL, &hierarchy);
if (status != MrmSUCCESS) {
XtAppError (app_context, "MrmOpenHierarchyPerDisplay failed");
exit (1);
}
MrmRegisterNames (callback_list, XtNumber (callback_list));
status = MrmFetchWidget (hierarchy, app_data.root_widget_name,
toplevel, &root_widget, &class_code);
if (status != MrmSUCCESS) {
XtAppError (app_context, "MrmFetchWidget failed");
exit (1);
}
MrmCloseHierarchy (hierarchy);
XtManageChild (root_widget);
XtRealizeWidget (toplevel);
XtAppMainLoop (app_context);
}
This program is similar to the hello_world.c program in Chapter 22, Introduction to UIL. However, we've made a few
small changes to make the program flexible enough to accommodate our needs in this chapter. The main()
procedure follows the steps required of any Mrm program except that the UID files containing the interface
description and the name of the widget to be created are not hard−coded in the program. This information is now
specified on the command line, so the program can be used to display different UID files and widget trees.
The list of UID files passed to MrmOpenHierarchyPerDisplay() is taken directly from the command line.
Since argv is in the format expected by the routine, we pass it directly to the routine, after adding 1 to skip the name
of program in argv[0]; We then subtract 1 from argc to account for the difference.
MrmOpenHierarchyPerDisplay() is called after the other command−line arguments have been removed by
XtVaAppInitialize() and XtGetApplicationResources().
You can specify the name of the widget hierarchy created by the program with the −root option. Xt takes care of
parsing the command−line switch and putting the value into the app_data structure. (See Volume Four, X Toolkit
Intrinsics Programming Manual, for detailed information on this process.) If you do not specify the −root option,
the application uses root as the default name. In most of the modules in this chapter, we use the default name root
for the top−level widget.
25 Creating a User Interface With UIL25 Creating a User Interface With UIL
657

Get Volume 6A: Motif Programming Manual now with the O’Reilly learning platform.

O’Reilly members experience books, live events, courses curated by job role, and more from O’Reilly and nearly 200 top publishers.