1 /*
2  *  [ This file is blatantly borrowed from the pixmap distribution. ]
3  *  [ It was written by the fellows below, and they disclaim all    ]
4  *  [ warranties, expressed or implied, in this software.           ]
5  *  [ As if anyone cares about that...                              ]
6  *
7  * Copyright 1991 Lionel Mallet
8  *
9  * Author:  Davor Matic, MIT X Consortium
10  */
11 
12 
13 #include <stdio.h>
14 #include <stdlib.h>
15 #include <X11/Intrinsic.h>
16 #include <X11/StringDefs.h>
17 #include <X11/Xos.h>
18 #include <X11/Shell.h>
19 #include <X11/Xatom.h>
20 #include <X11/Xaw/Dialog.h>
21 #include <X11/Xaw/Command.h>
22 #include <X11/Xaw/AsciiText.h>
23 
24 #include "Dialog.h"
25 
26 
27 
28 #define min(x, y)                     (((x) < (y)) ? (x) : (y))
29 #define max(x, y)                     (((x) > (y)) ? (x) : (y))
30 
31 static int selected;
32 static DialogButton dialog_buttons[] = {
33     {"Yes", Yes},
34     {"No", No},
35     {"Okay", Okay},
36     {"Abort", Abort},
37     {"Cancel", Cancel},
38     {"Retry", Retry},
39 };
40 
41 
42 
43 
SetSelected(w,client_data,call_data)44 static void SetSelected(w, client_data, call_data)
45      Widget w;
46      XtPointer client_data, call_data;
47 {
48   selected = (int)client_data;
49 }
50 
51 
52 /*
53  * Can't make this static because we need to be able to access the
54  * name over in display.c to properly set the resources we want.
55  */
SetOkay(w)56 void SetOkay(w)
57      Widget w;
58 {
59   SetSelected(w, Okay | Yes );
60 }
61 
62 
63 
64 
CreateDialog(Widget top_widget,char * name,int options)65 Dialog CreateDialog(Widget top_widget, char *name, int options)
66 {
67   int i;
68   Dialog popup;
69 
70   if ((popup = (Dialog) XtMalloc(sizeof(_Dialog))) == NULL)
71     return NULL;
72 
73 
74   popup->top_widget = top_widget;
75   popup->shell_widget = XtCreatePopupShell(name,
76 					   transientShellWidgetClass,
77 					   top_widget, NULL, 0);
78   popup->dialog_widget = XtCreateManagedWidget("dialog",
79 					       dialogWidgetClass,
80 					       popup->shell_widget,
81 					       NULL, 0);
82 
83   for (i = 0; i < XtNumber(dialog_buttons); i++)
84     if (options & dialog_buttons[i].flag)
85       XawDialogAddButton(popup->dialog_widget,
86 			 dialog_buttons[i].name,
87 			 SetSelected, (XtPointer)dialog_buttons[i].flag);
88 
89   popup->options = options;
90   return popup;
91 }
92 
93 
FreeDialog(Dialog dialog)94 void FreeDialog(Dialog dialog)
95 {
96   if (dialog == NULL)
97     return;
98 
99   XtDestroyWidget(dialog->shell_widget);
100   XtFree((char *)dialog);
101 }
102 
103 
104 
PositionPopup(Widget shell_widget)105 void PositionPopup(Widget shell_widget)
106 {
107   int n;
108   Arg wargs[10];
109   Position popup_x, popup_y, top_x, top_y;
110   Dimension popup_width, popup_height, top_width, top_height, border_width;
111 
112   n = 0;
113   XtSetArg(wargs[n], XtNx, &top_x); n++;
114   XtSetArg(wargs[n], XtNy, &top_y); n++;
115   XtSetArg(wargs[n], XtNwidth, &top_width); n++;
116   XtSetArg(wargs[n], XtNheight, &top_height); n++;
117   XtGetValues(XtParent(shell_widget), wargs, n);
118 
119   n = 0;
120   XtSetArg(wargs[n], XtNwidth, &popup_width); n++;
121   XtSetArg(wargs[n], XtNheight, &popup_height); n++;
122   XtSetArg(wargs[n], XtNborderWidth, &border_width); n++;
123   XtGetValues(shell_widget, wargs, n);
124 
125   popup_x = max(0,
126 		min(top_x + ((Position)top_width - (Position)popup_width) / 2,
127 		    (Position)DisplayWidth(XtDisplay(shell_widget),
128 			       DefaultScreen(XtDisplay(shell_widget))) -
129 		    (Position)popup_width - 2 * (Position)border_width));
130   popup_y = max(0,
131 		min(top_y+((Position)top_height - (Position)popup_height) / 2,
132 		    (Position)DisplayHeight(XtDisplay(shell_widget),
133 			       DefaultScreen(XtDisplay(shell_widget))) -
134 		    (Position)popup_height - 2 * (Position)border_width));
135   n = 0;
136   XtSetArg(wargs[n], XtNx, popup_x); n++;
137   XtSetArg(wargs[n], XtNy, popup_y); n++;
138   XtSetValues(shell_widget, wargs, n);
139 }
140 
141 
142 
PopupDialog(XtAppContext app_con,Dialog popup,char * message,char * suggestion,char ** answer,XtGrabKind grab)143 int PopupDialog(XtAppContext app_con, Dialog popup, char *message,
144 		char *suggestion, char **answer, XtGrabKind grab)
145 {
146   int n, height = 35;
147   Arg wargs[8];
148   Widget value;
149 
150   n = 0;
151   XtSetArg(wargs[n], XtNlabel, message); n++;
152   if (suggestion)
153    {
154      XtSetArg(wargs[n], XtNvalue, suggestion); n++;
155    }
156   XtSetValues(popup->dialog_widget, wargs, n);
157 
158 
159   /*
160    * Here we get ahold of the ascii text widget for the dialog box (if it
161    * exists) and we set some useful resources in it.
162    */
163   value = XtNameToWidget(popup->dialog_widget, "value");
164 
165   n = 0;
166   XtSetArg(wargs[n], XtNresizable,        True);                n++;
167   XtSetArg(wargs[n], XtNheight,           height);              n++;
168   XtSetArg(wargs[n], XtNwidth,            250);                 n++;
169   XtSetArg(wargs[n], XtNresize,           XawtextResizeHeight); n++;
170   XtSetArg(wargs[n], XtNscrollHorizontal, XawtextScrollWhenNeeded); n++;
171   if (value)
172     XtSetValues(value, wargs, n);
173 
174 
175   XtRealizeWidget(popup->shell_widget);
176 
177   PositionPopup(popup->shell_widget);
178 
179   selected = Empty;
180 
181   XtPopup(popup->shell_widget, grab);
182 
183 
184   while ((selected & popup->options) == Empty)
185    {
186      XEvent event;
187 
188      XtAppNextEvent(app_con, &event);
189      XtDispatchEvent(&event);
190    }
191 
192   PopdownDialog(popup, answer);
193 
194   return (selected & popup->options);
195 }
196 
197 
198 
199 
PopdownDialog(Dialog popup,char ** answer)200 void PopdownDialog(Dialog popup, char **answer)
201 {
202     if (answer)
203       *answer = XawDialogGetValueString(popup->dialog_widget);
204 
205     XtPopdown(popup->shell_widget);
206 }
207