FileSelectionDialog resources:
XmNfilterLabelString XmNdirListLabelString
XmNfileListLabelString
Command resources:
XmNpromptString
The labels and callbacks of the various buttons in the action area are specified by resources based on the standard
Motif dialog button names. For example, the XmNokLabelString resource is used to set the label for the OK
button. XmNokCallback is used to specify the callback routine that the dialog should call when that button is
activated. As discussed earlier, it may be appropriate to change the labels of these buttons, but the resource and
callback names will always have names that correspond to their default labels.
The XmNmessageString resource specifies the message that is displayed by the MessageDialog. The
XmNsymbolPixmap resource specifies the iconic symbol that is associated with each of the MessageDialog types.
This resource is rarely changed, so discussion of it is deferred until Chapter 21, Advanced Dialog Programming.
The other resources apply to the different types of selection dialogs. For example, -XmNselectionLabelString
sets the label that is placed above the list area in SelectionDialog. These resources are discussed in Chapter 6,
Selection Dialogs.
All of these resources apply to the Labels and PushButtons in the different dialogs. It is important to note that they are
different from the usual resources for Labels and PushButtons. For example, the Label resource XmNlabelString
would normally be used to specify the label for both Label and PushButton widgets. Dialogs use their own resources
to maintain the abstraction of the dialog widget as a discrete user−interface object.
Another important thing to remember about the resources that refer to widget labels is that their values must be
specified as compound strings. Compound strings allow labels to be rendered in arbitrary fonts and to span multiple
lines. See Chapter 19, Compound Strings, for more information.
The following code fragment demonstrates how to specify dialog resources and callback routines:
Widget dialog;
XmString msg, yes, no;
extern void my_callback();
dialog = XmCreateQuestionDialog (parent, "dialog", NULL, 0);
yes = XmStringCreateLocalized ("Yes");
no = XmStringCreateLocalized ("No");
msg = XmStringCreateLocalized ("Do you want to quit?");
XtVaSetValues (dialog, XmNmessageString, msg, XmNokLabelString, yes, XmNcancelLabelString, no, NULL);
XtAddCallback (dialog, XmNokCallback, my_callback, NULL); XtAddCallback (dialog, XmNcancelCallback,
my_callback, NULL); XmStringFree (yes); XmStringFree (no); XmStringFree (msg);
6.3.4 Dialog Management
None of the Motif toolkit convenience functions manage the widgets that they create, so the application must call
XtManageChild() explicitly. It just so happens that managing a dialog widget that is the immediate child of a
DialogShell causes the entire dialog to pop up. Similarly, unmanaging the same dialog widget causes it and its
6 Introduction to Dialogs 6.3.4 Dialog Management
114
DialogShell parent to pop down. This behavior is consistent with the Motif toolkit's treatment of the dialog/shell
combination as a single object abstraction. The toolkit is treating its own dialog widgets as opaque objects and trying
to hide the fact that there are DialogShells associated with them. The toolkit is also making the assumption that when
the programmer manages a dialog, she wants it to pop up immediately.
This practice is somewhat presumptuous and it conflicts directly with the specifications for the X Toolkit Intrinsics.
These specifications say that when the programmer wants to display a popup shell on the screen, she should use
XtPopup(). Similarly, when the dialog is to be dismissed, the programmer should call XtPopdown(). The fact
that XtManageChild() happens to pop up the shell and XtUnmanageChild() causes it to pop down is
misleading to the new Motif programmer and confusing to the experienced Xt programmer.
You should understand that this discussion of managing dialogs does not apply to customized dialogs that you create
yourself. It only applies to the predefined Motif dialog widgets that are created as immediate children of DialogShells.
The Motif toolkit uses this method because it has been around for a long time and it must be supported for backwards
compatibility with older versions. Furthermore, using XtPopup() requires access to the DialogShell parent of a
dialog widget, which breaks the single−object abstraction.
There are two ways to manage Motif dialogs. You can follow the Motif toolkit conventions of using
XtManageChild() and XtUnmanageChild() to pop up and pop down dialog widgets or you can use
XtPopup() and XtPopdown() on the dialog's parent to do the same job. Whatever you do, it is good practice to
pick one method and be consistent throughout an application. It is possible to mix and match the methods, but there
may be some undesirable side effects, which we will address in the next few sections.
In an effort to make our applications easier to port to other Xt−based toolkits, we follow the established convention of
using XtPopup(). This technique can coexist easily with XtManageChild(), since popping up an already
popped−up shell has no effect. XtPopup() takes the following form:
void
XtPopup(shell, grab_kind)
Widget shell;
XtGrabKind grab_kind;
The shell parameter to the function must be a shell widget; in this case it happens to be a DialogShell. If you
created the dialog using one of the Motif convenience routines, you can get a handle to the DialogShell by calling
XtParent() on the dialog widget.
The grab_kind parameter can be one of XtGrabNone, XtGrabNonexclusive, or XtGrabExclusive. We
almost always use XtGrabNone, since the other values imply a server grab, which means that other windows on the
desktop are locked out. Grabbing the server results in what is called modality; it implies that the user cannot interact
with anything but the dialog. While a grab may be desirable in some cases, the Motif toolkit provides some predefined
resources that handle the grab for you automatically. The advantage of using this alternate method is that it allows the
client to communicate more closely with the Motif Window Manager (mwm) and it provides for different kinds of
modality. These methods are discussed in Section #smodaldlg. For detailed information on XtPopup() and the
different uses of grab_kind, see Volume Four, X Toolkit Intrinsics Programming Manual.
If you call XtPopup() on a dialog widget that has already been popped up using XtManageChild(), the routine
has no effect. As a result, if you attempt to specify grab_kind as something other than XtGrabNone, it also has
no effect.
The counterpart to XtPopup() is XtPopdown(). Any time you want to pop down a shell, you can use this
function, which has the following form:
6 Introduction to Dialogs 6.3.4 Dialog Management
115
void
XtPopdown(shell)
Widget shell;
Again, the shell parameter should be the XtParent() of the dialog widget. If you use XtUnmanageChild()
to pop down a dialog, it is not necessary to call XtPopdown(), although we advise it for correctness and good form.
However, it is important to note that if you use XtUnmanageChild() to pop down a dialog, you must use
XtManageChild() to redisplay it again. Don't forget that the dialog widget itself is not a shell, so managing or
unmanaging it still takes place when you use the manage and unmanage functions.
Let's take a closer look at how dialogs are really used in an application. Examining the overall design and the
mechanics that are involved will help to clarify a number of issues about managing and unmanaging dialogs and
DialogShells. The program listed in the source code displays an InformationDialog when the user presses a
PushButton in the application's main window. XtSetLanguageProc() is only available in X11R5; there is no
corresponding function in X11R4. XmStringCreateLocalized() is only available in Motif 1.2;
XmStringCreateSimple() is the corresponding function in Motif 1.1.
/* hello_dialog.c −− your typical Hello World program using
* an InformationDialog.
*/
#include <Xm/RowColumn.h>
#include <Xm/MessageB.h>
#include <Xm/PushB.h>
main(argc, argv)
int argc;
char *argv[];
{
XtAppContext app;
Widget toplevel, rc, pb;
extern void popup(); /* callback for the pushbuttons −− pops up dialog */
extern void exit();
XtSetLanguageProc (NULL, NULL, NULL);
toplevel = XtVaAppInitialize (&app, "Demos", NULL, 0,
&argc, argv, NULL, NULL);
rc = XtVaCreateWidget ("rowcol",
xmRowColumnWidgetClass, toplevel, NULL);
pb = XtVaCreateManagedWidget ("Hello",
xmPushButtonWidgetClass, rc, NULL);
XtAddCallback (pb, XmNactivateCallback, popup, "Hello World");
pb = XtVaCreateManagedWidget ("Goodbye",
xmPushButtonWidgetClass, rc, NULL);
XtAddCallback (pb, XmNactivateCallback, exit, NULL);
XtManageChild (rc);
XtRealizeWidget (toplevel);
XtAppMainLoop (app);
}
/* callback for the PushButtons. Popup an InformationDialog displaying
* the text passed as the client data parameter.
*/
void
popup(button, client_data, call_data)
Widget button;
6 Introduction to Dialogs 6.3.4 Dialog Management
116
XtPointer client_data;
XtPointer call_data;
{
Widget dialog;
XmString xm_string;
extern void activate();
Arg args[5];
int n = 0;
char *text = (char *) client_data;
/* set the label for the dialog */
xm_string = XmStringCreateLocalized (text);
XtSetArg (args[n], XmNmessageString, xm_string); n++;
/* Create the InformationDialog as child of button */
dialog = XmCreateInformationDialog (button, "info", args, n);
/* no longer need the compound string, free it */
XmStringFree (xm_string);
/* add the callback routine */
XtAddCallback (dialog, XmNokCallback, activate, NULL);
/* manage the dialog */
XtManageChild (dialog);
XtPopup (XtParent (dialog), XtGrabNone);
}
/* callback routine for when the user presses the OK button.
* Yes, despite the fact that the OK button was pressed, the
* widget passed to this callback routine is the dialog!
*/
void
activate(dialog, client_data, call_data)
Widget dialog;
XtPointer client_data;
XtPointer call_data;
{
puts ("OK was pressed.");
}
The output of this program is shown in the figure.
6 Introduction to Dialogs 6.3.4 Dialog Management
117

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.