#include	<Xm/PushB.h>
#include	<Xm/MessageB.h>

Widget top, wait_dialog;
Widget CreateWorkingDialog(Widget parent);
void pushCB(Widget w, XtPointer c, XtPointer s);

int
main(int ac, char *av[])
{
    XtAppContext app;
    Widget pb;

    top = XtAppInitialize(&app, "Sample", NULL, 0, &ac, av, NULL, NULL, 0);
    pb = XmCreatePushButton(top, "Push me", NULL, 0);
    XtManageChild(pb);
    XtAddCallback(pb, XmNactivateCallback,
		  (XtCallbackProc)pushCB, NULL);
    wait_dialog = CreateWorkingDialog(top);

    XtRealizeWidget(top);
    XtAppMainLoop(app);

    return 0;
}

Widget
CreateWorkingDialog(Widget parent)
{
    Widget dialog, pb[2];
    Arg dialog_args[] = {
	{ XmNmessageString, },
	{ XmNokLabelString, },
	{ XmNdialogTitle, },
	{ XmNdialogStyle,
	      XmDIALOG_PRIMARY_APPLICATION_MODAL },
    };

    dialog_args[0].value = 
	(XtArgVal)XmStringCreateSimple("Please wait a minute.");
    dialog_args[1].value =
	(XtArgVal)XmStringCreateSimple("Done");
    dialog_args[2].value =
	(XtArgVal)XmStringCreateSimple("Working");
    dialog = XmCreateWorkingDialog(top, "workingD",
			   dialog_args, XtNumber(dialog_args));
    XmStringFree((XmString)dialog_args[0].value);
    XmStringFree((XmString)dialog_args[1].value);
    XmStringFree((XmString)dialog_args[2].value);

    pb[0] = XmMessageBoxGetChild(dialog,
			 XmDIALOG_HELP_BUTTON);
    pb[1] = XmMessageBoxGetChild(dialog,
			 XmDIALOG_CANCEL_BUTTON);
    XtUnmanageChildren(pb, 2);

    return dialog;
}

void WaitExposeEvent(Widget target);

void
pushCB(Widget w, XtPointer c, XtPointer s)
{
    Widget ok;

    ok = XmMessageBoxGetChild(wait_dialog, XmDIALOG_OK_BUTTON);
    XtSetSensitive(ok, False);
    XtManageChild(wait_dialog);
    WaitExposeEvent(wait_dialog);
    sleep(10);
    XtSetSensitive(ok, True);
}

void
WaitExposeEvent(Widget target)
{
    /* ウィジェットのウィンドウのIDを取得する */
    Window w = XtWindowOfObject(target);
    XtAppContext app = XtWidgetToApplicationContext(target);
    Boolean cont = True;

    while (cont || XtAppPending(app)) {
	XEvent ev;
	XtAppNextEvent(app, &ev);
	XtDispatchEvent(&ev);
	/* 目的のイベントを処理したか調べる */
	if (ev.type == Expose && ev.xany.window == w)
	    cont = False;
    }
}
