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