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