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