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