/*
 * alert.c : A popup click-to-remove message box.
 *
 * George Ferguson, ferguson@cs.rochester.edu, 4 Sep 1991.
 *
 */

#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Shell.h>
#include <X11/Xaw/Dialog.h>
#include <X11/Xaw/Cardinals.h>
#include <stdio.h>
extern Widget toplevel;		/* this is the only external */

/*
 * Functions defined here
 */
void alert0(),alert1();		/* interface routines */
void alertOk();			/* public action procedure */

static Widget alertShell,alertDialog;
static Boolean alertDone;

void
alert0(str)
char *str;
{
    Arg args[2];
    XEvent event;
    Window rwin,child;
    int rx,ry,cx,cy,x,y;
    unsigned int but;
    Dimension w,h;

    /* Go synchronous or the widgets don't resize properly */
    XSynchronize(XtDisplay(toplevel),True);
    /* If the popup isn't created yet, then create it */
    if (alertShell == NULL) {
	alertShell = XtCreatePopupShell("alertShell",transientShellWidgetClass,
							toplevel,NULL,ZERO);
	alertDialog = XtCreateManagedWidget("alertDialog",dialogWidgetClass,
							alertShell,NULL,ZERO);
	XawDialogAddButton(alertDialog,"okButton",alertOk,NULL);
	XtRealizeWidget(alertShell);
    }
    /* Set the label */
    XtSetArg(args[0],XtNlabel,str);
    XtSetValues(alertDialog,args,ONE);
    /* Center the popup over the mouse */
    XtSetArg(args[0],XtNwidth,&w);
    XtSetArg(args[1],XtNheight,&h);
    XtGetValues(alertShell,args,TWO);
    XQueryPointer(XtDisplay(toplevel),XtWindow(toplevel),
					&rwin,&child,&rx,&ry,&cx,&cy,&but);
    x = rx-w/2;
    if (x < 0)
	x = 0;
    else if (x > WidthOfScreen(XtScreen(toplevel))-w)
	x = WidthOfScreen(XtScreen(toplevel))-w;
    y = ry-h/2;
    if (y < 0)
	y = 0;
    else if (y > HeightOfScreen(XtScreen(toplevel))-h)
	y = WidthOfScreen(XtScreen(toplevel))-h;
    XtSetArg(args[0],XtNx,x);
    XtSetArg(args[1],XtNy,y);
    XtSetValues(alertShell,args,TWO);
    /* Beep */
    XBell(XtDisplay(toplevel),0);
    /* Pop it up and block until one of the buttons is clicked */
    alertDone = False;
    XtPopup(alertShell,XtGrabExclusive);
    while (!alertDone) {
	XtAppNextEvent(XtWidgetToApplicationContext(toplevel),&event);
	XtDispatchEvent(&event);
    }
    /* Okay, pop it down */
    XtPopdown(alertShell);
    /* Back to normal */
    XSynchronize(XtDisplay(toplevel),False);
}

void
alert1(fmt,arg)
char *fmt,*arg;
{
    char buf[256];

    sprintf(buf,fmt,arg);
    alert0(buf);
}

void
alert2(fmt,arg1,arg2)
char *fmt,*arg1,*arg2;
{
    char buf[256];

    sprintf(buf,fmt,arg1,arg2);
    alert0(buf);
}

/*ARGSUSED*/
void
alertOk(w,event,params,num_params)
Widget w;
XEvent *event;
String *params;
Cardinal *num_params;
{
    alertDone = True;
}
