strongly recommends using the main window layout, many applications simply do not fit the standard GUI design
model. For example, a clock application, a terminal emulator, a calculator, and a host of other desktop applications do
not follow the Motif specifications in this regard, but they can still have Motif elements within them and can still be
regarded as Motif−compliant. If you already have an application in mind, chances are you already know whether or
not the main window layout is suited to the application; if you are in doubt, your best bet is to comply with the Motif
Style Guide.
Before we start discussing the MainWindow widget, you should realize that this widget class does not create any of
the widgets it manages. It merely facilitates managing the widgets in a way that is consistent with the Style Guide. In
order to discuss the MainWindow widget, we are going to have to discuss a number of other widget classes and use
them in examples. As a beginning chapter in a large book on Motif programming, this may seem like a bit much to
handle, especially if you are completely unfamiliar with the Motif toolkit. We encourage you to branch off into other
chapters whenever you find it necessary to do so. However, it is not our intention to explain these other widgets ahead
of time, nor is it our assumption that you already understand them. The lack of an understanding of the other widgets
should not interfere with our goal of describing the MainWindow widget and how it fits into the design of an
application.
5.1 Creating a MainWindow
The MainWindow widget class is defined in <Xm/MainW.h>, which must be included whenever you create a
MainWindow widget. As mentioned in Chapter 2, The Motif Programming Model, you should probably use an
ApplicationShell or TopLevelShell widget as the parent of a MainWindow. If the MainWindow is being used as the
main application window, the ApplicationShell returned by XtVaAppInitialize() (or another similar toolkit
initialization function) is typically used as the parent. The function XtVaCreateManagedWidget() can be used
to create an instance of a MainWindow widget, as shown in the following code fragment:
#include <Xm/MainW.h>
...
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, main_w;
XtAppContext app;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtAppInitialize (&app, "App−Class",
NULL, 0, &argc, argv, NULL, NULL);
main_w = XtVaCreateManagedWidget ("mw",
xmMainWindowWidgetClass, toplevel,
resource−value−list,
NULL);
XtRealizeWidget(toplevel);
XtAppMainLoop(app);
}
The MainWindow class is subclassed from the ScrolledWindow class, which means that it inherits all the attributes of
a ScrolledWindow, including its resources. A ScrolledWindow allows the user to view an arbitrary widget of any size
by attaching horizontal and vertical ScrollBars to it. You can think of a MainWindow as a ScrolledWindow with the
additional ability to have an optional menu bar, command area, and message area. Because the MainWindow is
subclassed from the ScrolledWindow widget, we will be referring to some ScrolledWindow resources and disclosing
some facts about the ScrolledWindow. For more information about the ScrolledWindow, see Chapter 9,
ScrolledWindows and ScrollBars. You may eventually need to learn more about the ScrolledWindow widget to best
5 The Main Window 5.1 Creating a MainWindow
82
make use of the MainWindow, but this chapter tries to present the fundamentals of the MainWindow widget, rather
than focus on the ScrolledWindow.
While a MainWindow does control the sizes and positions of its widget children like any manager widget, the
geometry management it performs is not the classic management style of other manager widgets. The MainWindow is
a special−case object that handles only certain types of children and performs only simple widget positioning. It is
designed to support the generic main window layout specified by the Motif Style Guide.
Let's take a look at how the MainWindow can be used in an actual application. the source code demonstrates how the
MainWindow widget fits into a typical application design. XtSetLanguageProc() is only available in X11R5;
there is no corresponding function in X11R4.
/* show_pix.c −− A minimal example of a MainWindow. Use a Label as the
* workWindow to display a bitmap specified on the command line.
*/
#include <Xm/MainW.h>
#include <Xm/Label.h>
main(argc, argv)
int argc;
char *argv[];
{
Widget toplevel, main_w, label;
XtAppContext app;
Pixmap pixmap;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL);
if (!argv[1]) {
printf ("usage: %s bitmap−file0, *argv);
exit (1);
}
main_w = XtVaCreateManagedWidget ("main_window",
xmMainWindowWidgetClass, toplevel,
XmNscrollBarDisplayPolicy, XmAS_NEEDED,
XmNscrollingPolicy, XmAUTOMATIC,
NULL);
/* Load bitmap given in argv[1] */
pixmap = XmGetPixmap (XtScreen (toplevel), argv[1],
BlackPixelOfScreen (XtScreen (toplevel)),
WhitePixelOfScreen (XtScreen (toplevel)));
if (pixmap == XmUNSPECIFIED_PIXMAP) {
printf ("can't create pixmap from %s0, argv[1]);
exit (1);
}
/* Now create label using pixmap */
label = XtVaCreateManagedWidget ("label", xmLabelWidgetClass, main_w,
XmNlabelType, XmPIXMAP,
XmNlabelPixmap, pixmap,
NULL);
/* set the label as the "work area" of the main window */
5 The Main Window 5.1 Creating a MainWindow
83
XtVaSetValues (main_w,
XmNworkWindow, label,
NULL);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
In this example, the MainWindow widget is not used to its full potential. It only contains one other widget, a Label
widget, that is used to display a bitmap from the file specified as the first argument on the command line (argv[1]).
XtVaAppInitialize() parses the command−line arguments that are used when the program is run. The
command−line options that are specific to Xlib or Xt are evaluated and removed from the argument list. What is not
parsed is left in argv; our program reads argv[1] as the name of a bitmap to display in the MainWindow. The
Label widget is used as the work area window for the MainWindow. We did this intentionally to focus your attention
on the scrolled−window aspect of the MainWindow widget. The following command line:
% show_pix /usr/include/X11/bitmaps/xlogo64
produces the output shown in the figure.
The file specified on the command line should contain X11 bitmap data, so that the application can create a pixmap.
The pixmap is displayed in a Label widget, which has been specified as the XmNworkWindow of the MainWindow.
As shown in the figure, the bitmap is simply displayed in the window. However, if a larger bitmap is specified, only a
portion of the bitmap can be displayed, so ScrollBars are provided to allow the user to view the entire bitmap. The
output of the command:
% show_pix /usr/include/X11/bitmaps/escherknot
is shown in the figure.
Output of show_pix xlogo64
5 The Main Window 5.1 Creating a MainWindow
84
Output of show_pix escherknot
The bitmap is obviously too large to be displayed in the MainWindow without either clipping the image or enlarging
the window. Rather than resize its own window to an unreasonable size, the MainWindow can display ScrollBars.
This behavior is enabled by setting the MainWindow resources XmNscrollBarDisplayPolicy to
XmAS_NEEDED and XmN-scrollingPolicy to XmAUTOMATIC. These values automate the process whereby
ScrollBars are managed when they are needed. If there is enough room for the entire bitmap to be displayed, the
ScrollBars are not provided. Try resizing the show_pix window and see how the ScrollBars appear and disappear as
needed. This behavior occurs as a result of setting XmNscrollBarDisplayPolicy to XmAS_NEEDED.
Since we do not specify a size for the MainWindow, the toolkit sets both the width and height to be 100 pixels. These
default values are not a documented feature. Both the MainWindow and the ScrolledWindow suffer from the same
problem: if you do not specifically set the -XmNwidth and XmNheight resources, the default size of the widget is
not very useful.
The XmNscrollBarDisplayPolicy and XmNscrollingPolicy resources are inherited from the
ScrolledWindow widget class. Because XmNscrollingPolicy is set to XmAUTOMATIC, the toolkit creates and
manages the ScrollBars automatically. Another possible value for the resource is XmAPPLICATION_DEFINED,
which implies that the application is going to create and manage the ScrollBars for the MainWindow and control all of
the aspects of their functionality. Application−defined scrolling is the default style for the MainWindow widget, but it
is unlikely that you will want to leave it that way, since automatic scrolling is far easier to manage at this stage of the
game. For complete details on the different scrolling styles, see Chapter 9, ScrolledWindows and ScrollBars.
Using the application−defined scrolling policy does not necessarily require you to provide your own scrolling
mechanisms. It simply relieves the MainWindow widget of the responsibility of handling the scrolling mechanisms. If
you use a ScrolledList or ScrolledText widget as the work area, you should definitely leave the
XmNscrollingPolicy as XmAPPLICATION_DEFINED, since these widgets manage their own ScrollBars. They
will handle the scrolling behavior instead of the MainWindow. the source code shows an example of a program that
uses a ScrolledList for the work area in a MainWindow widget. XtSetLanguageProc() is only available in
X11R5; there is no corresponding function in X11R4.
/* main_list.c −− Use the ScrolledList window as the feature
* component of a MainWindow widget.
*/
#include <Xm/MainW.h>
#include <Xm/List.h>
main(argc, argv)
char *argv[];
{
Widget toplevel, main_w, list_w;
5 The Main Window 5.1 Creating a MainWindow
85
XtAppContext app;
Pixmap pixmap;
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL);
main_w = XtVaCreateManagedWidget ("main_window",
xmMainWindowWidgetClass, toplevel,
NULL);
list_w = XmCreateScrolledList (main_w, "main_list", NULL, 0);
XtVaSetValues (list_w,
XtVaTypedArg, XmNitems, XmRString,
"Red, Green, Blue, Orange, Maroon, Grey, Black, White", 53,
XmNitemCount, 8,
XmNvisibleItemCount, 5,
NULL);
XtManageChild (list_w);
/* set the list_w as the "work area" of the main window */
XtVaSetValues (main_w, XmNworkWindow, XtParent (list_w), NULL);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
In order to simplify the application, we specified the items in the ScrolledList as a single string:
XtVaSetValues(list_w,
XtVaTypedArg, XmNitems, XmRString,
"Red, Green, Blue, Orange, Maroon, Grey, Black, White", 53,
XmNitemCount, 8,
XmNvisibleItemCount, 5,
NULL);
This technique provides the easiest way to specify a list for a List widget. The items in a List widget must be specified
as an array of compound strings. If we took the time to create each list item separately, we would have to create each
compound string, assemble the array of XmString objects and specify it as the XmNitems resource, and then free
each string separately after the widget was created. By using XtVaTypedArg, the whole list can be created in one
line using the List widget's type converter to convert the string into a list of compound strings. We use this form of
resource specification frequently in the book to simplify examples. See Volume Four, X Toolkit Intrinsics
Programming Manual, for a complete discussion on how this kind of type conversion is done. See Chapter 12, The
List Widget, for details on the List widget; see Chapter 19, Compound Strings, for details on compound strings.
It is important to note that while XmCreateScrolledList() creates both a ScrolledWindow widget and a List
widget, it returns the List widget. As a result, we must use XtParent() to get access to the ScrolledWindow
widget, so that it can be specified as the work area of the MainWindow. A common programming error with a
ScrolledText or a ScrolledList widget is using the actual Text or List widget rather than its ScrolledWindow parent.
Again, we refer you to Chapter 9, ScrolledWindows and ScrollBars, for a complete discussion of the use of
ScrolledText and ScrolledList compound objects.
5 The Main Window 5.1 Creating a MainWindow
86
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.