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