Files
nethack/win/X11/dialogs.c
PatR a34d327159 bit of X11 reformating
Cleanup up the copyright notice in dialogs.c, and replace some tabs.
2016-01-12 02:20:43 -08:00

398 lines
12 KiB
C

/*
* Copyright 1991 University of Wisconsin-Madison
*
* Permission to use, copy, modify, distribute, and sell this software and
* its documentation for any purpose is hereby granted without fee, provided
* that the above copyright notice appear in all copies and that both that
* copyright notice and this permission notice appear in supporting
* documentation, and that the name of the University of Wisconsin-Madison
* not be used in advertising or publicity pertaining to distribution of the
* software without specific, written prior permission. The University of
* Wisconsin-Madison makes no representations about the suitability of this
* software for any purpose. It is provided "as is" without express or
* implied warranty.
*
* THE UNIVERSITY OF WISCONSIN-MADISON DISCLAIMS ALL WARRANTIES WITH REGARD
* TO THIS SOFTWARE, INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY AND
* FITNESS, IN NO EVENT SHALL THE UNIVERSITY OF WISCONSIN-MADISON BE LIABLE
* FOR ANY SPECIAL, INDIRECT OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*
* Author: Tim Theisen Department of Computer Sciences
* tim@cs.wisc.edu University of Wisconsin-Madison
* uwvax!tim 1210 West Dayton Street
* (608)262-0438 Madison, WI 53706
*
*
* Modified 12/91 by Dean Luick. Tim graciously donated this piece of code
* from his program ghostview, an X11 front end for ghostscript.
*
* + Make the cancel button optional.
* + Put an #ifdef SPECIAL_CMAP around code to fix a colormap bug.
* We don't need it here.
* + Add the function positionpopup() from another part of ghostview
* to this code.
*
* Modified 2/93, Various.
* + Added workaround for SYSV include problem.
* + Changed the default width response text widget to be as wide as the
* window itself. Suggestion from David E. Wexelblat, dwex@goblin.org.
*
* Modified 5/2015, anonymous.
* + Include nethack's lint.h to get nhStr() macro.
* + Use nhStr() on string literals (or macros from <X11/StringDefs.h>
* that hide string literals) to cast away implicit 'const' in order
* to suppress "warning: assignment discards qualifers from pointer
* target type" issued by 'gcc -Wwrite-strings' as used by nethack.
* (For this file, always the second parameter to XtSetArg().)
*
* $NHDT-Date: 1452594032 2016/01/12 10:20:32 $ $NHDT-Branch: NetHack-3.6.0 $:$NHDT-Revision: 1.7 $
*/
#ifndef SYSV
#define PRESERVE_NO_SYSV /* X11 include files may define SYSV */
#endif
#include <X11/Intrinsic.h>
#include <X11/StringDefs.h>
#include <X11/Xos.h>
#include <X11/Xaw/Cardinals.h>
#include <X11/Xaw/Form.h>
#include <X11/Xaw/Label.h>
#include <X11/Xaw/AsciiText.h>
#include <X11/Xaw/Command.h>
#ifdef PRESERVE_NO_SYSV
#ifdef SYSV
#undef SYSV
#endif
#undef PRESERVE_NO_SYSV
#endif
#include "config.h" /* #define for const for non __STDC__ compilers */
#include "lint.h" /* for nethack's nhStr() macro */
/* ":" added to both translations below to allow limited redefining of
* keysyms before testing for keysym values -- dlc */
static const char okay_accelerators[] = "#override\n\
:<Key>Return: set() notify() unset()\n";
static const char cancel_accelerators[] = "#override\n\
:<Key>Escape: set() notify() unset()\n\
:<Ctrl>[: set() notify() unset()\n"; /* for keyboards w/o an ESC */
/* Create a dialog widget. It is just a form widget with
* a label prompt
* a text response
* an okay button
* an optional cancel button
*/
Widget
CreateDialog(parent, name, okay_callback, cancel_callback)
Widget parent;
String name;
XtCallbackProc okay_callback;
XtCallbackProc cancel_callback;
{
Widget form, prompt, response, okay, cancel;
Arg args[20];
Cardinal num_args;
num_args = 0;
#ifdef SPECIAL_CMAP
if (special_cmap) {
XtSetArg(args[num_args], nhStr(XtNbackground), white);
num_args++;
}
#endif
form =
XtCreateManagedWidget(name, formWidgetClass, parent, args, num_args);
num_args = 0;
#ifdef SPECIAL_CMAP
if (special_cmap) {
XtSetArg(args[num_args], nhStr(XtNforeground), black);
num_args++;
XtSetArg(args[num_args], nhStr(XtNbackground), white);
num_args++;
}
#endif
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop);
num_args++;
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop);
num_args++;
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft);
num_args++;
XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft);
num_args++;
XtSetArg(args[num_args], nhStr(XtNresizable), True);
num_args++;
XtSetArg(args[num_args], nhStr(XtNborderWidth), 0);
num_args++;
prompt = XtCreateManagedWidget("prompt", labelWidgetClass, form, args,
num_args);
num_args = 0;
#ifdef SPECIAL_CMAP
if (special_cmap) {
XtSetArg(args[num_args], nhStr(XtNforeground), black);
num_args++;
XtSetArg(args[num_args], nhStr(XtNbackground), white);
num_args++;
}
#endif
XtSetArg(args[num_args], nhStr(XtNfromVert), prompt);
num_args++;
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop);
num_args++;
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop);
num_args++;
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft);
num_args++;
XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft);
num_args++;
XtSetArg(args[num_args], nhStr(XtNresizable), True);
num_args++;
XtSetArg(args[num_args], nhStr(XtNeditType), XawtextEdit);
num_args++;
XtSetArg(args[num_args], nhStr(XtNresize), XawtextResizeWidth);
num_args++;
XtSetArg(args[num_args], nhStr(XtNstring), "");
num_args++;
response = XtCreateManagedWidget("response", asciiTextWidgetClass, form,
args, num_args);
num_args = 0;
#ifdef SPECIAL_CMAP
if (special_cmap) {
XtSetArg(args[num_args], nhStr(XtNforeground), black);
num_args++;
XtSetArg(args[num_args], nhStr(XtNbackground), white);
num_args++;
}
#endif
XtSetArg(args[num_args], nhStr(XtNfromVert), response);
num_args++;
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop);
num_args++;
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop);
num_args++;
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft);
num_args++;
XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft);
num_args++;
XtSetArg(args[num_args], nhStr(XtNresizable), True);
num_args++;
XtSetArg(args[num_args], nhStr(XtNaccelerators),
XtParseAcceleratorTable(okay_accelerators));
num_args++;
okay = XtCreateManagedWidget("okay", commandWidgetClass, form, args,
num_args);
XtAddCallback(okay, XtNcallback, okay_callback, form);
/* Only create cancel button if there is a callback for it. */
if (cancel_callback) {
num_args = 0;
#ifdef SPECIAL_CMAP
if (special_cmap) {
XtSetArg(args[num_args], nhStr(XtNforeground), black);
num_args++;
XtSetArg(args[num_args], nhStr(XtNbackground), white);
num_args++;
}
#endif
XtSetArg(args[num_args], nhStr(XtNfromVert), response);
num_args++;
XtSetArg(args[num_args], nhStr(XtNfromHoriz), okay);
num_args++;
XtSetArg(args[num_args], nhStr(XtNtop), XtChainTop);
num_args++;
XtSetArg(args[num_args], nhStr(XtNbottom), XtChainTop);
num_args++;
XtSetArg(args[num_args], nhStr(XtNleft), XtChainLeft);
num_args++;
XtSetArg(args[num_args], nhStr(XtNright), XtChainLeft);
num_args++;
XtSetArg(args[num_args], nhStr(XtNresizable), True);
num_args++;
XtSetArg(args[num_args], nhStr(XtNaccelerators),
XtParseAcceleratorTable(cancel_accelerators));
num_args++;
cancel = XtCreateManagedWidget("cancel", commandWidgetClass, form,
args, num_args);
XtAddCallback(cancel, XtNcallback, cancel_callback, form);
XtInstallAccelerators(response, cancel);
}
XtInstallAccelerators(response, okay);
XtSetKeyboardFocus(form, response);
return form;
}
#if 0
/* get the prompt from the dialog box. Used a startup time to
* save away the initial prompt */
String
GetDialogPrompt(w)
Widget w;
{
Arg args[1];
Widget label;
String s;
label = XtNameToWidget(w, "prompt");
XtSetArg(args[0], nhStr(XtNlabel), &s);
XtGetValues(label, args, ONE);
return XtNewString(s);
}
#endif
/* set the prompt. This is used to put error information in the prompt */
void
SetDialogPrompt(w, newprompt)
Widget w;
String newprompt;
{
Arg args[1];
Widget label;
label = XtNameToWidget(w, "prompt");
XtSetArg(args[0], nhStr(XtNlabel), newprompt);
XtSetValues(label, args, ONE);
}
/* get what the user typed; caller must free the response */
String
GetDialogResponse(w)
Widget w;
{
Arg args[1];
Widget response;
String s;
response = XtNameToWidget(w, "response");
XtSetArg(args[0], nhStr(XtNstring), &s);
XtGetValues(response, args, ONE);
return XtNewString(s);
}
#define max(a, b) (((a) > (b)) ? (a) : (b))
/* set the default reponse */
void
SetDialogResponse(w, s)
Widget w;
String s;
{
Arg args[4];
Widget response;
XFontStruct *font;
Dimension width, nwidth, leftMargin, rightMargin;
response = XtNameToWidget(w, "response");
XtSetArg(args[0], nhStr(XtNfont), &font);
XtSetArg(args[1], nhStr(XtNleftMargin), &leftMargin);
XtSetArg(args[2], nhStr(XtNrightMargin), &rightMargin);
XtSetArg(args[3], nhStr(XtNwidth), &width);
XtGetValues(response, args, FOUR);
/* width includes margins as per Xaw documentation */
nwidth = (font->max_bounds.width * strlen(s)) + leftMargin + rightMargin;
if (nwidth < width)
nwidth = width;
XtSetArg(args[0], nhStr(XtNstring), s);
XtSetArg(args[1], nhStr(XtNwidth), nwidth);
XtSetValues(response, args, TWO);
XawTextSetInsertionPoint(response, strlen(s));
}
#if 0
/* clear the response */
void
ClearDialogResponse(w)
Widget w;
{
Arg args[2];
Widget response;
response = XtNameToWidget(w, "response");
XtSetArg(args[0], nhStr(XtNstring), "");
XtSetArg(args[1], nhStr(XtNwidth), 100);
XtSetValues(response, args, TWO);
}
#endif
/* Not a part of the original dialogs.c from ghostview ---------------------
*/
/* position popup window under the cursor */
void
positionpopup(w, bottom)
Widget w;
boolean bottom; /* position y on bottom? */
{
Arg args[3];
Cardinal num_args;
Dimension width, height, b_width;
int x, y, max_x, max_y;
Window root, child;
XSizeHints *hints;
int dummyx, dummyy;
unsigned int dummymask;
extern Widget toplevel;
/* following line deals with a race condition w/brain-damaged WM's -dlc */
XtUnrealizeWidget(w);
XQueryPointer(XtDisplay(toplevel), XtWindow(toplevel), &root, &child, &x,
&y, &dummyx, &dummyy, &dummymask);
num_args = 0;
XtSetArg(args[num_args], XtNwidth, &width);
num_args++;
XtSetArg(args[num_args], XtNheight, &height);
num_args++;
XtSetArg(args[num_args], XtNborderWidth, &b_width);
num_args++;
XtGetValues(w, args, num_args);
/* position so that the cursor is center,center or center,bottom */
width += 2 * b_width;
x -= ((Position) width / 2);
if (x < 0)
x = 0;
if (x > (max_x = (Position)(XtScreen(w)->width - width)))
x = max_x;
if (bottom) {
y -= (height + b_width - 1);
height += 2 * b_width;
} else {
height += 2 * b_width;
y -= ((Position) height / 2);
}
if (y < 0)
y = 0;
if (y > (max_y = (Position)(XtScreen(w)->height - height)))
y = max_y;
num_args = 0;
XtSetArg(args[num_args], XtNx, x);
num_args++;
XtSetArg(args[num_args], XtNy, y);
num_args++;
XtSetValues(w, args, num_args);
/* Some older window managers ignore XtN{x,y}; hint the same values */
/* The {x,y} are not used by newer window managers; older ones need them
*/
XtRealizeWidget(w);
hints = XAllocSizeHints();
hints->flags = USPosition;
hints->x = x;
hints->y = y;
XSetWMNormalHints(XtDisplay(w), XtWindow(w), hints);
XFree(hints);
}