/* * @(#)Confirm - a Yes/No confirmation window with optional prompt argument. * * From an idea contributed by Mitchell L. Model on 5-17-89 * * Copyright 1990,1991,1992 by National Semiconductor Corporation * * Permission to use, copy, modify, and distribute this software and its * documentation for any purpose is hereby granted without fee, provided that * the above copyright notice appear in all copies and that both that * copyright notice and this permission notice appear in supporting * documentation, and that the name of National Semiconductor Corporation not * be used in advertising or publicity pertaining to distribution of the * software without specific, written prior permission. * * NATIONAL SEMICONDUCTOR CORPORATION MAKES NO REPRESENTATIONS ABOUT THE * SUITABILITY OF THIS SOFTWARE FOR ANY PURPOSE. IT IS PROVIDED "AS IS" * WITHOUT EXPRESS OR IMPLIED WARRANTY. NATIONAL SEMICONDUCTOR CORPORATION * DISCLAIMS ALL WARRANTIES WITH REGARD TO THIS SOFTWARE, INCLUDING ALL IMPLIED * WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE. IN NO * EVENT SHALL NATIONAL SEMICONDUCTOR CORPORATION BE LIABLE FOR ANY SPECIAL, * INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR * PERFORMANCE OF THIS SOFTWARE. * * Author: Michael C. Wagnitz - National Semiconductor Corporation * */ #include "global.h" #define btnsepr 7 typedef struct _result { Bool *popflg; Bool *var; Widget shell; } *Result; void ProcessOneEvent(Display *display) { static XEvent event; XNextEvent(display, &event); XtDispatchEvent(&event); } /* ProcessOneEvent */ static Result MakeResult(Widget shell, int *popflg, int *resultvar) { Result rec = (Result) XtMalloc((unsigned) sizeof(struct _result)); rec->popflg = popflg; rec->var = resultvar; rec->shell = shell; return rec; } /* MakeResult */ /* ARGSUSED */ /* ** ClearConfirm - get rid of the confirmation box. */ void ClearConfirm(Widget w, int val, Result result) { XtPopdown(result->shell); XtDestroyWidget(result->shell); *result->popflg = FALSE; *result->var = val; } /* ClearConfirm */ /* ARGSUSED */ void Yes(Widget w, XtPointer closure, XtPointer call_data) /* unused */ { Result result = (Result) closure; ClearConfirm(w, TRUE, result); } /* ARGSUSED */ void No(Widget w, XtPointer closure, XtPointer call_data) /* unused */ { Result result = (Result) closure; ClearConfirm(w, FALSE, result); } /* No */ /* * Confirm - put up a window asking for confirmation. */ Bool Confirm(char *prompt) { int root_x, root_y, child_x, child_y; int nargs, buttons, labelwidth, yeswidth, btnborder, btnwidth; Dimension rWidth, rBorder, rHeight; Bool popped_up = FALSE, result = FALSE; String query = NULL; String Translations = ",:\n"; Window root, child; Widget shell, form, label, yes, no; Arg args[4]; Result resultrec; /* ** First, find out if expert flag is set. If so, just return True. */ if (XMail.expert == TRUE) return TRUE; /* ** Find out where the mouse is, so we can put the confirmation ** box right there. */ XQueryPointer(XtDisplay(toplevel), XtWindow(toplevel), &root, &child, &root_x, &root_y, &child_x, &child_y, &buttons); /* ** Construct the confirmation box */ shell=XtCreatePopupShell("Confirm",overrideShellWidgetClass,toplevel,args,0); XtSetArg(args[0], XtNtranslations, XtParseTranslationTable(Translations)); XtSetArg(args[1], XtNborderWidth, 0); form = XtCreateManagedWidget("form", formWidgetClass, shell, args, 2); if (! prompt) label = NULL; else { if (query = (String) XtMalloc((unsigned) strlen(prompt) + 2)) { (void) strcpy(query, prompt); (void) strcat(query, "?"); XtSetArg(args[0], XtNlabel, query); } else XtSetArg(args[0], XtNlabel, ""); XtSetArg(args[1], XtNjustify, XtJustifyCenter); XtSetArg(args[2], XtNborderWidth, 0); label = XtCreateManagedWidget("prompt", labelWidgetClass, form, args, 3); XtFree((String) query); /* XtFree tests if target is null */ } nargs = 0; XtSetArg(args[nargs], XtNhorizDistance, btnsepr); nargs++; if (prompt) { XtSetArg(args[nargs], XtNfromVert, label); nargs++; XtSetArg(args[nargs], XtNvertDistance, 12); nargs++; } yes = XtCreateManagedWidget("yes", commandWidgetClass, form, args, nargs); nargs = 1; XtSetArg(args[nargs], XtNfromHoriz, yes); nargs++; if (prompt) { XtSetArg(args[nargs], XtNfromVert, label); nargs++; XtSetArg(args[nargs], XtNvertDistance, 12); nargs++; } no = XtCreateManagedWidget("no", commandWidgetClass, form, args, nargs); if (! label) labelwidth = 0; else { XtSetArg(args[0], XtNwidth, &rWidth); XtGetValues(label, args, ONE); labelwidth = (int) rWidth; } XtSetArg(args[0], XtNwidth, &rWidth); XtSetArg(args[1], XtNborder, &rBorder); XtGetValues(yes, args, TWO); yeswidth = (int) rWidth; btnborder = (int) rBorder; btnwidth = (labelwidth - btnsepr - (2 * btnborder)) / 2; if (btnwidth < yeswidth) btnwidth = yeswidth; XtSetArg(args[0], XtNwidth, btnwidth); XtSetValues(yes, args, ONE); XtSetValues(no, args, ONE); XtRealizeWidget(shell); XtSetArg(args[0], XtNwidth, &rWidth); XtSetArg(args[1], XtNheight, &rHeight); XtGetValues(shell, args, TWO); root_x -= ( (int) rWidth) / 2; root_y -= ( (int) rHeight) / 2; /* ** Keep confirm popup within root window borders (don't place it off-screen) */ if (root_x + (int)rWidth > RootWidth) root_x = RootWidth - rWidth ; if (root_x < 0) root_x = 0; if (root_y + (int)rHeight > RootHeight) root_y = RootHeight - rHeight; if (root_y < 0) root_y = 0; XtSetArg(args[0], XtNx, root_x); XtSetArg(args[1], XtNy, root_y); XtSetValues(shell, args, TWO); resultrec = MakeResult(shell, &popped_up, &result); XtAddCallback(yes, XtNcallback, Yes, (XtPointer)resultrec); XtAddCallback(no, XtNcallback, No, (XtPointer)resultrec); if (XMail.bellRing) /* ring bell if not silenced by user */ XBell (XtDisplay (toplevel), 33); XtPopup(shell, XtGrabExclusive); popped_up = TRUE; while (popped_up) ProcessOneEvent(XtDisplay(shell)); return result; } /* Confirm */