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

comp.windows.x.intrinsics Frequently Asked Questions (FAQ)
Section - 43. How do I query the user synchronously using Xt?

( Single Page )
[ Usenet FAQs | Web FAQs | Documents | RFC Index | Cities ]


Top Document: comp.windows.x.intrinsics Frequently Asked Questions (FAQ)
Previous Document: 42. Is this a memory leak in the X11R4 deletion of work procs?!
Next Document: 44. How do I simulate a button press/release event for a widget?
See reader questions & answers on this topic! - Help others by sharing your knowledge
----------------------------------------------------------------------

It is possible to have code which looks like this trivial callback,
which has a clear flow of control. The calls to AskUser() block until
answer is set to one of the valid values. If it is not a "yes" answer,
the code drops out of the callback and back to an event-processing
loop:

	void quit(Widget w, XtPointer client, XtPointer call)
	{
		int             answer;
		answer = AskUser(w, "Really Quit?");
		if (RET_YES == answer)
			{
			answer = AskUser(w, "Are You Really Positive?");
			if (RET_YES == answer)
				exit(0);
                }
	}

A more realistic example might ask whether to create a file or whether
to overwrite it.

This is accomplished by entering a second event-processing loop and
waiting until the user answers the question; the answer is returned to
the calling function. That function AskUser() looks something like
this, where the Motif can be replaced with widget-set-specific code to
create some sort of dialog-box displaying the question string and
buttons for "OK", "Cancel" and "Help" or equivalents:

  int AskUser(w, string)
        Widget          w;
        char           *string;
  {
        int             answer=RET_NONE;	/* some not-used marker */
        Widget          dialog;			/* could cache&carry, but ...*/
        Arg             args[3];
        int             n = 0;
        XtAppContext    context;

        n=0;
        XtSetArg(args[n], XmNmessageString, XmStringCreateLtoR(string,
                XmSTRING_DEFAULT_CHARSET)); n++;
        XtSetArg(args[n], XmNdialogStyle, XmDIALOG_APPLICATION_MODAL); n++;
        dialog = XmCreateQuestionDialog(XtParent(w), string, args, n);
        XtAddCallback(dialog, XmNokCallback, response, &answer);
        XtAddCallback(dialog, XmNcancelCallback, response, &answer);
        XtAddCallback(dialog, XmNhelpCallback, response, &answer);
        XtManageChild(dialog);

        context = XtWidgetToApplicationContext (w);
        while (answer == RET_NONE || XtAppPending(context)) {
                XtAppProcessEvent (context, XtIMAll);
        }
        XtDestroyWidget(dialog);  /* blow away the dialog box and shell */
        return answer;
  }

The dialog supports three buttons, which are set to call the same
function when tickled by the user.  The variable answer is set when
the user finally selects one of those choices:

  void response(w, client, call)
        Widget          w;
        XtPointer client;
        XtPointer call;
  {
  int *answer = (int *) client;
  XmAnyCallbackStruct *reason = (XmAnyCallbackStruct *) call;
        switch (reason->reason) {
        case XmCR_OK:
                *answer = RET_YES;	/* some #define value */
                break;
        case XmCR_CANCEL:
                *answer = RET_NO; 
		break;
        case XmCR_HELP:
                *answer = RET_HELP;
                break;
        default:
                return;
        }
}

and the code unwraps back to the point at which an answer was needed and
continues from there.

[Thanks to Dan Heller (argv@sun.com); further code is in Dan's R3/contrib
WidgetWrap library. 2/91]

User Contributions:

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