27 Advanced UIL Programming
This chapter describes advanced concepts and programming techniques in UIL. It builds on the UIL material
explained in the previous chapters.
This chapter introduces and examines ways that you can make the most of UIL's more advanced features. In the
following sections, we describe how to add non−Motif widgets to an interface description, discuss methods and ideas
for organizing UIL files, and examine the considerations that you face when setting resources in UIL. Finally, we
present material on advanced uses of UIL lists and user−interface prototyping.
27.1 Using Non−Motif Widgets
With UIL, it is easy to define instances of any of the Motif widgets, because their type names are built into the
compiler. However, you may need to use your own widget or a third−party widget in an application to provide
functionality that is not available in the Motif widget set. Fortunately, it is possible to include other widgets using the
special user_defined widget class along with the argument and reason value types.
OSF/Motif also supports non−Motif widget descriptions using the widget meta−language (WML). These widgets are
written into a separate WML description file which is run through the WML compiler. WML is typically used for
describing alternative widget sets; many third party widget sets include compiled WML description files. The use of
compiled WML description files is covered in #suilwmlopt, but a complete description of WML syntax and usage is
beyond the scope of this book.
Getting back to UIL, here are the steps involved in defining and creating a user−defined widget:
Write a widget creation procedure for the new widget.
Register the creation procedure with Mrm using MrmRegisterClass().
Declare the creation procedure in UIL.
Declare the widget's resources and callbacks in UIL.
Define one or more instances of the widget.
To illustrate these steps, we are going to present an example that uses the Athena (Xaw) Tree and Panner widgets. The
Tree widget is a constraint widget that arranges its children in a tree, while the Panner is a two−dimensional scroll bar.
27.1.1 The Widget Creation Procedure
In order to create a non−Motif widget, you must write a creation procedure and register it with Mrm. A user−defined
widget creation procedure takes the same form as the Motif widget creation routines. The parent argument specifies
the parent of the widget to create, and the name argument is the widget's name. The args and num_args
parameters supply the initial resource settings for the widget. Most creation procedures create a widget simply by
calling XtCreateWidget().
Mrm must know about a new creation function before you can create widgets with it. Widget creation functions are
registered with MrmRegisterClass(), which must be called before any user−defined widgets are created. This
function takes the following form:
Cardinal
MrmRegisterClass(class_code, class_name, proc_name, create_proc,
717
widget_class)
MrmType class_code;
String class_name;
String proc_name;
Widget (*create_proc)();
WidgetClass widget_class;
The first two arguments, class_code and class_name, are obsolete but remain to preserve backwards
compatibility. You should always pass 0 and NULL for these arguments, respectively. The proc_name parameter
specifies the name of the creation procedure as it appears in a UIL module. To avoid confusion, it is a good idea to use
the same name in both application code and UIL. The create_proc argument is the address of the creation
procedure, and widget_class is a pointer to the class structure of the widget. The function indicates the result of
the operation by returning either MrmSUCCESS or MrmFAILURE. A failure only occurs when the function cannot
allocate memory.
MrmRegisterClass() does not take an MrmHierarchy argument like many of the Mrm routines, which means
that any user−defined widgets that you register with this function are accessible from all open hierarchies. Mrm does
not provide a way to register a widget class with an individual hierarchy. the source code demonstrates the use of
MrmRegisterClass().
/* tree.c −−
* Program to show the Tree and Panner widgets.
*/
#include <stdio.h>
#include <X11/Intrinsic.h>
#include <X11/Xaw/Tree.h>
#include <X11/Xaw/Panner.h>
#include <X11/StringDefs.h>
#include <Mrm/MrmAppl.h>
void pan();
static MrmRegisterArg callback_list[] = {
{ "pan", (XtPointer) pan },
/* Add additional callback procedures here... */
};
Widget
XawCreateTreeWidget (parent, name, args, num_args)
Widget parent;
String name;
ArgList args;
Cardinal num_args;
{
return (XtCreateWidget (name, treeWidgetClass, parent, args, num_args));
}
Widget
XawCreatePannerWidget (parent, name, args, num_args)
Widget parent;
String name;
ArgList args;
Cardinal num_args;
{
return (XtCreateWidget (name, pannerWidgetClass, parent, args, num_args));
}
27 Advanced UIL Programming 27 Advanced UIL Programming
718
void
pan (panner, client_data, call_data)
Widget panner;
XtPointer client_data;
XtPointer call_data;
{
Widget tree = (Widget) client_data;
XawPannerReport *report = (XawPannerReport *) call_data;
/* Should use XtSetValues, but DrawingArea bug prevents us */
XtMoveWidget (tree, −report−>slider_x, −report−>slider_y);
}
int
main (argc, argv)
int argc;
char *argv[];
{
XtAppContext app_context;
Widget toplevel, root_widget;
Cardinal status;
static String uid_file_list[] = { "tree" };
MrmType class_code;
MrmHierarchy hierarchy;
XtSetLanguageProc (NULL, NULL, NULL);
MrmInitialize();
toplevel = XtVaAppInitialize (&app_context, "Demos", NULL, 0,
&argc, argv, NULL, NULL);
status = MrmOpenHierarchyPerDisplay (XtDisplay (toplevel),
XtNumber (uid_file_list), uid_file_list, NULL, &hierarchy);
if (status != MrmSUCCESS) {
XtAppError (app_context, "MrmOpenHierarchyPerDisplay failed");
exit (1);
}
MrmRegisterNames (callback_list, XtNumber (callback_list));
MrmRegisterClass (0, NULL, "XawCreateTreeWidget",
XawCreateTreeWidget, treeWidgetClass);
MrmRegisterClass (0, NULL, "XawCreatePannerWidget",
XawCreatePannerWidget, pannerWidgetClass);
status = MrmFetchWidget (hierarchy, "root", toplevel, &root_widget,
&class_code);
if (status != MrmSUCCESS) {
XtAppError (app_context, "MrmFetchWidget failed");
exit (1);
}
XtManageChild (root_widget);
XtRealizeWidget (toplevel);
XtAppMainLoop (app_context);
}
27 Advanced UIL Programming 27 Advanced UIL Programming
719

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.