1 /*
2 * Copyright 1993, 1994 Liverpool University Computer Science Department
3 *
4 * Permission to use, copy, modify, and distribute this software and its
5 * documentation for any purpose and without fee is hereby granted, provided
6 * that the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of L.U.C.S. not be used in advertising
9 * or publicity pertaining to distribution of the software without specific,
10 * written prior permission. L.U.C.S. makes no representations about the
11 * suitability of this software for any purpose. It is provided "as is"
12 * without express or implied warranty.
13 *
14 * FILE NAME: XbrDialog.c
15 * CREATED: Thu Oct 28 1993
16 * AUTHOR: Rik Turnbull (rik@csc.liv.ac.uk)
17 * DESCRIPTION: Deals with popping up Xm dialog boxes.
18 *
19 */
20
21 #include <Xm/Xm.h>
22 #include <Xm/MessageB.h>
23 #include <Xm/FileSB.h>
24 #include <Xm/SelectioB.h>
25
26 #include <stdio.h>
27 #include <stdarg.h>
28
29 #include "XbrCB.h"
30 #include "XbrCursor.h"
31 #include "XbrFSB.h"
32 #include "XbrRes.h"
33
34 #if (XmVERSION < 1) || ((XmVERSION == 1) && (XmREVISION < 2))
35 #define XmStringCreateLocalized(string) XmStringCreateLtoR(string,XmSTRING_DEFAULT_CHARSET)
36 #endif
37
38 #define XbrDIALOG_NOACTION -1
39
40 void XbrDialogError(Widget, ...);
41 int XbrDialogQuestion(Widget, char *, char *, ...);
42 char *XbrDialogFSBox(Widget, char *, char *);
43 char *XbrDialogPrompt(Widget, ...);
44 static void XbrDialogCBYes(Widget, XtPointer, XtPointer);
45 static void XbrDialogCBNo(Widget, XtPointer, XtPointer);
46
47 /* XbrDialogError:************************************************************/
48 /* XbrDialogError: Display an error dialog containing the given error msg */
49 /* XbrDialogError: in printf format. */
50 /* XbrDialogError:************************************************************/
51
XbrDialogError(Widget parent,...)52 void XbrDialogError(Widget parent, ...)
53 {
54 char *fmt, buffer[BUFSIZ];
55 Display *display = XtDisplay(parent);
56 va_list argp;
57 Arg args[10];
58 int n;
59 Widget w;
60
61 /* Get format string */
62 va_start(argp, parent);
63 fmt = va_arg( argp, char *);
64 vsprintf(buffer, fmt, argp);
65 va_end(argp);
66
67 /* Create widgets */
68 n = 0;
69 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
70 w = XmCreateErrorDialog(parent, "message", args, n);
71 XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_HELP_BUTTON));
72 XtUnmanageChild(XmMessageBoxGetChild(w, XmDIALOG_CANCEL_BUTTON));
73
74 /* Register a callback which destroys the widget & another to reset the
75 cursor.
76 */
77 XtAddCallback(w, XmNokCallback, XbrCBDestroyWidget, w);
78 XtAddCallback(w, XmNdestroyCallback, XbrCursorDeleteCB, NULL);
79
80 /* Set error message */
81 XtVaSetValues(w, XtVaTypedArg, XmNmessageString, XmRString, buffer,
82 sizeof(char *), NULL);
83
84 /* Sound bell */
85 XBell(display, 50);
86
87 /* Display the Error Box */
88 XtManageChild(w);
89 XbrCursorAdd(w, XbrGRAB);
90 }
91
92 /* XbrDialogQuestion:*********************************************************/
93 /* XbrDialogQuestion: Pop up a question dialog and take over the event loop. */
94 /* XbrDialogQuestion: When we have an answer, exit the event loop and return */
95 /* XbrDialogQuestion: the answer. */
96 /* XbrDialogQuestion:*********************************************************/
97
XbrDialogQuestion(Widget parent,char * yes,char * no,...)98 int XbrDialogQuestion(Widget parent, char *yes, char *no, ...)
99 {
100 static int action = XbrDIALOG_NOACTION;
101 char *fmt, buffer[BUFSIZ];
102 va_list argp;
103 Arg args[10];
104 int n;
105 XEvent event;
106 Widget w;
107 XmString yes_string, no_string, msg_string;
108
109 /* Get format string */
110 va_start(argp, no);
111 fmt = va_arg( argp, char *);
112 vsprintf(buffer, fmt, argp);
113 va_end(argp);
114
115 /* Create widgets */
116 n = 0;
117 yes_string = XmStringCreateLocalized(yes);
118 no_string = XmStringCreateLocalized(no);
119 msg_string = XmStringCreateLocalized(buffer);
120 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
121 XtSetArg(args[n], XmNcancelLabelString, no_string); n++;
122 XtSetArg(args[n], XmNokLabelString, yes_string); n++;
123 XtSetArg(args[n], XmNmessageString, msg_string); n++;
124 w = XmCreateQuestionDialog(parent, "question", args, n);
125 XmStringFree(yes_string); XmStringFree(no_string); XmStringFree(msg_string);
126 XtUnmanageChild(XmMessageBoxGetChild(w,XmDIALOG_HELP_BUTTON));
127
128 /* Register callbacks which reset the cursor and destroy the widgets */
129 XtAddCallback(w, XmNokCallback, XbrDialogCBYes, (XtPointer) &action);
130 XtAddCallback(w, XmNokCallback, XbrCBDestroyWidget, w);
131 XtAddCallback(w, XmNcancelCallback, XbrDialogCBNo, (XtPointer) &action);
132 XtAddCallback(w, XmNcancelCallback, XbrCBDestroyWidget, w);
133 XtAddCallback(w, XmNdestroyCallback, XbrCursorDeleteCB, NULL);
134
135 /* Display the Question Box */
136 XtManageChild(w);
137 XbrCursorAdd(w, XbrGRAB);
138
139 /* Take over the event loop */
140 action = XbrDIALOG_NOACTION;
141 while(action == XbrDIALOG_NOACTION) {
142 XtAppNextEvent(XtWidgetToApplicationContext(parent), &event);
143 XtDispatchEvent(&event);
144 }
145
146 return(action);
147 }
148
149 /* XbrDialogCBYes:************************************************************/
150 /* XbrDialogCBYes: Set the client_data to yes. */
151 /* XbrDialogCBYes:************************************************************/
152
XbrDialogCBYes(Widget w,XtPointer client_data,XtPointer call_data)153 static void XbrDialogCBYes(Widget w, XtPointer client_data, XtPointer call_data)
154 {
155 int *ptr = (int *) client_data;
156
157 *ptr = 1;
158 }
159
160 /* XbrDialogCBNo:*************************************************************/
161 /* XbrDialogCBNo: Set the client_data to no. */
162 /* XbrDialogCBNo:************************************************************/
163
XbrDialogCBNo(Widget w,XtPointer client_data,XtPointer call_data)164 static void XbrDialogCBNo(Widget w, XtPointer client_data, XtPointer call_data)
165 {
166 int *ptr = (int *) client_data;
167
168 *ptr = 0;
169 }
170
171 /*----------------------------------------------------------------------------
172 XbrDialogFSBox()
173 Popup a file selection box and get the filename.
174
175 Widget w Parent shell of file selection box
176 char *selection Selection string
177 char *filename Suggested filename
178 ----------------------------------------------------------------------------*/
XbrDialogFSBox(Widget w,char * selection,char * filename)179 char *XbrDialogFSBox(Widget w, char *selection, char *filename)
180 {
181 static Widget FSBShell = NULL, FSB;
182 static int action = XbrDIALOG_NOACTION;
183 XEvent event;
184 XmString string;
185 Arg args[10];
186 Cardinal n;
187 char *text, buffer[256];
188
189 /* Build main windows */
190 if(FSBShell == NULL) {
191 FSBShell = XtCreatePopupShell("File Selection",topLevelShellWidgetClass,
192 w, NULL, 0);
193 FSB = XtVaCreateManagedWidget("XbrlibFSB",xmFileSelectionBoxWidgetClass,
194 FSBShell, NULL);
195
196 /* Unmanage HELP button */
197 XtUnmanageChild(XmFileSelectionBoxGetChild(FSB, XmDIALOG_HELP_BUTTON));
198
199 /* Cursor callbacks */
200 XtAddCallback(FSBShell, XmNpopupCallback, XbrCursorAddCB,
201 (XtPointer)XbrGRAB);
202 XtAddCallback(FSBShell, XmNpopdownCallback, XbrCursorDeleteCB, NULL);
203 XtAddCallback(FSBShell, XmNpopdownCallback, XbrCBRefresh, NULL);
204
205 /* OK Callbacks */
206 XtAddCallback(FSB, XmNokCallback, XbrDialogCBYes, &action);
207 XtAddCallback(FSB, XmNokCallback, XbrCBPopdownShell, FSBShell);
208
209 /* CANCEL Callbacks */
210 XtAddCallback(FSB, XmNcancelCallback, XbrDialogCBNo, &action);
211 XtAddCallback(FSB, XmNcancelCallback, XbrCBPopdownShell, FSBShell);
212 }
213
214 /* Set the selection. */
215 if(selection == NULL)
216 string = XmStringCreateLocalized("Selection");
217 else
218 string = XmStringCreateLocalized(selection);
219
220 n = 0;
221 XtSetArg(args[n], XmNselectionLabelString, string); n++;
222 XtSetValues(FSB, args, n);
223 XmStringFree(string);
224
225 /* Re-search the filenames. */
226 n = 0;
227 XtSetArg(args[n], XmNdirMask, &string); n++;
228 XtGetValues(FSB, args, n);
229 XmFileSelectionDoSearch(FSB, string);
230 XmStringFree(string);
231
232 /* Set the suggested filename. */
233 text = XbrFSBSelection(FSB);
234 sprintf(buffer, "%s/%s", fname_dirname(text), filename?filename:"");
235 string = XmStringCreateLocalized(buffer);
236 n = 0;
237 XtSetArg(args[n], XmNdirSpec, string); n++;
238 XtSetValues(FSB, args, n);
239 XmStringFree(string);
240
241 /* Display the File Selection Box */
242 XtPopup(FSBShell, XtGrabExclusive);
243
244 /* Take over the event loop */
245 action = XbrDIALOG_NOACTION;
246 while(action == XbrDIALOG_NOACTION) {
247 XtAppNextEvent(XtWidgetToApplicationContext(w), &event);
248 XtDispatchEvent(&event);
249 }
250
251 /* What happened */
252 if(action)
253 return(XtNewString(XbrFSBSelection(FSB)));
254 else
255 return(NULL);
256 }
257
258 /*----------------------------------------------------------------------------
259 XbrDialogPrompt()
260 Prompt the user for a command or string.
261
262 Widget w The parent widget of the dialog
263 ... Variable argument of printf style statements
264 ----------------------------------------------------------------------------*/
XbrDialogPrompt(Widget w,...)265 char *XbrDialogPrompt(Widget w, ...)
266 {
267 Widget Prompt = NULL;
268 static int action = XbrDIALOG_NOACTION;
269 XEvent event;
270 XmString string;
271 Arg args[10];
272 Cardinal n;
273 char *fmt, buffer[BUFSIZ];
274 va_list argp;
275
276 /* Get format string */
277 va_start(argp, w);
278 fmt = va_arg( argp, char *);
279 vsprintf(buffer, fmt, argp);
280 va_end(argp);
281
282 /* Build main windows */
283 n = 0;
284 string = XmStringCreateLocalized(buffer);
285 XtSetArg(args[n], XmNdialogStyle, XmDIALOG_FULL_APPLICATION_MODAL); n++;
286 XtSetArg(args[n], XmNselectionLabelString, string); n++;
287 Prompt = XmCreatePromptDialog(w, "XbrPrompt", args, n);
288 XmStringFree(string);
289
290 /* Get rid of the HELP button */
291 XtUnmanageChild(XmSelectionBoxGetChild(Prompt, XmDIALOG_HELP_BUTTON));
292
293 /* Cursor callbacks */
294 XtAddCallback(XtParent(Prompt), XmNpopupCallback, XbrCursorAddCB,(XtPointer)XbrGRAB);
295 XtAddCallback(XtParent(Prompt), XmNdestroyCallback, XbrCursorDeleteCB, NULL);
296
297 /* OK Callbacks */
298 XtAddCallback(Prompt, XmNokCallback, XbrDialogCBYes, &action);
299 XtAddCallback(Prompt, XmNokCallback, XbrCBDestroyWidget, Prompt);
300
301 /* CANCEL Callbacks */
302 XtAddCallback(Prompt, XmNcancelCallback, XbrDialogCBNo, &action);
303 XtAddCallback(Prompt, XmNcancelCallback, XbrCBDestroyWidget, Prompt);
304
305 /* Display the Prompt */
306 XtManageChild(Prompt);
307
308 /* Take over the event loop */
309 action = XbrDIALOG_NOACTION;
310 while(action == XbrDIALOG_NOACTION) {
311 XtAppNextEvent(XtWidgetToApplicationContext(w), &event);
312 XtDispatchEvent(&event);
313 }
314
315 /* What happened */
316 if(action)
317 return(XbrResGetString(Prompt, XmNtextString));
318 else
319 return(NULL);
320 }
321