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