Search the FAQ Archives

3 - A - B - C - D - E - F - G - H - I - J - K - L - M
N - O - P - Q - R - S - T - U - V - W - X - Y - Z
faqs.org - Internet FAQ Archives

Motif FAQ (Part 6 of 9)
Section - 202) How can I have a modal dialog which has to be answered before

( Part1 - Part2 - Part3 - Part4 - Part5 - Part6 - Part7 - Part8 - Part9 - Single Page )
[ Usenet FAQs | Web FAQs | Documents | RFC Index | Schools ]


Top Document: Motif FAQ (Part 6 of 9)
Previous Document: 201) How can I direct the keyboard input to a particular widget?
Next Document: 203) TOPIC: MEMORY AND SPEED
See reader questions & answers on this topic! - Help others by sharing your knowledge
the application can continue?
[Last modified: Sep 97]

Answer: Warning: the following answer relies on nested event loops.  Use these
with caution, as nested loops can affect the ordering of events and widget
destruction, leading to several undesirable side effects.

Ken Lee


Note: J.-N. Meurisse (uunet!rc4.vub.ac.be!jnmeuris) sent a correction to the
following code fragment. Change:

XtAddCallback(dialog, XmNpopdownCallback, ...)
to
XtAddCallback(XtParent(dialog), XmNpopdownCallback, ...)

The answer depends on whether you are using the Motif window manager mwm or
not.  Test for this by XmIsMotifWMRunning.

The window manager mwm knows how to control event passing to dialog widgets
declared as modal. If the dialog is set to application modal, then no
interaction with the rest of the application can occur until the dialog is
destroyed or unmanaged.

Use the appropriate code in the following program.  There is followup
discussion after the program.


/* Written by Dan Heller.  Copyright 1991, O'Reilly && Associates.
* This program is freely distributable without licensing fees and
* is provided without guarantee or warranty expressed or implied.
* This program is -not- in the public domain.  This program is
* taken from the Motif Programming Manual, O'Reilly Volume 6.
*/

/*
* ask_user.c -- create a pushbutton that posts a dialog box
* that asks the user a question that requires an immediate
* response.  The function that asks the question actually
* posts the dialog that displays the question, waits for and
* returns the result.
*/
#include <X11/Intrinsic.h>
#include <Xm/DialogS.h>
#include <Xm/SelectioB.h>
#include <Xm/RowColumn.h>
#include <Xm/MessageB.h>
#include <Xm/PushBG.h>
#include <Xm/PushB.h>

XtAppContext app;

#define YES 1
#define NO  2

/* main() --create a pushbutton whose callback pops up a dialog box */
main(argc, argv)
char *argv[];
int argc;
{
Widget parent, button, toplevel;
XmString label;
void pushed();

toplevel = XtAppInitialize(&app, "Demos",
NULL, 0, &argc, argv, NULL, NULL, 0);

label = XmStringCreateLocalized("/bin/rm *");
button = XtVaCreateManagedWidget("button",
xmPushButtonWidgetClass, toplevel,
XmNlabelString,          label,
NULL);
XtAddCallback(button, XmNactivateCallback,
pushed, "Remove Everything?");
XmStringFree(label);

XtRealizeWidget(toplevel);
XtAppMainLoop(app);
}

/* pushed() --the callback routine for the main app's pushbutton. */
void
pushed(w, question)
Widget w;
char *question;
{
if (AskUser(w, question) == YES)
puts("Yes");
else
puts("No");
}

/*
* AskUser() -- a generalized routine that asks the user a question
* and returns the response.
*/
AskUser(parent, question)
char *question;
{
static Widget dialog;
XmString text, yes, no;
static int answer;
extern void response();

answer = 0;
if (!dialog) {
dialog = XmCreateQuestionDialog(parent, "dialog", NULL, 0);
yes = XmStringCreateLocalized("Yes");
no = XmStringCreateLocalized("No");
XtVaSetValues(dialog,
    XmNdialogStyle,        XmDIALOG_APPLICATION_MODAL,
    XmNokLabelString,      yes,
    XmNcancelLabelString,  no,
    NULL);
XtSetSensitive(
    XmMessageBoxGetChild(dialog, XmDIALOG_HELP_BUTTON), False);
XtAddCallback(dialog, XmNokCallback, response, &answer);
XtAddCallback(dialog, XmNcancelCallback, response, &answer);
/* if the user interacts via the system menu: */
/* SEE CORRECTION ABOVE */
XtAddCallback(dialog, XmNpopdownCallback, response, &answer);
}
text = XmStringCreateLocalized(question);
XtVaSetValues(dialog,
XmNmessageString,      text,
NULL);
XmStringFree(text);
XtManageChild(dialog);
XtPopup(XtParent(dialog), XtGrabNone);

/* while the user hasn't provided an answer, simulate XtMainLoop.
* The answer changes as soon as the user selects one of the
* buttons and the callback routine changes its value.  Don't
* break loop until XtPending() also returns False to assure
* widget destruction.
*/
while (answer == 0 || XtAppPending(app))
XtAppProcessEvent(app, XtIMAll);
return answer;
}

/* response() --The user made some sort of response to the
* question posed in AskUser().  Set the answer (client_data)
* accordingly and destroy the dialog.
*/
void
response(w, answer, reason)
Widget w;
int *answer;
XmAnyCallbackStruct *reason;
{
switch (reason->reason) {
case XmCR_OK:
    *answer = YES;
    break;
case XmCR_CANCEL:
    *answer = NO;
    break;
default:
    *answer = NO;
    return;
}
}


If you aren't running a window manager that acknowledges this hint, then you
may have to grab the pointer (and keyboard) yourself to make sure the user
doesn't interact with any other widget.  Change the grab flag in XtPopup to
XtGrabExclusive, and XtRemoveGrab(XtParent(w)) to the response() function.

User Contributions:

Comment about this article, ask questions, or add new information about this topic:




Top Document: Motif FAQ (Part 6 of 9)
Previous Document: 201) How can I direct the keyboard input to a particular widget?
Next Document: 203) TOPIC: MEMORY AND SPEED

Part1 - Part2 - Part3 - Part4 - Part5 - Part6 - Part7 - Part8 - Part9 - Single Page

[ Usenet FAQs | Web FAQs | Documents | RFC Index ]

Send corrections/additions to the FAQ Maintainer:
kenton@rahul.net (Ken Lee)





Last Update March 27 2014 @ 02:11 PM