/* yesno.c - a yes no popup box * * This extends a Motif Dialog Box to be synchronous and return a value. * * Usage: * int ret; * XtCallbackProc proc; * Widget w; * * ret = YesNoBox("message", "OK button text", "cancel button text", * proc, w); * * proc is a pointer to an XtCallbackProc you want invoked on button * press. Normally you should pass NULL for this parameter * w is a widget it to position the dialog at. It MUST be * a valid widget id. * * returns: * YesNoYes OK button was pressed * YesNoCancel cancel button was pressed * YesNoHelp help button was pressed * */ /* * Edit History: * 03/03/92 tony - make standalone version */ #include #include #include #include "stdio.h" #include "yesno.h" /* The yes or no box */ int dlevel; static Widget YesNoBoxShell = NULL; /* the popup shell it goes in */ static Widget theYesNoBox; /* wiget holding warning dialog */ static int theYesNoReturn; /* the return value */ static int YesNoBoxIsActive; /* Is the box up */ static XtCallbackProc theYesNoProc; #if NeedFunctionPrototypes typedef void (*CBProc)(Widget, XtPointer, XtPointer); Widget CreateyesNoBox(Widget); /* Produced by the builder */ #else typedef void (*CBProc)(); Widget CreateyesNoBox(); /* Produced by the builder */ #endif /* Create the shell for the yes no box */ #ifdef _NO_PROTO void YesNoInitialize(AppShell) Widget AppShell; #else void YesNoInitialize(Widget AppShell) #endif { Arg args[10]; int argcnt; Widget p; if(YesNoBoxShell) return; while( p = XtParent(AppShell) ) { AppShell = p; } argcnt = 0; XtSetArg(args[argcnt], XmNx, 480); argcnt++; XtSetArg(args[argcnt], XmNy, 380); argcnt++; XtSetArg(args[argcnt], XtNallowShellResize, 1); argcnt++; YesNoBoxShell = XtCreatePopupShell("yesNo", transientShellWidgetClass, AppShell, args, argcnt); theYesNoBox = CreateyesNoBox(YesNoBoxShell); return; } #if XtSpecificationRelease < 5 extern XtTranslateCoords(Widget w, Position parent_x, Position parent_y, Position * root_x, Position * root_y); #endif #ifdef _NO_PROTO int YesNoBox(mess, yes, no, proc, w) char *mess; char *yes, *no; XtCallbackProc proc; Widget w; #else int YesNoBox(char *mess, char *yes, char *no, XtCallbackProc proc, Widget w) #endif { XmString xmstr; Arg args[10]; int argcnt; Widget ok_button, cancel_button, help_button; XEvent event; XButtonEvent *b; int retval; Position ok_x, ok_y; Position cancel_x, cancel_y; Position help_x, help_y; Dimension ok_width, ok_height; Dimension cancel_width, cancel_height; Dimension help_width, help_height; Position parent_x, parent_y; Position root_x, root_y; char geo[50]; XtAppContext context; if(YesNoBoxShell == NULL) { /* fprintf(stderr, "You forgot to call YesNoInitialize.\n");*/ YesNoInitialize(w); } if(YesNoBoxShell == NULL) { fprintf(stderr, "Did not work.\n"); return 1; } theYesNoProc = proc; context = XtWidgetToApplicationContext(theYesNoBox); argcnt = 0; XtSetArg(args[argcnt], XmNx, &parent_x); argcnt++; XtSetArg(args[argcnt], XmNy, &parent_y); argcnt++; XtGetValues(w, args, argcnt); XtTranslateCoords(w, parent_x, parent_y, &root_x, &root_y); /* printf("Try to pop up at %d,%d.\n", root_x, root_y); */ argcnt = 0; XtSetArg(args[argcnt], XmNx, root_x + 10); argcnt++; XtSetArg(args[argcnt], XmNy, root_y + 10); argcnt++; sprintf(geo, "+%d+%d", root_x+10, root_y+10); XtSetArg(args[argcnt], XmNgeometry, geo); argcnt++; XtSetValues(YesNoBoxShell, args, argcnt); cancel_button = XmMessageBoxGetChild(theYesNoBox, XmDIALOG_CANCEL_BUTTON); if(no && *no) { xmstr=XmStringCreateLtoR(no, XmSTRING_DEFAULT_CHARSET); } else { xmstr=XmStringCreateLtoR("No", XmSTRING_DEFAULT_CHARSET); } argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, xmstr); argcnt++; XtSetValues(cancel_button, args, argcnt); XmStringFree(xmstr); ok_button = XmMessageBoxGetChild(theYesNoBox, XmDIALOG_OK_BUTTON); if(yes && *yes) { xmstr=XmStringCreateLtoR(yes, XmSTRING_DEFAULT_CHARSET); } else { xmstr=XmStringCreateLtoR("Yes", XmSTRING_DEFAULT_CHARSET); } argcnt = 0; XtSetArg(args[argcnt], XmNlabelString, xmstr); argcnt++; XtSetValues(ok_button, args, argcnt); XmStringFree(xmstr); argcnt = 0; xmstr = XmStringCreateLtoR(mess, XmSTRING_DEFAULT_CHARSET); XtSetArg(args[argcnt], XmNmessageString, xmstr); argcnt++; XtSetValues(theYesNoBox, args, argcnt); XmStringFree(xmstr); if(!XtIsManaged(theYesNoBox)) XtManageChild(theYesNoBox); if(dlevel > 0) { XtPopup(YesNoBoxShell, XtGrabNone); } else { XtPopup(YesNoBoxShell, XtGrabExclusive); } /* printf("after yesno popup\n"); fflush(stdout); */ /* Find the positions of the buttons so we can map the button * click position back to something useful */ argcnt = 0; XtSetArg(args[argcnt], XmNx, &ok_x); argcnt++; XtSetArg(args[argcnt], XmNy, &ok_y); argcnt++; XtSetArg(args[argcnt], XmNwidth, &ok_width); argcnt++; XtSetArg(args[argcnt], XmNheight, &ok_height); argcnt++; XtGetValues(ok_button, args, argcnt); /*printf("ok_button=%x x=%d y=%d w=%d h=%d\n",XtWindow(ok_button), ok_x,ok_y,ok_width,ok_height); */ argcnt = 0; XtSetArg(args[argcnt], XmNx, &cancel_x); argcnt++; XtSetArg(args[argcnt], XmNy, &cancel_y); argcnt++; XtSetArg(args[argcnt], XmNwidth, &cancel_width); argcnt++; XtSetArg(args[argcnt], XmNheight, &cancel_height); argcnt++; XtGetValues(cancel_button, args, argcnt); /*printf("cancel_button=%x x=%d y=%d w=%d h=%d\n",XtWindow(cancel_button),cancel_x,cancel_y,cancel_width,cancel_height); */ help_button = XmMessageBoxGetChild(theYesNoBox, XmDIALOG_HELP_BUTTON); argcnt = 0; XtSetArg(args[argcnt], XmNx, &help_x); argcnt++; XtSetArg(args[argcnt], XmNy, &help_y); argcnt++; XtSetArg(args[argcnt], XmNwidth, &help_width); argcnt++; XtSetArg(args[argcnt], XmNheight, &help_height); argcnt++; XtGetValues(help_button, args, argcnt); /*printf("help_button=%x x=%d y=%d w=%d h=%d\n",XtWindow(help_button),help_x,help_y,help_width,help_height); */ /* Do our own main loop so the box is always application modal * no matter what window manager we are running. */ /* The loop may be terminated by YesNoBoxCallback */ YesNoBoxIsActive = 1; while(YesNoBoxIsActive) { XtAppNextEvent(context, &event); if(event.type == ButtonPress) { b = &event.xbutton; /*printf("Got Button event at window %x (%d,%d).\n", b->window, b->x, b->y); */ if (ok_x <= b->x && b->x <= ok_x + ok_width && ok_y <= b->y && b->y <= ok_y + ok_height) { /* printf("clicked on ok button\n"); */ theYesNoReturn = YesNoYes; break; } else if (cancel_x <= b->x && b->x <= cancel_x + cancel_width && cancel_y <= b->y && b->y <= cancel_y + cancel_height) { /* printf("clicked on cancel button\n"); */ theYesNoReturn = YesNoCancel; break; } else if (help_x <= b->x && b->x <= help_x + help_width && help_y <= b->y && b->y <= help_y + help_height) { /* printf("clicked on help button\n"); */ theYesNoReturn = YesNoHelp; break; } } else { XtDispatchEvent(&event); } } XtPopdown(YesNoBoxShell); return(theYesNoReturn); } /* Remove help and cancel buttons from a message box */ #ifndef _NO_PROTO static void YesNoBoxCreation(Widget w, XtPointer client, XtPointer call) #else static void YesNoBoxCreation(w, client, call) Widget w; XtPointer client; XtPointer call; #endif { Widget c; XmAnyCallbackStruct *acs=(XmAnyCallbackStruct*)call; /* printf("I am in YesNoBoxCreation\n"); */ theYesNoBox = w; } /* This routine is called when one of the Yes/No box buttons is activated * by the keyboard */ #ifdef _NO_PROTO static void YesNoBoxCallback(w, client, call) Widget w; XtPointer client; XtPointer call; #else static void YesNoBoxCallback(Widget w, XtPointer client, XtPointer call) #endif { XmAnyCallbackStruct *acs=(XmAnyCallbackStruct*)call; int type = (int) client; /*DEBUG printf("I am in YesBoxCallback: status %d.\n", type); */ if(theYesNoProc) { (*theYesNoProc)(w, client, call); } theYesNoProc = NULL; /* Do not all it to trigger again */ theYesNoReturn = type; /* Set the return for YesNoBox */ YesNoBoxIsActive = 0; /* Make our main loop terminate */ XtPopdown(XtParent(w)); } Widget CreateyesNoBox(parent) Widget parent; { Arg args[512]; Cardinal argcnt; /*SUPPRESS 591*/ Boolean argok; Widget retval; /*SUPPRESS 591*/ XmString xmstr[32]; Widget yesNoBox; XtInitializeWidgetClass(xmMessageBoxWidgetClass); argcnt = 0; XtSetArg(args[argcnt], XmNresizePolicy, XmRESIZE_ANY); argcnt++; XtSetArg(args[argcnt], XmNdialogType, XmDIALOG_WARNING); argcnt++; XtSetArg(args[argcnt], XmNmessageString, (xmstr[0]=XmStringCreateLtoR( "message\n\ message\n\ message", XmSTRING_DEFAULT_CHARSET))); argcnt++; XtSetArg(args[argcnt], XmNx, 0); argcnt++; XtSetArg(args[argcnt], XmNy, 0); argcnt++; yesNoBox = XtCreateWidget("yesNoBox", xmMessageBoxWidgetClass, parent, args, argcnt); XmStringFree( xmstr[0] ); YesNoBoxCreation(yesNoBox, (XtPointer)0, (XtPointer)0); XtAddCallback(yesNoBox, XmNhelpCallback, YesNoBoxCallback, (XtPointer) YesNoHelp); XtAddCallback(yesNoBox, XmNokCallback, YesNoBoxCallback, (XtPointer) YesNoYes); XtAddCallback(yesNoBox, XmNcancelCallback, YesNoBoxCallback, (XtPointer) YesNoCancel); retval = yesNoBox; return retval; }