more quieting of Qt6 build warnings
[NetHack.git] / win / X11 / dialogs.c
blob11664c198a77ce52b254a8e7b50b8a3b18e7c309
1 /*
2 * Copyright 1991 University of Wisconsin-Madison
4 * Permission to use, copy, modify, distribute, and sell this software and
5 * its documentation for any purpose is hereby granted without fee, provided
6 * that 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
9 * not 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
13 * implied warranty.
15 * THE UNIVERSITY OF WISCONSIN-MADISON DISCLAIMS ALL WARRANTIES WITH REGARD
16 * TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
17 * FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF WISCONSIN-MADISON BE LIABLE
18 * FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
19 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
20 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
21 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
23 * Author: Tim Theisen Department of Computer Sciences
24 * tim@cs.wisc.edu University of Wisconsin-Madison
25 * uwvax!tim 1210 West Dayton Street
26 * (608)262-0438 Madison, WI 53706
29 * Modified 12/91 by Dean Luick. Tim graciously donated this piece of code
30 * from his program ghostview, an X11 front end for ghostscript.
32 * + Make the cancel button optional.
33 * + Put an #ifdef SPECIAL_CMAP around code to fix a colormap bug.
34 * We don't need it here.
35 * + Add the function positionpopup() from another part of ghostview
36 * to this code.
38 * Modified 2/93, Various.
39 * + Added workaround for SYSV include problem.
40 * + Changed the default width response text widget to be as wide as the
41 * window itself. Suggestion from David E. Wexelblat, dwex@goblin.org.
43 * Modified 5/2015, anonymous.
44 * + Include nethack's lint.h to get nhStr() macro.
45 * + Use nhStr() on string literals (or macros from <X11/StringDefs.h>
46 * that hide string literals) to cast away implicit 'const' in order
47 * to suppress "warning: assignment discards qualifiers from pointer
48 * target type" issued by 'gcc -Wwrite-strings' as used by nethack.
49 * (For this file, always the second parameter to XtSetArg().)
51 * Modified 1/2016, Pat Rankin.
52 * + Added minimum width argument to SetDialogResponse() so that the
53 * text entry widget can be forced to wider than the default response.
54 * + Make 'okay' button same width as 'cancel', and both wider than
55 * default by a small arbitrary amount.
57 * $NHDT-Date: 1455157470 2016/02/11 02:24:30 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.9 $
60 #ifndef SYSV
61 #define PRESERVE_NO_SYSV /* X11 include files may define SYSV */
62 #endif
64 #include <X11/Intrinsic.h>
65 #include <X11/StringDefs.h>
66 #include <X11/Xos.h>
67 #include <X11/Xaw/Cardinals.h>
68 #include <X11/Xaw/Form.h>
69 #include <X11/Xaw/Label.h>
70 #include <X11/Xaw/AsciiText.h>
71 #include <X11/Xaw/Command.h>
73 #ifdef PRESERVE_NO_SYSV
74 #ifdef SYSV
75 #undef SYSV
76 #endif
77 #undef PRESERVE_NO_SYSV
78 #endif
80 #define X11_BUILD
81 #include "config.h" /* #define for const for non __STDC__ compilers */
82 #undef X11_BUILD
84 #include "lint.h" /* for nethack's nhStr() macro */
85 #include "winX.h" /* to make sure prototypes match corresponding functions */
87 /* ":" added to both translations below to allow limited redefining of
88 * keysyms before testing for keysym values -- dlc */
89 static const char okay_accelerators[] = "#override\n\
90 :<Key>Return: set() notify() unset()\n";
92 static const char cancel_accelerators[] = "#override\n\
93 :<Key>Escape: set() notify() unset()\n\
94 :<Ctrl>[: set() notify() unset()\n"; /* for keyboards w/o an ESC */
96 /* Create a dialog widget. It is just a form widget with
97 * a label prompt
98 * a text response
99 * an okay button
100 * an optional cancel button
102 Widget
103 CreateDialog(Widget parent, String name, XtCallbackProc okay_callback,
104 XtCallbackProc cancel_callback)
106 Widget form, prompt, response, okay, cancel;
107 Arg args[20];
108 Cardinal num_args;
109 Dimension owidth, cwidth;
111 num_args = 0;
112 #ifdef SPECIAL_CMAP
113 if (special_cmap) {
114 XtSetArg(args[num_args], nhStr(XtNbackground), white); num_args++;
116 #endif
117 form = XtCreateManagedWidget(name, formWidgetClass, parent,
118 args, num_args);
120 num_args = 0;
121 #ifdef SPECIAL_CMAP
122 if (special_cmap) {
123 XtSetArg(args[num_args], nhStr(XtNforeground), black); num_args++;
124 XtSetArg(args[num_args], nhStr(XtNbackground), white); num_args++;
126 #endif
127 XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
128 XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop); num_args++;
129 XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
130 XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++;
131 XtSetArg(args[num_args], nhStr(XtNresizable), True); num_args++;
132 XtSetArg(args[num_args], nhStr(XtNborderWidth), 0); num_args++;
133 prompt = XtCreateManagedWidget("prompt", labelWidgetClass, form,
134 args, num_args);
136 num_args = 0;
137 #ifdef SPECIAL_CMAP
138 if (special_cmap) {
139 XtSetArg(args[num_args], nhStr(XtNforeground), black); num_args++;
140 XtSetArg(args[num_args], nhStr(XtNbackground), white); num_args++;
142 #endif
143 XtSetArg(args[num_args], nhStr(XtNfromVert), prompt); num_args++;
144 XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
145 XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop); num_args++;
146 XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
147 XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++;
148 XtSetArg(args[num_args], nhStr(XtNresizable), True); num_args++;
149 XtSetArg(args[num_args], nhStr(XtNeditType), XawtextEdit); num_args++;
150 XtSetArg(args[num_args], nhStr(XtNresize), XawtextResizeWidth); num_args++;
151 XtSetArg(args[num_args], nhStr(XtNstring), ""); num_args++;
152 response = XtCreateManagedWidget("response", asciiTextWidgetClass, form,
153 args, num_args);
155 num_args = 0;
156 #ifdef SPECIAL_CMAP
157 if (special_cmap) {
158 XtSetArg(args[num_args], nhStr(XtNforeground), black); num_args++;
159 XtSetArg(args[num_args], nhStr(XtNbackground), white); num_args++;
161 #endif
162 XtSetArg(args[num_args], nhStr(XtNfromVert), response); num_args++;
163 XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
164 XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop); num_args++;
165 XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
166 XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++;
167 XtSetArg(args[num_args], nhStr(XtNresizable), True); num_args++;
168 XtSetArg(args[num_args], nhStr(XtNaccelerators),
169 XtParseAcceleratorTable(okay_accelerators)); num_args++;
170 okay = XtCreateManagedWidget("okay", commandWidgetClass, form,
171 args, num_args);
172 XtAddCallback(okay, XtNcallback, okay_callback, form);
173 XtSetArg(args[0], XtNwidth, &owidth);
174 XtGetValues(okay, args, ONE);
176 /* Only create cancel button if there is a callback for it. */
177 if (cancel_callback) {
178 num_args = 0;
179 #ifdef SPECIAL_CMAP
180 if (special_cmap) {
181 XtSetArg(args[num_args], nhStr(XtNforeground), black); num_args++;
182 XtSetArg(args[num_args], nhStr(XtNbackground), white); num_args++;
184 #endif
185 XtSetArg(args[num_args], nhStr(XtNfromVert), response); num_args++;
186 XtSetArg(args[num_args], nhStr(XtNfromHoriz), okay); num_args++;
187 XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop); num_args++;
188 XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop); num_args++;
189 XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft); num_args++;
190 XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft); num_args++;
191 XtSetArg(args[num_args], nhStr(XtNresizable), True); num_args++;
192 XtSetArg(args[num_args], nhStr(XtNaccelerators),
193 XtParseAcceleratorTable(cancel_accelerators)); num_args++;
194 cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form,
195 args, num_args);
196 XtAddCallback(cancel, XtNcallback, cancel_callback, form);
197 XtInstallAccelerators(response, cancel);
198 XtSetArg(args[0], XtNwidth, &cwidth);
199 XtGetValues(cancel, args, ONE);
200 /* widen the cancel button */
201 cwidth += 25;
202 XtSetArg(args[0], XtNwidth, cwidth);
203 XtSetValues(cancel, args, ONE);
204 } else
205 cwidth = owidth + 25;
207 /* make okay button same width as cancel, or widen it if no cancel */
208 XtSetArg(args[0], XtNwidth, cwidth);
209 XtSetValues(okay, args, ONE);
211 XtInstallAccelerators(response, okay);
212 XtSetKeyboardFocus(form, response);
214 return form;
217 #if 0
218 /* get the prompt from the dialog box. Used a startup time to
219 * save away the initial prompt */
220 String
221 GetDialogPrompt(Widget w)
223 Arg args[1];
224 Widget label;
225 String s;
227 label = XtNameToWidget(w, "prompt");
228 XtSetArg(args[0], nhStr(XtNlabel), &s);
229 XtGetValues(label, args, ONE);
230 return XtNewString(s);
232 #endif
234 /* set the prompt. This is used to put error information in the prompt */
235 void
236 SetDialogPrompt(Widget w, String newprompt)
238 Arg args[1];
239 Widget label;
241 label = XtNameToWidget(w, "prompt");
242 XtSetArg(args[0], nhStr(XtNlabel), newprompt);
243 XtSetValues(label, args, ONE);
246 /* get what the user typed; caller must free the response */
247 String
248 GetDialogResponse(Widget w)
250 Arg args[1];
251 Widget response;
252 String s;
254 response = XtNameToWidget(w, "response");
255 XtSetArg(args[0], nhStr(XtNstring), &s);
256 XtGetValues(response, args, ONE);
257 return XtNewString(s);
260 /* set the default response */
261 void
262 SetDialogResponse(Widget w, String s, unsigned ln)
264 Arg args[4];
265 Widget response;
266 XFontStruct *font;
267 Dimension width, nwidth, leftMargin, rightMargin;
268 unsigned s_len = strlen(s);
270 if (s_len < ln)
271 s_len = ln;
272 response = XtNameToWidget(w, "response");
273 XtSetArg(args[0], nhStr(XtNfont), &font);
274 XtSetArg(args[1], nhStr(XtNleftMargin), &leftMargin);
275 XtSetArg(args[2], nhStr(XtNrightMargin), &rightMargin);
276 XtSetArg(args[3], nhStr(XtNwidth), &width);
277 XtGetValues(response, args, FOUR);
278 /* width includes margins as per Xaw documentation */
279 nwidth = font->max_bounds.width * (s_len + 1) + leftMargin + rightMargin;
280 if (nwidth < width)
281 nwidth = width;
283 XtSetArg(args[0], nhStr(XtNstring), s);
284 XtSetArg(args[1], nhStr(XtNwidth), nwidth);
285 XtSetValues(response, args, TWO);
286 XawTextSetInsertionPoint(response, strlen(s));
289 #if 0
290 /* clear the response */
291 void
292 ClearDialogResponse(Widget w)
294 Arg args[2];
295 Widget response;
297 response = XtNameToWidget(w, "response");
298 XtSetArg(args[0], nhStr(XtNstring), "");
299 XtSetArg(args[1], nhStr(XtNwidth), 100);
300 XtSetValues(response, args, TWO);
302 #endif
304 /* Not a part of the original dialogs.c from ghostview -------------------- */
306 /* position popup window under the cursor */
307 void
308 positionpopup(Widget w, boolean bottom) /* position y on bottom? */
310 Arg args[3];
311 Cardinal num_args;
312 Dimension width, height, b_width;
313 int x, y, max_x, max_y;
314 Window root, child;
315 XSizeHints *hints;
316 int dummyx, dummyy;
317 unsigned int dummymask;
318 extern Widget toplevel;
320 /* following line deals with a race condition w/brain-damaged WM's -dlc */
321 XtUnrealizeWidget(w);
323 XQueryPointer(XtDisplay(toplevel), XtWindow(toplevel), &root, &child, &x,
324 &y, &dummyx, &dummyy, &dummymask);
325 num_args = 0;
326 XtSetArg(args[num_args], XtNwidth, &width); num_args++;
327 XtSetArg(args[num_args], XtNheight, &height); num_args++;
328 XtSetArg(args[num_args], XtNborderWidth, &b_width); num_args++;
329 XtGetValues(w, args, num_args);
331 /* position so that the cursor is center,center or center,bottom */
332 width += 2 * b_width;
333 x -= ((Position) width / 2);
334 if (x < 0)
335 x = 0;
336 if (x > (max_x = (Position) (XtScreen(w)->width - width)))
337 x = max_x;
339 if (bottom) {
340 y -= (height + b_width - 1);
341 height += 2 * b_width;
342 } else {
343 height += 2 * b_width;
344 y -= ((Position) height / 2);
346 if (y < 0)
347 y = 0;
348 if (y > (max_y = (Position) (XtScreen(w)->height - height)))
349 y = max_y;
351 num_args = 0;
352 XtSetArg(args[num_args], XtNx, x); num_args++;
353 XtSetArg(args[num_args], XtNy, y); num_args++;
354 XtSetValues(w, args, num_args);
356 /* Some older window managers ignore XtN{x,y}; hint the same values.
357 {x,y} are not used by newer window managers; older ones need them. */
358 XtRealizeWidget(w);
359 hints = XAllocSizeHints();
360 hints->flags = USPosition;
361 hints->x = x;
362 hints->y = y;
363 XSetWMNormalHints(XtDisplay(w), XtWindow(w), hints);
364 XFree(hints);
367 /*dialogs.c*/