1/* 2 3Copyright 1989, 1998 The Open Group 4 5Permission to use, copy, modify, distribute, and sell this software and its 6documentation for any purpose is hereby granted without fee, provided that 7the above copyright notice appear in all copies and that both that 8copyright notice and this permission notice appear in supporting 9documentation. 10 11The above copyright notice and this permission notice shall be included 12in all copies or substantial portions of the Software. 13 14THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS 15OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF 16MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. 17IN NO EVENT SHALL THE OPEN GROUP BE LIABLE FOR ANY CLAIM, DAMAGES OR 18OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, 19ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR 20OTHER DEALINGS IN THE SOFTWARE. 21 22Except as contained in this notice, the name of The Open Group shall 23not be used in advertising or otherwise to promote the sale, use or 24other dealings in this Software without prior written authorization 25from The Open Group. 26 27*/ 28 29/* 30 * Author: Davor Matic, MIT X Consortium 31 */ 32 33#ifdef HAVE_CONFIG_H 34# include "config.h" 35#endif 36 37#include <X11/Intrinsic.h> 38#include <X11/StringDefs.h> 39#include <X11/Shell.h> 40#include <X11/Xaw/Dialog.h> 41#include <X11/Xaw/Command.h> 42#include <X11/Xmu/CharSet.h> 43 44#include "Dialog.h" 45 46#define min(x, y) (((x) < (y)) ? (x) : (y)) 47#define max(x, y) (((x) > (y)) ? (x) : (y)) 48 49 50static void SetDialogButton(Widget w, XEvent *event, 51 String *argv, Cardinal *argc); 52 53static XtActionsRec actions_table[] = { 54 {"set-dialog-button", SetDialogButton}, 55}; 56 57static DialogButton dialog_buttons[] = { 58 {"yes", Yes}, 59 {"no", No}, 60 {"maybe", Maybe}, 61 {"okay", Okay}, 62 {"abort", Abort}, 63 {"cancel", Cancel}, 64 {"retry", Retry}, 65}; 66 67static unsigned long selected; 68 69/* ARGSUSED */ 70static void 71SetSelected(Widget w, XtPointer clientData, XtPointer callData) /* ARGSUSED */ 72{ 73 String name = (String)clientData; 74 int i; 75 76 for (i = 0; i < XtNumber(dialog_buttons); i++) 77 if (!strcmp(dialog_buttons[i].name, name)) 78 selected |= dialog_buttons[i].flag; 79} 80 81/* ARGSUSED */ 82static void 83SetDialogButton(Widget w, /* not used */ 84 XEvent *event, /* not used */ 85 String *argv, 86 Cardinal *argc) 87{ 88 char button_name[80]; 89 XtPointer dummy = NULL; 90 int i; 91 92 for (i = 0; i < *argc; i++) { 93 XmuCopyISOLatin1Lowered (button_name, argv[i]); 94 SetSelected(w, button_name, dummy); 95 } 96} 97 98static Boolean firstTime = True; 99 100Dialog 101CreateDialog(Widget top_widget, String name, unsigned long options) 102{ 103 int i; 104 Dialog popup; 105 106 popup = (Dialog) XtMalloc(sizeof(_Dialog)); 107 108 if (popup) { 109 if (firstTime) { 110 XtAddActions(actions_table, XtNumber(actions_table)); 111 firstTime = False; 112 } 113 popup->top_widget = top_widget; 114 popup->shell_widget = XtCreatePopupShell(name, 115 transientShellWidgetClass, 116 top_widget, NULL, 0); 117 popup->dialog_widget = XtCreateManagedWidget("dialog", 118 dialogWidgetClass, 119 popup->shell_widget, 120 NULL, 0); 121 for (i = 0; i < XtNumber(dialog_buttons); i++) 122 if (options & dialog_buttons[i].flag) 123 XawDialogAddButton(popup->dialog_widget, 124 dialog_buttons[i].name, 125 SetSelected, dialog_buttons[i].name); 126 popup->options = options; 127 return popup; 128 } 129 else 130 return NULL; 131} 132 133void 134PopdownDialog(Dialog popup, _XtString *answer) 135{ 136 if (answer) 137 *answer = XawDialogGetValueString(popup->dialog_widget); 138 139 XtPopdown(popup->shell_widget); 140} 141 142unsigned long 143PopupDialog(Dialog popup, String message, String suggestion, 144 _XtString *answer, XtGrabKind grab) 145{ 146 Position popup_x, popup_y, top_x, top_y; 147 Dimension popup_width, popup_height, top_width, top_height, border_width; 148 int n; 149 Arg wargs[4]; 150 151 n = 0; 152 XtSetArg(wargs[n], XtNlabel, message); n++; 153 XtSetArg(wargs[n], XtNvalue, suggestion); n++; 154 XtSetValues(popup->dialog_widget, wargs, n); 155 156 XtRealizeWidget(popup->shell_widget); 157 158 n = 0; 159 XtSetArg(wargs[n], XtNx, &top_x); n++; 160 XtSetArg(wargs[n], XtNy, &top_y); n++; 161 XtSetArg(wargs[n], XtNwidth, &top_width); n++; 162 XtSetArg(wargs[n], XtNheight, &top_height); n++; 163 XtGetValues(popup->top_widget, wargs, n); 164 165 n = 0; 166 XtSetArg(wargs[n], XtNwidth, &popup_width); n++; 167 XtSetArg(wargs[n], XtNheight, &popup_height); n++; 168 XtSetArg(wargs[n], XtNborderWidth, &border_width); n++; 169 XtGetValues(popup->shell_widget, wargs, n); 170 171 popup_x = max(0, 172 min(top_x + ((Position)top_width - (Position)popup_width) / 2, 173 (Position)DisplayWidth(XtDisplay(popup->shell_widget), 174 DefaultScreen(XtDisplay(popup->shell_widget))) - 175 (Position)popup_width - 2 * (Position)border_width)); 176 popup_y = max(0, 177 min(top_y + ((Position)top_height - (Position)popup_height) / 2, 178 (Position)DisplayHeight(XtDisplay(popup->shell_widget), 179 DefaultScreen(XtDisplay(popup->shell_widget))) - 180 (Position)popup_height - 2 * (Position)border_width)); 181 n = 0; 182 XtSetArg(wargs[n], XtNx, popup_x); n++; 183 XtSetArg(wargs[n], XtNy, popup_y); n++; 184 XtSetValues(popup->shell_widget, wargs, n); 185 186 selected = None; 187 188 XtPopup(popup->shell_widget, grab); 189 XWarpPointer(XtDisplay(popup->shell_widget), 190 XtWindow(popup->top_widget), 191 XtWindow(popup->shell_widget), 192 0, 0, top_width, top_height, 193 popup_width / 2, popup_height / 2); 194 195 while ((selected & popup->options) == None) { 196 XEvent event; 197 XtNextEvent(&event); 198 XtDispatchEvent(&event); 199 } 200 201 PopdownDialog(popup, answer); 202 203 return (selected & popup->options); 204} 205