2 * Copyright 1991 University of Wisconsin-Madison
4 * Permission to use, copy, modify, distribute, and sell this software and its
5 * documentation for any purpose is hereby granted without fee, provided that
6 * the above copyright notice appear in all copies and that both that
7 * copyright notice and this permission notice appear in supporting
8 * documentation, and that the name of the University of Wisconsin-Madison not
9 * be used in advertising or publicity pertaining to distribution of the
10 * software without specific, written prior permission. The University of
11 * Wisconsin-Madison makes no representations about the suitability of this
12 * software for any purpose. It is provided "as is" without express or
15 * THE UNIVERSITY OF WISCONSIN-MADISON DISCLAIMS ALL WARRANTIES WITH REGARD TO
16 * THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF WISCONSIN-MADISON BE LIABLE
19 * ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER
20 * RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF
21 * CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN
22 * CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
24 * Author: Tim Theisen Department of Computer Sciences
25 * tim@cs.wisc.edu University of Wisconsin-Madison
26 * uwvax!tim 1210 West Dayton Street
27 * (608)262-0438 Madison, WI 53706
30 * Modified 12/91 by Dean Luick. Tim graciously donated this piece of code
31 * from his program ghostview, an X11 front end for ghostscript.
33 * + Make the cancel button optional.
34 * + Put an #ifdef SPECIAL_CMAP around code to fix a colormap bug.
35 * We don't need it here.
36 * + Add the function positionpopup() from another part of ghostview
39 * Modified 2/93, Various.
40 * + Added workaround for SYSV include problem.
41 * + Changed the default width response text widget to be as wide as the
42 * window itself. Suggestion from David E. Wexelblat, dwex@goblin.org.
44 * Modified 5/2015, anonymous.
45 * + Include nethack's lint.h to get nhStr() macro.
46 * + Use nhStr() on string literals (or macros from <X11/StringDefs.h>
47 * that hide string literals) to cast away implicit 'const' in order
48 * to suppress "warning: assignment discards qualifers from pointer
49 * target type" issued by 'gcc -Wwrite-strings' as used by nethack.
50 * (For this file, always the second parameter to XtSetArg().)
52 * $NHDT-Date: 1432512808 2015/05/25 00:13:28 $ $NHDT-Branch: master $:$NHDT-Revision: 1.6 $
56 #define PRESERVE_NO_SYSV /* X11 include files may define SYSV */
59 #include <X11/Intrinsic.h>
60 #include <X11/StringDefs.h>
62 #include <X11/Xaw/Cardinals.h>
63 #include <X11/Xaw/Form.h>
64 #include <X11/Xaw/Label.h>
65 #include <X11/Xaw/AsciiText.h>
66 #include <X11/Xaw/Command.h>
68 #ifdef PRESERVE_NO_SYSV
72 #undef PRESERVE_NO_SYSV
75 #include "config.h" /* #define for const for non __STDC__ compilers */
76 #include "lint.h" /* for nethack's nhStr() macro */
78 /* ":" added to both translations below to allow limited redefining of
79 * keysyms before testing for keysym values -- dlc */
80 static const char okay_accelerators[] = "#override\n\
81 :<Key>Return: set() notify() unset()\n";
83 static const char cancel_accelerators[] = "#override\n\
84 :<Key>Escape: set() notify() unset()\n\
85 :<Ctrl>[: set() notify() unset()\n"; /* for keyboards w/o an ESC */
87 /* Create a dialog widget. It is just a form widget with
91 * an optional cancel button
94 CreateDialog(parent, name, okay_callback, cancel_callback)
97 XtCallbackProc okay_callback;
98 XtCallbackProc cancel_callback;
100 Widget form, prompt, response, okay, cancel;
107 XtSetArg(args[num_args], nhStr(XtNbackground), white);
112 XtCreateManagedWidget(name, formWidgetClass, parent, args, num_args);
117 XtSetArg(args[num_args], nhStr(XtNforeground), black);
119 XtSetArg(args[num_args], nhStr(XtNbackground), white);
123 XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop);
125 XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop);
127 XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft);
129 XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft);
131 XtSetArg(args[num_args], nhStr(XtNresizable), True);
133 XtSetArg(args[num_args], nhStr(XtNborderWidth), 0);
135 prompt = XtCreateManagedWidget("prompt", labelWidgetClass, form, args,
141 XtSetArg(args[num_args], nhStr(XtNforeground), black);
143 XtSetArg(args[num_args], nhStr(XtNbackground), white);
147 XtSetArg(args[num_args], nhStr(XtNfromVert), prompt);
149 XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop);
151 XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop);
153 XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft);
155 XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft);
157 XtSetArg(args[num_args], nhStr(XtNresizable), True);
159 XtSetArg(args[num_args], nhStr(XtNeditType), XawtextEdit);
161 XtSetArg(args[num_args], nhStr(XtNresize), XawtextResizeWidth);
163 XtSetArg(args[num_args], nhStr(XtNstring), "");
165 response = XtCreateManagedWidget("response", asciiTextWidgetClass, form,
171 XtSetArg(args[num_args], nhStr(XtNforeground), black);
173 XtSetArg(args[num_args], nhStr(XtNbackground), white);
177 XtSetArg(args[num_args], nhStr(XtNfromVert), response);
179 XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop);
181 XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop);
183 XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft);
185 XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft);
187 XtSetArg(args[num_args], nhStr(XtNresizable), True);
189 XtSetArg(args[num_args], nhStr(XtNaccelerators),
190 XtParseAcceleratorTable(okay_accelerators));
192 okay = XtCreateManagedWidget("okay", commandWidgetClass, form, args,
194 XtAddCallback(okay, XtNcallback, okay_callback, form);
196 /* Only create cancel button if there is a callback for it. */
197 if (cancel_callback) {
201 XtSetArg(args[num_args], nhStr(XtNforeground), black);
203 XtSetArg(args[num_args], nhStr(XtNbackground), white);
207 XtSetArg(args[num_args], nhStr(XtNfromVert), response);
209 XtSetArg(args[num_args], nhStr(XtNfromHoriz), okay);
211 XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop);
213 XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop);
215 XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft);
217 XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft);
219 XtSetArg(args[num_args], nhStr(XtNresizable), True);
221 XtSetArg(args[num_args], nhStr(XtNaccelerators),
222 XtParseAcceleratorTable(cancel_accelerators));
224 cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form,
226 XtAddCallback(cancel, XtNcallback, cancel_callback, form);
227 XtInstallAccelerators(response, cancel);
230 XtInstallAccelerators(response, okay);
231 XtSetKeyboardFocus(form, response);
237 /* get the prompt from the dialog box. Used a startup time to
238 * save away the initial prompt */
247 label = XtNameToWidget(w, "prompt");
248 XtSetArg(args[0], nhStr(XtNlabel), &s);
249 XtGetValues(label, args, ONE);
250 return XtNewString(s);
254 /* set the prompt. This is used to put error information in the prompt */
256 SetDialogPrompt(w, newprompt)
263 label = XtNameToWidget(w, "prompt");
264 XtSetArg(args[0], nhStr(XtNlabel), newprompt);
265 XtSetValues(label, args, ONE);
268 /* get what the user typed; caller must free the response */
277 response = XtNameToWidget(w, "response");
278 XtSetArg(args[0], nhStr(XtNstring), &s);
279 XtGetValues(response, args, ONE);
280 return XtNewString(s);
283 #define max(a, b) (((a) > (b)) ? (a) : (b))
284 /* set the default reponse */
286 SetDialogResponse(w, s)
293 Dimension width, nwidth, leftMargin, rightMargin;
295 response = XtNameToWidget(w, "response");
296 XtSetArg(args[0], nhStr(XtNfont), &font);
297 XtSetArg(args[1], nhStr(XtNleftMargin), &leftMargin);
298 XtSetArg(args[2], nhStr(XtNrightMargin), &rightMargin);
299 XtSetArg(args[3], nhStr(XtNwidth), &width);
300 XtGetValues(response, args, FOUR);
301 /* width includes margins as per Xaw documentation */
302 nwidth = (font->max_bounds.width * strlen(s)) + leftMargin + rightMargin;
306 XtSetArg(args[0], nhStr(XtNstring), s);
307 XtSetArg(args[1], nhStr(XtNwidth), nwidth);
308 XtSetValues(response, args, TWO);
309 XawTextSetInsertionPoint(response, strlen(s));
313 /* clear the response */
315 ClearDialogResponse(w)
321 response = XtNameToWidget(w, "response");
322 XtSetArg(args[0], nhStr(XtNstring), "");
323 XtSetArg(args[1], nhStr(XtNwidth), 100);
324 XtSetValues(response, args, TWO);
328 /* Not a part of the original dialogs.c from ghostview ---------------------
331 /* position popup window under the cursor */
333 positionpopup(w, bottom)
335 boolean bottom; /* position y on bottom? */
339 Dimension width, height, b_width;
340 int x, y, max_x, max_y;
344 unsigned int dummymask;
345 extern Widget toplevel;
347 /* following line deals with a race condition w/brain-damaged WM's -dlc */
348 XtUnrealizeWidget(w);
350 XQueryPointer(XtDisplay(toplevel), XtWindow(toplevel), &root, &child, &x,
351 &y, &dummyx, &dummyy, &dummymask);
353 XtSetArg(args[num_args], XtNwidth, &width);
355 XtSetArg(args[num_args], XtNheight, &height);
357 XtSetArg(args[num_args], XtNborderWidth, &b_width);
359 XtGetValues(w, args, num_args);
361 /* position so that the cursor is center,center or center,bottom */
362 width += 2 * b_width;
363 x -= ((Position) width / 2);
366 if (x > (max_x = (Position)(XtScreen(w)->width - width)))
370 y -= (height + b_width - 1);
371 height += 2 * b_width;
373 height += 2 * b_width;
374 y -= ((Position) height / 2);
378 if (y > (max_y = (Position)(XtScreen(w)->height - height)))
382 XtSetArg(args[num_args], XtNx, x);
384 XtSetArg(args[num_args], XtNy, y);
386 XtSetValues(w, args, num_args);
388 /* Some older window managers ignore XtN{x,y}; hint the same values */
389 /* The {x,y} are not used by newer window managers; older ones need them
392 hints = XAllocSizeHints();
393 hints->flags = USPosition;
396 XSetWMNormalHints(XtDisplay(w), XtWindow(w), hints);