Dialog.c revision cbc4e2be
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
33eaef79e5Smrg#include <X11/Intrinsic.h>
34eaef79e5Smrg#include <X11/StringDefs.h>
35eaef79e5Smrg#include <X11/Shell.h>
36eaef79e5Smrg#include <X11/Xaw/Dialog.h>
37eaef79e5Smrg#include <X11/Xaw/Command.h>
38eaef79e5Smrg#include <X11/Xmu/CharSet.h>
39cbc4e2beSmrg
40eaef79e5Smrg#include "Dialog.h"
41eaef79e5Smrg
42eaef79e5Smrg#define min(x, y)                     (((x) < (y)) ? (x) : (y))
43eaef79e5Smrg#define max(x, y)                     (((x) > (y)) ? (x) : (y))
44eaef79e5Smrg
45eaef79e5Smrg
46cbc4e2beSmrgstatic void SetDialogButton(Widget w, XEvent *event,
47eaef79e5Smrg			    String *argv, Cardinal *argc);
48eaef79e5Smrg
49eaef79e5Smrgstatic XtActionsRec actions_table[] = {
50eaef79e5Smrg  {"set-dialog-button", SetDialogButton},
51eaef79e5Smrg};
52eaef79e5Smrg
53eaef79e5Smrgstatic DialogButton dialog_buttons[] = {
54eaef79e5Smrg    {"yes", Yes},
55eaef79e5Smrg    {"no", No},
56eaef79e5Smrg    {"maybe", Maybe},
57eaef79e5Smrg    {"okay", Okay},
58eaef79e5Smrg    {"abort", Abort},
59eaef79e5Smrg    {"cancel", Cancel},
60eaef79e5Smrg    {"retry", Retry},
61eaef79e5Smrg};
62eaef79e5Smrg
63eaef79e5Smrgstatic unsigned long selected;
64eaef79e5Smrg
65eaef79e5Smrg/* ARGSUSED */
66cbc4e2beSmrgstatic void
67eaef79e5SmrgSetSelected(Widget w, XtPointer clientData, XtPointer callData) /* ARGSUSED */
68eaef79e5Smrg{
69eaef79e5Smrg    String name = (String)clientData;
70eaef79e5Smrg    int i;
71cbc4e2beSmrg
72cbc4e2beSmrg    for (i = 0; i < XtNumber(dialog_buttons); i++)
73cbc4e2beSmrg	if (!strcmp(dialog_buttons[i].name, name))
74eaef79e5Smrg	    selected |= dialog_buttons[i].flag;
75eaef79e5Smrg}
76eaef79e5Smrg
77eaef79e5Smrg/* ARGSUSED */
78cbc4e2beSmrgstatic void
79eaef79e5SmrgSetDialogButton(Widget w,	/* not used */
80eaef79e5Smrg		XEvent *event,	/* not used */
81cbc4e2beSmrg		String *argv,
82eaef79e5Smrg		Cardinal *argc)
83eaef79e5Smrg{
84eaef79e5Smrg  char button_name[80];
85eaef79e5Smrg  XtPointer dummy = NULL;
86eaef79e5Smrg  int i;
87eaef79e5Smrg
88eaef79e5Smrg  for (i = 0; i < *argc; i++) {
89eaef79e5Smrg    XmuCopyISOLatin1Lowered (button_name, argv[i]);
90eaef79e5Smrg    SetSelected(w, button_name, dummy);
91eaef79e5Smrg  }
92eaef79e5Smrg}
93eaef79e5Smrg
94eaef79e5Smrgstatic Boolean firstTime = True;
95eaef79e5Smrg
96cbc4e2beSmrgDialog
97eaef79e5SmrgCreateDialog(Widget top_widget, String name, unsigned long options)
98eaef79e5Smrg{
99eaef79e5Smrg    int i;
100eaef79e5Smrg    Dialog popup;
101eaef79e5Smrg
102eaef79e5Smrg    popup = (Dialog) XtMalloc(sizeof(_Dialog));
103eaef79e5Smrg
104eaef79e5Smrg    if (popup) {
105eaef79e5Smrg        if (firstTime) {
106eaef79e5Smrg	  XtAddActions(actions_table, XtNumber(actions_table));
107eaef79e5Smrg	  firstTime = False;
108eaef79e5Smrg	}
109eaef79e5Smrg	popup->top_widget = top_widget;
110cbc4e2beSmrg	popup->shell_widget = XtCreatePopupShell(name,
111cbc4e2beSmrg						 transientShellWidgetClass,
112eaef79e5Smrg						 top_widget, NULL, 0);
113cbc4e2beSmrg	popup->dialog_widget = XtCreateManagedWidget("dialog",
114eaef79e5Smrg						     dialogWidgetClass,
115cbc4e2beSmrg						     popup->shell_widget,
116eaef79e5Smrg						     NULL, 0);
117eaef79e5Smrg	for (i = 0; i < XtNumber(dialog_buttons); i++)
118eaef79e5Smrg	    if (options & dialog_buttons[i].flag)
119cbc4e2beSmrg		XawDialogAddButton(popup->dialog_widget,
120cbc4e2beSmrg				   dialog_buttons[i].name,
121eaef79e5Smrg				   SetSelected, dialog_buttons[i].name);
122eaef79e5Smrg	popup->options = options;
123eaef79e5Smrg	return popup;
124eaef79e5Smrg    }
125eaef79e5Smrg    else
126eaef79e5Smrg	return NULL;
127eaef79e5Smrg}
128eaef79e5Smrg
129cbc4e2beSmrgvoid
130eaef79e5SmrgPopdownDialog(Dialog popup, String *answer)
131eaef79e5Smrg{
132eaef79e5Smrg    if (answer)
133eaef79e5Smrg	*answer = XawDialogGetValueString(popup->dialog_widget);
134cbc4e2beSmrg
135eaef79e5Smrg    XtPopdown(popup->shell_widget);
136eaef79e5Smrg}
137eaef79e5Smrg
138cbc4e2beSmrgunsigned long
139cbc4e2beSmrgPopupDialog(Dialog popup, String message, String suggestion,
140eaef79e5Smrg	    String *answer, XtGrabKind grab)
141eaef79e5Smrg{
142eaef79e5Smrg  Position popup_x, popup_y, top_x, top_y;
143eaef79e5Smrg  Dimension popup_width, popup_height, top_width, top_height, border_width;
144eaef79e5Smrg  int n;
145eaef79e5Smrg  Arg wargs[4];
146eaef79e5Smrg
147eaef79e5Smrg  n = 0;
148eaef79e5Smrg  XtSetArg(wargs[n], XtNlabel, message); n++;
149eaef79e5Smrg  XtSetArg(wargs[n], XtNvalue, suggestion); n++;
150eaef79e5Smrg  XtSetValues(popup->dialog_widget, wargs, n);
151eaef79e5Smrg
152eaef79e5Smrg  XtRealizeWidget(popup->shell_widget);
153eaef79e5Smrg
154eaef79e5Smrg  n = 0;
155eaef79e5Smrg  XtSetArg(wargs[n], XtNx, &top_x); n++;
156eaef79e5Smrg  XtSetArg(wargs[n], XtNy, &top_y); n++;
157eaef79e5Smrg  XtSetArg(wargs[n], XtNwidth, &top_width); n++;
158eaef79e5Smrg  XtSetArg(wargs[n], XtNheight, &top_height); n++;
159eaef79e5Smrg  XtGetValues(popup->top_widget, wargs, n);
160eaef79e5Smrg
161eaef79e5Smrg  n = 0;
162eaef79e5Smrg  XtSetArg(wargs[n], XtNwidth, &popup_width); n++;
163eaef79e5Smrg  XtSetArg(wargs[n], XtNheight, &popup_height); n++;
164eaef79e5Smrg  XtSetArg(wargs[n], XtNborderWidth, &border_width); n++;
165eaef79e5Smrg  XtGetValues(popup->shell_widget, wargs, n);
166eaef79e5Smrg
167cbc4e2beSmrg  popup_x = max(0,
168cbc4e2beSmrg	min(top_x + ((Position)top_width - (Position)popup_width) / 2,
169cbc4e2beSmrg	    (Position)DisplayWidth(XtDisplay(popup->shell_widget),
170eaef79e5Smrg		   DefaultScreen(XtDisplay(popup->shell_widget))) -
171eaef79e5Smrg	    (Position)popup_width - 2 * (Position)border_width));
172cbc4e2beSmrg  popup_y = max(0,
173eaef79e5Smrg	min(top_y + ((Position)top_height - (Position)popup_height) / 2,
174cbc4e2beSmrg	    (Position)DisplayHeight(XtDisplay(popup->shell_widget),
175eaef79e5Smrg		    DefaultScreen(XtDisplay(popup->shell_widget))) -
176eaef79e5Smrg	    (Position)popup_height - 2 * (Position)border_width));
177eaef79e5Smrg  n = 0;
178eaef79e5Smrg  XtSetArg(wargs[n], XtNx, popup_x); n++;
179eaef79e5Smrg  XtSetArg(wargs[n], XtNy, popup_y); n++;
180eaef79e5Smrg  XtSetValues(popup->shell_widget, wargs, n);
181eaef79e5Smrg
182eaef79e5Smrg  selected = None;
183eaef79e5Smrg
184eaef79e5Smrg  XtPopup(popup->shell_widget, grab);
185cbc4e2beSmrg  XWarpPointer(XtDisplay(popup->shell_widget),
186eaef79e5Smrg	       XtWindow(popup->top_widget),
187cbc4e2beSmrg	       XtWindow(popup->shell_widget),
188eaef79e5Smrg	       0, 0, top_width, top_height,
189eaef79e5Smrg	       popup_width / 2, popup_height / 2);
190eaef79e5Smrg
191eaef79e5Smrg  while ((selected & popup->options) == None) {
192eaef79e5Smrg      XEvent event;
193eaef79e5Smrg      XtNextEvent(&event);
194eaef79e5Smrg      XtDispatchEvent(&event);
195eaef79e5Smrg  }
196eaef79e5Smrg
197eaef79e5Smrg  PopdownDialog(popup, answer);
198eaef79e5Smrg
199eaef79e5Smrg  return (selected & popup->options);
200eaef79e5Smrg}
201