home *** CD-ROM | disk | FTP | other *** search
- Path: sparky!uunet!news.tek.com!master!saab!billr
- From: billr@saab.CNA.TEK.COM (Bill Randle)
- Newsgroups: comp.sources.games
- Subject: v16i016: nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part16/108
- Message-ID: <4299@master.CNA.TEK.COM>
- Date: 28 Jan 93 19:13:58 GMT
- Sender: news@master.CNA.TEK.COM
- Lines: 1874
- Approved: billr@saab.CNA.TEK.COM
-
- Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
- Posting-number: Volume 16, Issue 16
- Archive-name: nethack31/Part16
- Supersedes: nethack3p9: Volume 10, Issue 46-102
- Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
-
-
-
- #! /bin/sh
- # This is a shell archive. Remove anything before this line, then unpack
- # it by saving it into a file and typing "sh file". To overwrite existing
- # files, type "sh file -c". You can also feed this as standard input via
- # unshar, or by typing "sh <file", e.g.. If this archive is complete, you
- # will see the following message at the end:
- # "End of archive 16 (of 108)."
- # Contents: sys/atari/Install.tos win/X11/winX.c
- # Wrapped by billr@saab on Wed Jan 27 16:08:51 1993
- PATH=/bin:/usr/bin:/usr/ucb ; export PATH
- if test -f 'sys/atari/Install.tos' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'sys/atari/Install.tos'\"
- else
- echo shar: Extracting \"'sys/atari/Install.tos'\" \(8575 characters\)
- sed "s/^X//" >'sys/atari/Install.tos' <<'END_OF_FILE'
- X Instructions for compiling and installing NetHack 3.1
- X on a TOS system
- X =====================================================
- X (or, How to make ST NetHack 3.1)
- X Last revision: 23 Jan 1993
- X
- X1. Make sure all the NetHack files are in the appropriate directory structure.
- X You should have a main directory with subdirectories dat, doc, include,
- X src, util, sys\atari, sys\share, and sys\unix. You may have other sub-
- X directories under sys, but they needn't concern you. If you do not follow
- X this structure, the Makefiles will not function properly. The .c files
- X for the main program belong in src, those for utility programs in util,
- X and Atari-specific ones in sys\atari. All the .h files belong in include,
- X the documentation in doc, and assorted data files in dat. You may also
- X use random.c from sys\share. The Makefiles belong in sys\unix (except
- X for the Atari-specific Makefile.utl found in this directory).
- X (A more detailed explanation of the directory structure may be found in
- X Files, which should be in the top directory.)
- X
- X
- X2. If you don't already have a good command line interpreter, get one.
- X Doing all of the following from the desktop or a GEM shell will
- X probably be a *big* pain. If you can get a Bourne shell compatible
- X one, and put it in \bin\sh, then you'll save yourself some trouble
- X with the Makefiles. There are several good shells on various
- X FTP sites (including atari.archive.umich.edu).
- X
- X Run the "setup.g" shell script in sys\atari. This will move all the
- X makefiles and other files to the appropriate directories.
- X
- X The file termcap.uu is the fixed version of the Fred Fish termcap library.
- X You will need to run a uudecode utility on it to generate the file
- X termcap.arc. termcap.arc contains several files of termcap routines.
- X Using them with NetHack involves very little knowledge of the UNIX concept
- X of a termcap database; mostly you need to know enough to set a TERM
- X environment variable. You can unarc termcap.arc here in the sys\share
- X directory, but if you are going to use it, it is probably best to unarc a
- X copy in the src directory. That way you will not miss copying any
- X files over. Some compilers (notably the gcc) already have a termcap
- X library; if so, you won't need this one.
- X
- X3. Now go to the include subdirectory to edit a couple of the header files
- X there.
- X
- X First edit config.h according to the comments to match your system and
- X desired set of features. In particular:
- X make sure that UNIX is *not* defined, and TOS is (if you're using
- X the MiNT library, and/or the -mint option to gcc, this will
- X be done automatically)
- X make sure the HACKDIR is defined properly (or not at all)
- X make sure that COMPRESS is not defined
- X
- X If you want to build a NetHack that will run on a 1 megabyte machine,
- X I'm afraid you're going to have to disable some options. Just what
- X to disable is a tough choice; NetHack *almost* fits in 1 meg, but
- X almost isn't quite good enough :-(. On the other hand, if you can
- X compile NetHack, you almost certainly have at least 2 megabytes;
- X certainly gcc won't compile NetHack with less than 4.
- X
- X Also edit tosconf.h; this shouldn't need much changing. If you are not
- X going to include random.c you will need to comment out RANDOM. Gcc users
- X don't need RANDOM, since the gcc and MiNT libraries have a Berkeley
- X derived srandom() function already. If you have no termcap support and
- X don't want to use the supplied termcap.uu, comment out TERMLIB. Gcc has
- X a termcap library, so TERMLIB should always be "on" with gcc (and you
- X don't need to worry about termcap.uu at all).
- X
- X4. If you're using a compiler other than the gcc, you may want to look
- X through system.h, in the include directory. This file matches the return
- X and parameter types for system calls and library routines with various
- X flavors of compilers and operating systems. Leaving this file alone is
- X unlikely to cause problems, but if you get compile errors with any
- X functions in the standard library, it's worth checking the declarations
- X there.
- X
- X5. If you want to change the high score list behavior, examine the top of
- X topten.c, in the src directory. You may want to change the definitions of
- X PERSMAX, POINTSMIN, and ENTRYMAX. I set POINTSMIN to 51 and ENTRYMAX to
- X 50 to keep the size of the score list down.
- X
- X6. Go to the src directory and edit your Makefile. You'll want the Systos
- X target configuration; the comments explain most of what needs to be done,
- X at least for the gcc. If your compiler doesn't like directories separated
- X by /'s, then change these to \'s.
- X
- X Next, go to the top, util, dat, and doc directories, and edit the Makefiles
- X there, as necessary. You'll need nroff and/or TeX to do the files in doc;
- X if you don't have one/both of these, you can skip it (docs?? we don't need
- X no steenking docs :-)).
- X
- X If you elected to use Fred Fish's termcap library (bundled in as
- X termcap.arc), you will have to generate termcap.a from those sources.
- X
- X If you are recompiling after patching your sources, or if you got your
- X files from somewhere other than the official distribution, "touch
- X makedefs.c" to ensure that certain files (onames.h and pm.h) are remade,
- X lest potentially troublesome timestamps fool "make."
- X
- X8. Now, enter "make all", and take a long siesta; your computer will be
- X occupied for a long time. If all goes well, you will get an executable.
- X If you tried to compile in too many features, you will probably get a
- X dysfunctional executable, and will have to start over.
- X
- X Hint 1: If you're short on memory, you might enter "make -n all
- X >make.bat," and then run script.bat with some sort of batch
- X program or with the gulam command "script make.bat."
- X
- X Hint 2: You'll save yourself a lot of grief if you use the GNU
- X version of the "make" program. Some of the smaller makes aren't
- X completely compatible. GNU software for the Atari is widely
- X available; for example, by anonymous FTP from atari.archive.umich.edu.
- X
- X9. Make sure the support files-- data, rumors, cmdhelp, opthelp, help, hh,
- X history, license, and oracles (if ORACLES was #define'd)-- were copied
- X to the game directory. If not, move them there from the auxil directory
- X yourself. rumors can be created manually by entering "makedefs -r;"
- X data by entering "makedefs -d."
- X
- X Also, make sure that the various level files (*.lev, from the dat
- X subdirectory) were copied over correctly. If you're not sure what files
- X should have been made, double check with Makefile.dat.
- X
- X10. Go to the src\atari directory. Copy atari.cnf to your game directory
- X as NetHack.cnf. Edit it to reflect your particular setup and personal
- X preferences, following the comments.
- X
- X If you compiled in the TERMLIB feature, also move the "termcap" file to
- X your game directory. (Note: gcc's termcap routines have built-in
- X defaults, so the termcap file is not necessary with that compiler.)
- X
- X To use funky graphics characters in TOS, uudecode "atarifnt.uue" and unarc
- X the resulting "atarifnt.arc". This contains a program to run that makes
- X some line graphics characters available to NetHack. To use them, uncomment
- X the appropriate line in your NetHack.cnf file, and run the program before
- X running NetHack (you can put the program in an AUTO folder if you want).
- X This font won't work if you're running Speedo GDOS (and possibly other
- X GDOS variants). I hope to have a bitmapped GDOS font suitable for
- X NetHack 3.1 "Real Soon Now."
- X
- X If you're running NetHack from the MultiTOS desktop, and you want a
- X more useful set of drop down menus than the plain system "File/Edit"
- X ones, copy nethack.mnu to your games directory. This file contains a
- X menu definition that puts a lot of the common commands into the menu.
- X
- X11. Play NetHack. If it works, you're done!
- X
- X
- XNotes
- X-----
- X
- X1) Save files and bones files from previous versions will not work with
- X NetHack 3.1. Don't bother trying to keep them.
- X
- X2) To install an update of NetHack after changing something, enter "make"
- X from the src directory. If you add, delete, or reorder monsters or
- X objects, or you change the format of saved level files, delete any save
- X and bones files. (Trying to use such files sometimes produces amusing
- X confusions on the game's part, but more often produces crashes.)
- X
- END_OF_FILE
- if test 8575 -ne `wc -c <'sys/atari/Install.tos'`; then
- echo shar: \"'sys/atari/Install.tos'\" unpacked with wrong size!
- fi
- # end of 'sys/atari/Install.tos'
- fi
- if test -f 'win/X11/winX.c' -a "${1}" != "-c" ; then
- echo shar: Will not clobber existing file \"'win/X11/winX.c'\"
- else
- echo shar: Extracting \"'win/X11/winX.c'\" \(45228 characters\)
- sed "s/^X//" >'win/X11/winX.c' <<'END_OF_FILE'
- X/* SCCS Id: @(#)winX.c 3.1 93/01/22 */
- X/* Copyright (c) Dean Luick, 1992 */
- X/* NetHack may be freely redistributed. See license for details. */
- X
- X/*
- X * "Main" file for the X window-port. This contains most of the interface
- X * routines. Please see doc/window.doc for an description of the window
- X * interface.
- X */
- X#include <X11/Intrinsic.h>
- X#include <X11/StringDefs.h>
- X#include <X11/Shell.h>
- X#include <X11/Xaw/AsciiText.h>
- X#include <X11/Xaw/Label.h>
- X#include <X11/Xaw/Form.h>
- X#include <X11/Xaw/Cardinals.h>
- X#include <X11/Xatom.h>
- X#include <X11/Xos.h>
- X/* for color support; should be ifdef TEXTCOLOR, but must come before hack.h */
- X#include <X11/IntrinsicP.h>
- X
- X#include "hack.h"
- X#include "winX.h"
- X
- X/* Should be defined in <X11/Intrinsic.h> but you never know */
- X#ifndef XtSpecificationRelease
- X#define XtSpecificationRelease 0
- X#endif
- X
- X/*
- X * Icons.
- X */
- X#include "../win/X11/nh72icon"
- X#include "../win/X11/nh56icon"
- X#include "../win/X11/nh32icon"
- X
- Xstatic struct icon_info {
- X const char *name;
- X char *bits;
- X unsigned width, height;
- X} icon_data[] = {
- X { "nh72", nh72icon_bits, nh72icon_width, nh72icon_height },
- X { "nh56", nh56icon_bits, nh56icon_width, nh56icon_height },
- X { "nh32", nh32icon_bits, nh32icon_width, nh32icon_height },
- X { NULL, NULL, 0, 0 }
- X};
- X
- X/*
- X * Private global variables (shared among the window port files).
- X */
- Xstruct xwindow window_list[MAX_WINDOWS];
- XAppResources appResources;
- Xvoid (*input_func)();
- Xint click_x, click_y, click_button; /* Click position on a map window */
- X /* (filled by set_button_values()). */
- X
- X
- X/* Interface definition, for windows.c */
- Xstruct window_procs X11_procs = {
- X "X11",
- X X11_init_nhwindows,
- X X11_player_selection,
- X X11_askname,
- X X11_get_nh_event,
- X X11_exit_nhwindows,
- X X11_suspend_nhwindows,
- X X11_resume_nhwindows,
- X X11_create_nhwindow,
- X X11_clear_nhwindow,
- X X11_display_nhwindow,
- X X11_destroy_nhwindow,
- X X11_curs,
- X X11_putstr,
- X X11_display_file,
- X X11_start_menu,
- X X11_add_menu,
- X X11_end_menu,
- X X11_select_menu,
- X X11_update_inventory,
- X X11_mark_synch,
- X X11_wait_synch,
- X#ifdef CLIPPING
- X X11_cliparound,
- X#endif
- X X11_print_glyph,
- X X11_raw_print,
- X X11_raw_print_bold,
- X X11_nhgetch,
- X X11_nh_poskey,
- X X11_nhbell,
- X X11_doprev_message,
- X X11_yn_function,
- X X11_getlin,
- X#ifdef COM_COMPL
- X X11_get_ext_cmd,
- X#endif /* COM_COMPL */
- X X11_number_pad,
- X X11_delay_output,
- X /* other defs that really should go away (they're tty specific) */
- X X11_start_screen,
- X X11_end_screen,
- X};
- X
- X/*
- X * Local functions.
- X */
- Xstatic void FDECL(dismiss_file, (Widget, XEvent*, String*, Cardinal*));
- Xstatic void FDECL(yn_key, (Widget, XEvent*, String*, Cardinal*));
- Xstatic int FDECL(input_event, (int));
- Xstatic void NDECL(init_standard_windows);
- X
- X
- X/*
- X * Local variables.
- X */
- Xstatic boolean x_inited = FALSE; /* TRUE if window system is set up. */
- Xstatic winid message_win = WIN_ERR, /* These are the winids of the */
- X map_win = WIN_ERR, /* message, map, and status */
- X status_win = WIN_ERR; /* windows, when they are created */
- X /* in init_windows(). */
- Xstatic Pixmap icon_pixmap = None; /* Pixmap for icon. */
- X
- X/*
- X * Find the window structure that corresponds to the given widget. Note
- X * that this is not the popup widget, nor the viewport, but the child.
- X */
- Xstruct xwindow *
- Xfind_widget(w)
- X Widget w;
- X{
- X int windex;
- X struct xwindow *wp;
- X
- X /* This is sad. Search to find the corresponding window. */
- X for (windex = 0, wp = window_list; windex < MAX_WINDOWS; windex++, wp++)
- X if (wp->type != NHW_NONE && wp->w == w) break;
- X if (windex == MAX_WINDOWS) panic("find_widget: can't match widget");
- X return wp;
- X}
- X
- X/*
- X * Find a free window slot for use.
- X */
- Xstatic winid
- Xfind_free_window()
- X{
- X int windex;
- X struct xwindow *wp;
- X
- X for (windex = 0, wp = &window_list[0]; windex < MAX_WINDOWS; windex++, wp++)
- X if (wp->type == NHW_NONE) break;
- X
- X if (windex == MAX_WINDOWS)
- X panic("find_free_window: no free windows!");
- X return (winid) windex;
- X}
- X
- X#ifdef TEXTCOLOR
- X/*
- X * Color conversion. The default X11 color converters don't try very
- X * hard to find matching colors in PseudoColor visuals. If they can't
- X * allocate the exact color, they puke and give you something stupid.
- X * This is an attempt to find some close readonly cell and use it.
- X */
- XXtConvertArgRec const nhcolorConvertArgs[] = {
- X {XtWidgetBaseOffset, (XtPointer)XtOffset(Widget, core.screen),
- X sizeof(Screen *)},
- X {XtWidgetBaseOffset, (XtPointer)XtOffset(Widget, core.colormap),
- X sizeof(Colormap)}
- X};
- X
- X#define done(type, value) \
- X { \
- X if (toVal->addr != NULL) { \
- X if (toVal->size < sizeof(type)) { \
- X toVal->size = sizeof(type); \
- X return False; \
- X } \
- X *(type*)(toVal->addr) = (value); \
- X } \
- X else { \
- X static type static_val; \
- X static_val = (value); \
- X toVal->addr = (genericptr_t)&static_val; \
- X } \
- X toVal->size = sizeof(type); \
- X return True; \
- X }
- X
- X/* decl.h declares these, but it screws up structure references -dlc */
- X#undef red
- X#undef green
- X#undef blue
- X
- X/* Return True if something close was found. */
- XBoolean
- XnhCloseColor(screen, colormap, str, color)
- XScreen *screen; /* screen to use */
- XColormap colormap; /* the colormap to use */
- Xchar *str; /* color name */
- XXColor *color; /* the X color structure; changed only if successful */
- X{
- X int ncells;
- X long cdiff = 16777216; /* 2^24; hopefully our map is smaller */
- X XColor tmp;
- X static XColor *table = 0;
- X register i, j;
- X register long tdiff;
- X
- X /* if the screen doesn't have a big colormap, don't waste our time */
- X /* or if it's huge, and _some_ match should have been possible */
- X if((ncells = CellsOfScreen(screen)) < 256 || ncells > 4096)
- X return False;
- X
- X if (!XParseColor(DisplayOfScreen(screen), colormap, str, &tmp))
- X return False;
- X
- X if (!table) {
- X table = (XColor *) XtCalloc(ncells, sizeof(XColor));
- X for(i=0; i<ncells; i++)
- X table[i].pixel = i;
- X XQueryColors(DisplayOfScreen(screen), colormap, table, ncells);
- X }
- X
- X /* go thru cells and look for the one with smallest diff */
- X /* diff is calculated abs(reddiff)+abs(greendiff)+abs(bluediff) */
- X /* a more knowledgeable color person might improve this -dlc */
- X for(i=0; i<ncells; i++) {
- X if(table[i].flags == tmp.flags) {
- X j = (int)table[i].red - (int)tmp.red;
- X if(j < 0) j = -j;
- X tdiff = j;
- X j = (int)table[i].green - (int)tmp.green;
- X if(j < 0) j = -j;
- X tdiff += j;
- X j = (int)table[i].blue - (int)tmp.blue;
- X if(j < 0) j = -j;
- X tdiff += j;
- X if(tdiff < cdiff) {
- X cdiff = tdiff;
- X tmp.pixel = i; /* table[i].pixel == i */
- X }
- X }
- X }
- X
- X if(cdiff == 16777216) return False; /* nothing found?! */
- X
- X /*
- X * Found something. Return it and mark this color as used to avoid
- X * reuse. Reuse causes major contrast problems :-)
- X */
- X color->pixel = tmp.pixel;
- X table[tmp.pixel].flags = 0;
- X return True;
- X}
- X
- XBoolean
- XnhCvtStringToPixel(dpy, args, num_args, fromVal, toVal, closure_ret)
- XDisplay* dpy;
- XXrmValuePtr args;
- XCardinal *num_args;
- XXrmValuePtr fromVal;
- XXrmValuePtr toVal;
- XXtPointer *closure_ret;
- X{
- X String str = (String)fromVal->addr;
- X XColor screenColor;
- X XColor exactColor;
- X Screen *screen;
- X XtAppContext app = XtDisplayToApplicationContext(dpy);
- X Colormap colormap;
- X Status status;
- X String params[1];
- X Cardinal num_params=1;
- X
- X if (*num_args != 2) {
- X XtAppWarningMsg(app, "wrongParameters", "cvtStringToPixel",
- X "XtToolkitError",
- X "String to pixel conversion needs screen and colormap arguments",
- X (String *)NULL, (Cardinal *)NULL);
- X return False;
- X }
- X
- X screen = *((Screen **) args[0].addr);
- X colormap = *((Colormap *) args[1].addr);
- X
- X /* If Xt colors, use the Xt routine and hope for the best */
- X#if (XtSpecificationRelease >= 5)
- X if ((strcmpi(str, XtDefaultBackground) == 0) ||
- X (strcmpi(str, XtDefaultForeground) == 0)) {
- X return
- X XtCvtStringToPixel(dpy, args, num_args, fromVal, toVal, closure_ret);
- X }
- X#else
- X if (strcmpi(str, XtDefaultBackground) == 0) {
- X *closure_ret = (char*)False;
- X done(Pixel, WhitePixelOfScreen(screen));
- X }
- X if (strcmpi(str, XtDefaultForeground) == 0) {
- X *closure_ret = (char*)False;
- X done(Pixel, BlackPixelOfScreen(screen));
- X }
- X#endif
- X
- X status = XAllocNamedColor(DisplayOfScreen(screen), colormap,
- X (char*)str, &screenColor, &exactColor);
- X if (status == 0) {
- X String msg, type;
- X params[0] = str;
- X /* Server returns a specific error code but Xlib discards it. Ugh */
- X if (XLookupColor(DisplayOfScreen(screen), colormap, (char*)str,
- X &exactColor, &screenColor)) {
- X /* try to find another color that will do */
- X if (nhCloseColor(screen, colormap, (char*) str, &screenColor)) {
- X *closure_ret = (char*)True;
- X done(Pixel, screenColor.pixel);
- X }
- X type = "noColormap";
- X msg = "Cannot allocate colormap entry for \"%s\"";
- X }
- X else {
- X type = "badValue";
- X msg = "Color name \"%s\" is not defined";
- X }
- X
- X XtAppWarningMsg(app, type, "cvtStringToPixel",
- X "XtToolkitError", msg, params, &num_params);
- X *closure_ret = False;
- X return False;
- X } else {
- X *closure_ret = (char*)True;
- X done(Pixel, screenColor.pixel);
- X }
- X}
- X
- X/* ARGSUSED */
- Xstatic void
- XnhFreePixel(app, toVal, closure, args, num_args)
- XXtAppContext app;
- XXrmValuePtr toVal;
- XXtPointer closure;
- XXrmValuePtr args;
- XCardinal *num_args;
- X{
- X Screen *screen;
- X Colormap colormap;
- X
- X if (*num_args != 2) {
- X XtAppWarningMsg(app, "wrongParameters",
- X "freePixel", "XtToolkitError",
- X "Freeing a pixel requires screen and colormap arguments",
- X (String *)NULL, (Cardinal *)NULL);
- X return;
- X }
- X
- X screen = *((Screen **) args[0].addr);
- X colormap = *((Colormap *) args[1].addr);
- X
- X if (closure) {
- X XFreeColors( DisplayOfScreen(screen), colormap,
- X (unsigned long*)toVal->addr, 1, (unsigned long)0
- X );
- X }
- X}
- X#endif /* TEXTCOLOR */
- X
- X/* Global Functions ======================================================== */
- Xvoid
- XX11_raw_print(str)
- X const char *str;
- X{
- X (void) puts(str);
- X}
- X
- Xvoid
- XX11_raw_print_bold(str)
- X const char *str;
- X{
- X (void) puts(str);
- X}
- X
- Xvoid
- XX11_curs(window, x, y)
- X winid window;
- X int x, y;
- X{
- X check_winid(window);
- X
- X if (x < 0 || x >= COLNO) {
- X impossible("curs: bad x value [%d]", x);
- X x = 0;
- X }
- X if (y < 0 || y >= ROWNO) {
- X impossible("curs: bad y value [%d]", y);
- X y = 0;
- X }
- X
- X window_list[window].cursx = x;
- X window_list[window].cursy = y;
- X}
- X
- Xvoid
- XX11_putstr(window, attr, str)
- X winid window;
- X int attr;
- X const char *str;
- X{
- X winid new_win;
- X struct xwindow *wp;
- X
- X check_winid(window);
- X wp = &window_list[window];
- X
- X switch (wp->type) {
- X case NHW_MESSAGE:
- X Strcpy(toplines, str); /* for Norep(). */
- X append_message(wp, str);
- X break;
- X case NHW_STATUS:
- X adjust_status(wp, str);
- X break;
- X case NHW_MAP:
- X impossible("putstr: called on map window \"%s\"", str);
- X break;
- X case NHW_MENU:
- X if (wp->menu_information->is_menu) {
- X impossible(
- X "putstr: called on a menu window, \"%s\" discarded",
- X str);
- X break;
- X }
- X /*
- X * Change this menu window into a text window by creating a
- X * new text window, then copying it to this winid.
- X */
- X new_win = X11_create_nhwindow(NHW_TEXT);
- X X11_destroy_nhwindow(window);
- X *wp = window_list[new_win];
- X window_list[new_win].type = NHW_NONE; /* allow re-use */
- X /* fall though to add text */
- X case NHW_TEXT:
- X add_to_text_window(wp, attr, str);
- X break;
- X default:
- X impossible("putstr: unknown window type [%d] \"%s\"",
- X wp->type, str);
- X }
- X}
- X
- X/* We do event processing as a callback, so this is a null routine. */
- Xvoid X11_get_nh_event() { return; }
- X
- Xint
- XX11_nhgetch()
- X{
- X return input_event(EXIT_ON_KEY_PRESS);
- X}
- X
- X
- Xint
- XX11_nh_poskey(x, y, mod)
- X int *x, *y, *mod;
- X{
- X int val = input_event(EXIT_ON_KEY_OR_BUTTON_PRESS);
- X
- X if (val == 0) { /* user clicked on a map window */
- X *x = click_x;
- X *y = click_y;
- X *mod = click_button;
- X }
- X return val;
- X}
- X
- X
- Xwinid
- XX11_create_nhwindow(type)
- X int type;
- X{
- X winid window;
- X struct xwindow *wp;
- X
- X if (!x_inited)
- X panic("create_nhwindow: windows not initialized");
- X
- X /*
- X * We have already created the standard message, map, and status
- X * windows in the window init routine. The first window of that
- X * type to be created becomes the standard.
- X *
- X * A better way to do this would be to say that init_nhwindows()
- X * has already defined these three windows.
- X */
- X if (type == NHW_MAP && map_win != WIN_ERR) {
- X window = map_win;
- X map_win = WIN_ERR;
- X return window;
- X }
- X if (type == NHW_MESSAGE && message_win != WIN_ERR) {
- X window = message_win;
- X message_win = WIN_ERR;
- X return window;
- X }
- X if (type == NHW_STATUS && status_win != WIN_ERR) {
- X window = status_win;
- X status_win = WIN_ERR;
- X return window;
- X }
- X
- X window = find_free_window();
- X wp = &window_list[window];
- X
- X /* The create routines will set type, popup, w, and Win_info. */
- X wp->prevx = wp->prevy = wp->cursx = wp->cursy =
- X wp->pixel_width = wp->pixel_height = 0;
- X
- X switch (type) {
- X case NHW_MAP:
- X create_map_window(wp, TRUE, (Widget) 0);
- X break;
- X case NHW_MESSAGE:
- X create_message_window(wp, TRUE, (Widget) 0);
- X break;
- X case NHW_STATUS:
- X create_status_window(wp, TRUE, (Widget) 0);
- X break;
- X case NHW_MENU:
- X create_menu_window(wp);
- X break;
- X case NHW_TEXT:
- X create_text_window(wp);
- X break;
- X default:
- X panic("create_nhwindow: unknown type [%d]\n", type);
- X break;
- X }
- X return window;
- X}
- X
- Xvoid
- XX11_clear_nhwindow(window)
- X winid window;
- X{
- X struct xwindow *wp;
- X
- X check_winid(window);
- X wp = &window_list[window];
- X
- X switch (wp->type) {
- X case NHW_MAP:
- X clear_map_window(wp);
- X break;
- X case NHW_STATUS:
- X case NHW_TEXT:
- X case NHW_MENU:
- X case NHW_MESSAGE:
- X /* do nothing for these window types */
- X break;
- X default:
- X panic("clear_nhwindow: unknown window type [%d]\n", wp->type);
- X break;
- X }
- X}
- X
- Xvoid
- XX11_display_nhwindow(window, blocking)
- X winid window;
- X boolean blocking;
- X{
- X struct xwindow *wp;
- X check_winid(window);
- X
- X wp = &window_list[window];
- X
- X switch (wp->type) {
- X case NHW_MAP:
- X if (wp->popup)
- X nh_XtPopup(wp->popup, XtGrabNone, wp->w);
- X /*else
- X * XtMapWidget(toplevel);
- X *
- X * We don't need to do the above because we never have
- X * MappedWhenManaged unset because the DEC server doesn't
- X * like it. See comment above XtSetMappedWhenManaged() in
- X * init_standard_windows().
- X */
- X display_map_window(wp); /* flush map */
- X
- X /*
- X * We need to flush the message window here due to the way the tty
- X * port is set up. To flush a window, you need to call this
- X * routine. However, the tty port _pauses_ with a --more-- if we
- X * do a display_nhwindow(WIN_MESSAGE, FALSE). Thus, we can't call
- X * display_nhwindow(WIN_MESSAGE,FALSE) in parse() because then we
- X * get a --more-- after every line.
- X *
- X * Perhaps the window document should mention that when the map
- X * is flushed, everything on the three main windows should be
- X * flushed. Note: we don't need to flush the status window
- X * because we don't buffer changes.
- X */
- X if (WIN_MESSAGE != WIN_ERR)
- X display_message_window(&window_list[WIN_MESSAGE]);
- X if (blocking)
- X (void) x_event(EXIT_ON_KEY_OR_BUTTON_PRESS);
- X break;
- X case NHW_MESSAGE:
- X if (wp->popup)
- X nh_XtPopup(wp->popup, XtGrabNone, wp->w);
- X /*else
- X * XtMapWidget(toplevel);
- X *
- X * See comment in NHW_MAP case.
- X */
- X
- X display_message_window(wp); /* flush messages */
- X break;
- X case NHW_STATUS:
- X if (wp->popup)
- X nh_XtPopup(wp->popup, XtGrabNone, wp->w);
- X /*else
- X * XtMapWidget(toplevel);
- X *
- X * See comment in NHW_MAP case.
- X */
- X
- X break; /* no flushing necessary */
- X case NHW_MENU:
- X (void) X11_select_menu(window); /* pop up menu (global routine) */
- X break;
- X case NHW_TEXT:
- X display_text_window(wp, blocking); /* pop up text window */
- X break;
- X default:
- X panic("display_nhwindow: unknown window type [%d]\n", wp->type);
- X break;
- X }
- X}
- X
- Xvoid
- XX11_destroy_nhwindow(window)
- X winid window;
- X{
- X struct xwindow *wp;
- X check_winid(window);
- X
- X /*
- X * "Zap" known windows, but don't destroy them. We need to keep the
- X * toplevel widget popped up so that later windows (e.g. tombstone)
- X * are visible on DECWindow systems. This is due to the virtual
- X * roots that the DECWindow wm creates.
- X */
- X if (window == WIN_MESSAGE) {
- X WIN_MESSAGE = WIN_ERR;
- X flags.window_inited = 0;
- X return;
- X } else if (window == WIN_MAP) {
- X WIN_MAP = WIN_ERR;
- X return;
- X } else if (window == WIN_STATUS) {
- X WIN_STATUS = WIN_ERR;
- X return;
- X } else if (window == WIN_INVEN) {
- X WIN_INVEN = WIN_ERR;
- X return;
- X }
- X
- X wp = &window_list[window];
- X
- X switch (wp->type) {
- X case NHW_MAP:
- X destroy_map_window(wp);
- X break;
- X case NHW_MENU:
- X destroy_menu_window(wp);
- X break;
- X case NHW_TEXT:
- X destroy_text_window(wp);
- X break;
- X case NHW_STATUS:
- X destroy_status_window(wp);
- X break;
- X case NHW_MESSAGE:
- X destroy_message_window(wp);
- X break;
- X default:
- X panic("destroy_nhwindow: unknown window type [%d]", wp->type);
- X break;
- X }
- X}
- X
- X/* We don't implement a continous invent screen, so this is null. */
- Xvoid X11_update_inventory() { return; }
- X
- X/* The current implementation has all of the saved lines on the screen. */
- Xint X11_doprev_message() { return 0; }
- X
- Xvoid
- XX11_nhbell()
- X{
- X /* We can't use XBell until toplevel has been initialized. */
- X if (x_inited)
- X XBell(XtDisplay(toplevel), 0);
- X /* else print ^G ?? */
- X}
- X
- Xvoid X11_mark_synch()
- X{
- X if (x_inited) {
- X /*
- X * the window document is a bit unclear about the status of text
- X * that has been pline()d but not displayed w/display_nhwindow(),
- X * though the main code and tty code assume that a pline() followed
- X * by mark_synch() results in the text being seen, even if
- X * display_nhwindow() wasn't called. Duplicate this behavior.
- X */
- X if (WIN_MESSAGE != WIN_ERR)
- X display_message_window(&window_list[WIN_MESSAGE]);
- X XSync(XtDisplay(toplevel), False);
- X }
- X}
- X
- Xvoid X11_wait_synch() {if (x_inited) XFlush(XtDisplay(toplevel)); }
- X
- X
- X/* Both resume_ and suspend_ are called from ioctl.c and unixunix.c. */
- Xvoid X11_resume_nhwindows() { return; }
- X
- X/* ARGSUSED */
- Xvoid X11_suspend_nhwindows(str) const char *str; { return; }
- X
- X/* Under X, we don't need to initialize the number pad. */
- X/* ARGSUSED */
- Xvoid X11_number_pad(state) int state; { return; } /* called from options.c */
- X
- X
- Xvoid X11_start_screen() { return; } /* called from setftty() in unixtty.c */
- Xvoid X11_end_screen() { return; } /* called from settty() in unixtty.c */
- X
- X
- X/* init and exit nhwindows ------------------------------------------------- */
- X
- XXtAppContext app_context; /* context of application */
- XWidget toplevel = (Widget) 0; /* toplevel widget */
- X
- Xstatic XtActionsRec actions[] = {
- X {"dismiss_file", dismiss_file}, /* action for file viewing widget */
- X {"dismiss_text", dismiss_text}, /* button action for text widget */
- X {"key_dismiss_text",key_dismiss_text},/* key action for text widget */
- X {"menu_key", menu_key}, /* action for menu accelerators */
- X {"yn_key", yn_key}, /* action for yn accelerators */
- X {"ec_key", ec_key}, /* action for extended commands */
- X {"ps_key", ps_key}, /* action for player selection */
- X};
- X
- Xstatic XtResource resources[] = {
- X { "slow", "Slow", XtRBoolean, sizeof(Boolean),
- X XtOffset(AppResources *,slow), XtRString, "False" },
- X { "autofocus", "AutoFocus", XtRBoolean, sizeof(Boolean),
- X XtOffset(AppResources *,autofocus), XtRString, "False" },
- X { "message_line", "Message_line", XtRBoolean, sizeof(Boolean),
- X XtOffset(AppResources *,message_line), XtRString, "False" },
- X { "icon", "Icon", XtRString, sizeof(String),
- X XtOffset(AppResources *,icon), XtRString, "nh72" },
- X};
- X
- Xvoid
- XX11_init_nhwindows()
- X{
- X static const char *banner_text[] = {
- X "NetHack",
- X "Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993",
- X "by Stichting Mathematisch Centrum and M. Stephenson.",
- X "See license for details.",
- X "",
- X "",
- X 0
- X };
- X static const char *av[] = { "nethack" };
- X register const char **pp;
- X int i;
- X Cardinal num_args;
- X Arg args[4];
- X
- X /* Init windows to nothing. */
- X for (i = 0; i < MAX_WINDOWS; i++)
- X window_list[i].type = NHW_NONE;
- X
- X XSetIOErrorHandler((XIOErrorHandler) hangup);
- X
- X i = 1;
- X num_args = 0;
- X XtSetArg(args[num_args], XtNallowShellResize, True); num_args++;
- X toplevel = XtAppInitialize(
- X &app_context,
- X "NetHack", /* application class */
- X NULL, 0, /* options list */
- X &i, av, /* command line args */
- X NULL, /* fallback resources */
- X args, num_args);
- X
- X /* We don't need to realize the top level widget. */
- X
- X#ifdef TEXTCOLOR
- X /* add new color converter to deal with overused colormaps */
- X XtSetTypeConverter(XtRString, XtRPixel, nhCvtStringToPixel,
- X nhcolorConvertArgs, XtNumber(nhcolorConvertArgs),
- X XtCacheByDisplay, nhFreePixel);
- X#endif /* TEXTCOLOR */
- X
- X /* Register the actions mentioned in "actions". */
- X XtAppAddActions(app_context, actions, XtNumber(actions));
- X
- X /* Get application-wide resources */
- X XtGetApplicationResources(toplevel,(XtPointer)&appResources,
- X resources,XtNumber(resources),NULL,ZERO);
- X
- X /* Initialize other things. */
- X init_standard_windows();
- X init_extended_commands_popup();
- X
- X /* Give the window manager an icon to use; toplevel must be realized. */
- X if (appResources.icon && *appResources.icon) {
- X struct icon_info *ip;
- X
- X for (ip = icon_data; ip->name; ip++)
- X if (!strcmp(appResources.icon, ip->name)) {
- X icon_pixmap = XCreateBitmapFromData(XtDisplay(toplevel),
- X XtWindow(toplevel),
- X ip->bits, ip->width, ip->height);
- X if (icon_pixmap != None) {
- X XWMHints hints;
- X
- X hints.flags = IconPixmapHint;
- X hints.icon_pixmap = icon_pixmap;
- X XSetWMHints(XtDisplay(toplevel),
- X XtWindow(toplevel), &hints);
- X }
- X break;
- X }
- X }
- X
- X x_inited = TRUE; /* X is now initialized */
- X
- X /* Display the startup banner in the message window. */
- X for (pp = banner_text; *pp; pp++)
- X X11_putstr(WIN_MESSAGE, 0, *pp);
- X}
- X
- X/*
- X * Let the OS take care of almost everything. This includes the "main"
- X * three windows: message, map, and status. Note that if I destroy one of
- X * the three main windows, they all will be destroyed, due to their shared
- X * parent. I currently don't check such a thing occuring, so the whole mess
- X * will probably crash&burn if I tried it.
- X */
- X/* ARGSUSED */
- Xvoid X11_exit_nhwindows(dummy)
- X const char *dummy;
- X{
- X /* explicitly free the icon pixmap */
- X if (icon_pixmap != None) {
- X XFreePixmap(XtDisplay(toplevel), icon_pixmap);
- X icon_pixmap = None;
- X }
- X}
- X
- X
- X/* delay_output ------------------------------------------------------------ */
- X
- X/*
- X * Timeout callback for delay_output(). Send a fake message to the map
- X * window.
- X */
- X/* ARGSUSED */
- Xstatic void
- Xd_timeout(client_data, id)
- X XtPointer client_data;
- X XtIntervalId *id;
- X{
- X XEvent event;
- X XClientMessageEvent *mesg;
- X
- X /* Set up a fake message to the event handler. */
- X mesg = (XClientMessageEvent *) &event;
- X mesg->type = ClientMessage;
- X mesg->message_type = XA_STRING;
- X mesg->format = 8;
- X XSendEvent(XtDisplay(window_list[WIN_MAP].w),
- X XtWindow(window_list[WIN_MAP].w),
- X False,
- X NoEventMask,
- X (XEvent*) mesg);
- X}
- X
- X/*
- X * Delay for 50ms. This is not implemented asynch. Maybe later.
- X * Start the timeout, then wait in the event loop. The timeout
- X * function will send an event to the map window which will be waiting
- X * for a sent event.
- X */
- Xvoid
- XX11_delay_output()
- X{
- X if (!x_inited) return;
- X
- X (void) XtAppAddTimeOut(app_context, 30L, d_timeout, (XtPointer) 0);
- X
- X /* The timeout function will enable the event loop exit. */
- X (void) x_event(EXIT_ON_SENT_EVENT);
- X}
- X
- X
- X/* askname ----------------------------------------------------------------- */
- X/* Callback for askname dialog widget. */
- X/* ARGSUSED */
- Xstatic void
- Xaskname_done(w, client_data, call_data)
- X Widget w;
- X XtPointer client_data;
- X XtPointer call_data;
- X{
- X int len;
- X char *s;
- X Widget dialog = (Widget) client_data;
- X
- X s = (char *) GetDialogResponse(dialog);
- X
- X len = strlen(s);
- X if (len == 0) {
- X X11_nhbell();
- X return;
- X }
- X
- X /* Truncate name if necessary */
- X if (len >= sizeof(plname)-1)
- X len = sizeof(plname)-1;
- X
- X (void) strncpy(plname, s, len);
- X plname[len] = '\0';
- X
- X nh_XtPopdown(XtParent(dialog));
- X exit_x_event = TRUE;
- X}
- X
- Xvoid
- XX11_askname()
- X{
- X Widget popup, dialog;
- X Arg args[1];
- X
- X XtSetArg(args[0], XtNallowShellResize, True);
- X
- X popup = XtCreatePopupShell("askname", transientShellWidgetClass,
- X toplevel, args, ONE);
- X
- X dialog = CreateDialog(popup, "dialog",
- X askname_done, (XtCallbackProc) 0);
- X
- X SetDialogPrompt(dialog, "What is your name?"); /* set prompt */
- X SetDialogResponse(dialog, ""); /* set default answer */
- X
- X XtRealizeWidget(popup);
- X positionpopup(popup); /* center on cursor */
- X
- X nh_XtPopup(popup, XtGrabExclusive, dialog);
- X
- X /* The callback will enable the event loop exit. */
- X (void) x_event(EXIT_ON_EXIT);
- X}
- X
- X
- X/* getline ----------------------------------------------------------------- */
- X/* This uses Tim Theisen's dialog widget set (from GhostView). */
- X
- Xstatic Widget getline_popup, getline_dialog;
- X
- X#define CANCEL_STR "\033"
- Xstatic char *getline_input;
- X
- X
- X/* Callback for getline dialog widget. */
- X/* ARGSUSED */
- Xstatic void
- Xdone_button(w, client_data, call_data)
- X Widget w;
- X XtPointer client_data;
- X XtPointer call_data;
- X{
- X char *s;
- X Widget dialog = (Widget) client_data;
- X
- X s = (char *) GetDialogResponse(dialog);
- X
- X if (strlen(s) == 0)
- X Strcpy(getline_input, CANCEL_STR);
- X else
- X Strcpy(getline_input, s);
- X
- X nh_XtPopdown(XtParent(dialog));
- X exit_x_event = TRUE;
- X}
- X
- X/* Callback for getline dialog widget. */
- X/* ARGSUSED */
- Xstatic void
- Xabort_button(w, client_data, call_data)
- X Widget w;
- X XtPointer client_data;
- X XtPointer call_data;
- X{
- X Widget dialog = (Widget) client_data;
- X
- X Strcpy(getline_input, CANCEL_STR);
- X nh_XtPopdown(XtParent(dialog));
- X exit_x_event = TRUE;
- X}
- X
- X
- Xvoid
- XX11_getlin(question, input)
- X const char *question;
- X char *input;
- X{
- X static boolean need_to_init = True;
- X
- X getline_input = input;
- X
- X flush_screen(1);
- X if (need_to_init) {
- X Arg args[1];
- X
- X need_to_init = False;
- X
- X XtSetArg(args[0], XtNallowShellResize, True);
- X
- X getline_popup = XtCreatePopupShell("getline",transientShellWidgetClass,
- X toplevel, args, ONE);
- X
- X getline_dialog = CreateDialog(getline_popup, "dialog",
- X done_button, abort_button);
- X
- X XtRealizeWidget(getline_popup);
- X }
- X SetDialogPrompt(getline_dialog, question); /* set prompt */
- X SetDialogResponse(getline_dialog, ""); /* set default answer */
- X positionpopup(getline_popup); /* center on cursor */
- X
- X nh_XtPopup(getline_popup, XtGrabNone, getline_dialog);
- X
- X /* The callback will enable the event loop exit. */
- X (void) x_event(EXIT_ON_EXIT);
- X}
- X
- X
- X/* Display file ------------------------------------------------------------ */
- Xstatic const char display_translations[] =
- X "#override\n\
- X <BtnDown>: dismiss_file()";
- X
- X
- X/* Callback for file dismissal. */
- X/*ARGSUSED*/
- Xstatic void
- Xdismiss_file(w, event, params, num_params)
- X Widget w;
- X XEvent *event;
- X String *params;
- X Cardinal *num_params;
- X{
- X Widget popup = XtParent(w);
- X nh_XtPopdown(popup);
- X XtDestroyWidget(popup);
- X}
- X
- Xvoid
- XX11_display_file(str, complain)
- X const char *str;
- X boolean complain;
- X{
- X FILE *fp;
- X Arg args[12];
- X Cardinal num_args;
- X Widget popup, dispfile;
- X Position top_margin, bottom_margin, left_margin, right_margin;
- X XFontStruct *fs;
- X int new_width, new_height;
- X#define LLEN 128
- X char line[LLEN];
- X int num_lines;
- X
- X /* Use the port-independent file opener to see if the file exists. */
- X fp = fopen_datafile(str, "r");
- X
- X if (!fp) {
- X if(complain) pline("Cannot open %s. Sorry.", str);
- X
- X return; /* it doesn't exist, ignore */
- X }
- X
- X /*
- X * Count the number of lines in the file. If under the max display
- X * size, use that instead.
- X */
- X num_lines = 0;
- X while (fgets(line, LLEN, fp)) {
- X num_lines++;
- X if (num_lines >= DISPLAY_FILE_SIZE) break;
- X }
- X
- X (void) fclose(fp);
- X
- X /* Ignore empty files */
- X if (num_lines == 0) return;
- X
- X num_args = 0;
- X XtSetArg(args[num_args], XtNtitle, str); num_args++;
- X
- X popup = XtCreatePopupShell("display_file", topLevelShellWidgetClass,
- X toplevel, args, num_args);
- X
- X num_args = 0;
- X XtSetArg(args[num_args], XtNscrollHorizontal,
- X XawtextScrollWhenNeeded); num_args++;
- X XtSetArg(args[num_args], XtNscrollVertical,
- X XawtextScrollWhenNeeded); num_args++;
- X XtSetArg(args[num_args], XtNtype, XawAsciiFile); num_args++;
- X XtSetArg(args[num_args], XtNstring, str); num_args++;
- X XtSetArg(args[num_args], XtNdisplayCaret, False); num_args++;
- X XtSetArg(args[num_args], XtNtranslations,
- X XtParseTranslationTable(display_translations)); num_args++;
- X
- X dispfile = XtCreateManagedWidget(
- X "text", /* name */
- X asciiTextWidgetClass,
- X popup, /* parent widget */
- X args, /* set some values */
- X num_args); /* number of values to set */
- X
- X /* Get font and border information. */
- X num_args = 0;
- X XtSetArg(args[num_args], XtNfont, &fs); num_args++;
- X XtSetArg(args[num_args], XtNtopMargin, &top_margin); num_args++;
- X XtSetArg(args[num_args], XtNbottomMargin, &bottom_margin); num_args++;
- X XtSetArg(args[num_args], XtNleftMargin, &left_margin); num_args++;
- X XtSetArg(args[num_args], XtNrightMargin, &right_margin); num_args++;
- X XtGetValues(dispfile, args, num_args);
- X
- X /*
- X * Font height is ascent + descent.
- X *
- X * The data files are currently set up assuming an 80 char wide window
- X * and a fixed width font. Soo..
- X */
- X new_height = num_lines * (fs->ascent + fs->descent) +
- X top_margin + bottom_margin;
- X new_width = 80 * fs->max_bounds.width + left_margin + right_margin;
- X
- X /* Set the new width and height. */
- X num_args = 0;
- X XtSetArg(args[num_args], XtNwidth, new_width); num_args++;
- X XtSetArg(args[num_args], XtNheight, new_height); num_args++;
- X XtSetValues(dispfile, args, num_args);
- X
- X nh_XtPopup(popup, XtGrabNone, None);
- X}
- X
- X
- X/* yn_function ------------------------------------------------------------- */
- X/* (not threaded) */
- X
- Xstatic const char *yn_quitchars = " \n\r";
- Xstatic const char *yn_choices; /* string of acceptable input */
- Xstatic char yn_def;
- Xstatic char yn_return; /* return value */
- Xstatic char yn_esc_map; /* ESC maps to this char. */
- Xstatic Widget yn_popup; /* popup for the yn fuction (created once) */
- Xstatic Widget yn_label; /* label for yn function (created once) */
- Xstatic boolean yn_getting_num; /* TRUE if accepting digits */
- Xstatic int yn_ndigits; /* digit count */
- Xstatic long yn_val; /* accumulated value */
- X
- Xstatic const char yn_translations[] =
- X "#override\n\
- X <Key>: yn_key()";
- X
- X/*
- X * Convert the given key event into a character. If the key maps to
- X * more than one character only the first is returned. If there is
- X * no conversion (i.e. just the CTRL key hit) a NULL is returned.
- X */
- Xchar
- Xkey_event_to_char(key)
- X XKeyEvent *key;
- X{
- X char keystring[MAX_KEY_STRING];
- X int nbytes;
- X
- X nbytes = XLookupString(key, keystring, MAX_KEY_STRING, NULL, NULL);
- X
- X /* Modifier keys return a zero lengh string when pressed. */
- X if (nbytes == 0) return '\0';
- X
- X return keystring[0];
- X}
- X
- X/*
- X * Called when we get a key press event on a yn window.
- X */
- X/* ARGSUSED */
- Xstatic void
- Xyn_key(w, event, params, num_params)
- X Widget w;
- X XEvent *event;
- X String *params;
- X Cardinal *num_params;
- X{
- X char ch;
- X
- X if(appResources.slow && !input_func)
- X extern_map_input(event);
- X
- X ch = key_event_to_char((XKeyEvent *) event);
- X
- X if (ch == '\0') { /* don't accept nul char or modifier event */
- X /* no bell */
- X return;
- X }
- X
- X if (!yn_choices) { /* accept any input */
- X yn_return = ch;
- X } else {
- X ch = lowc(ch); /* move to lower case */
- X
- X if (ch == '\033') {
- X yn_getting_num = FALSE;
- X yn_return = yn_esc_map;
- X } else if (index(yn_quitchars, ch)) {
- X yn_return = yn_def;
- X } else if (index(yn_choices, ch)) {
- X if (ch == '#') {
- X if (yn_getting_num) { /* don't select again */
- X X11_nhbell();
- X return;
- X }
- X yn_getting_num = TRUE;
- X yn_ndigits = 0;
- X yn_val = 0;
- X return; /* wait for more input */
- X }
- X yn_return = ch;
- X if (ch != 'y') yn_getting_num = FALSE;
- X } else {
- X if (yn_getting_num) {
- X if (digit(ch)) {
- X yn_ndigits++;
- X yn_val = (yn_val * 10) + (long) (ch - '0');
- X return; /* wait for more input */
- X }
- X if (yn_ndigits && (ch == '\b' || ch == 127/*DEL*/)) {
- X yn_ndigits--;
- X yn_val = yn_val/ 10;
- X return; /* wait for more input */
- X }
- X }
- X X11_nhbell(); /* no match */
- X return;
- X }
- X
- X if (yn_getting_num) {
- X yn_return = '#';
- X yn_number = yn_val; /* assign global */
- X }
- X }
- X exit_x_event = TRUE; /* exit our event handler */
- X}
- X
- X
- Xchar
- XX11_yn_function(ques, choices, def)
- X const char *ques;
- X const char *choices;
- X char def;
- X{
- X static Boolean need_to_init = True;
- X char buf[QBUFSZ];
- X Arg args[4];
- X Cardinal num_args;
- X
- X yn_choices = choices; /* set up globals for callback to use */
- X yn_def = def;
- X
- X /*
- X * This is sort of a kludge. There are quite a few places in the main
- X * nethack code where a pline containing information is followed by a
- X * call to yn_function(). There is no flush of the message window
- X * (it is implicit in the tty window port), so the line never shows
- X * up for us! Solution: do our own flush.
- X */
- X if (WIN_MESSAGE != WIN_ERR)
- X display_message_window(&window_list[WIN_MESSAGE]);
- X
- X if (choices) {
- X /* ques [choices] (def) */
- X if ((1 + strlen(ques) + 2 + strlen(choices) + 4) >= QBUFSZ)
- X panic("yn_function: question too long");
- X if (def)
- X Sprintf(buf, "%s [%s] (%c)", ques, choices, def);
- X else
- X Sprintf(buf, "%s [%s] ", ques, choices);
- X
- X /* escape maps to 'q' or 'n' or default, in that order */
- X yn_esc_map = (index(choices, 'q') ? 'q' :
- X (index(choices, 'n') ? 'n' :
- X def));
- X } else {
- X if ((1 + strlen(ques)) >= QBUFSZ)
- X panic("yn_function: question too long");
- X Strcpy(buf, ques);
- X }
- X
- X if (!appResources.slow && need_to_init) {
- X need_to_init = False;
- X
- X XtSetArg(args[0], XtNallowShellResize, True);
- X yn_popup = XtCreatePopupShell("query", transientShellWidgetClass,
- X toplevel, args, ONE);
- X
- X num_args = 0;
- X XtSetArg(args[num_args], XtNtranslations,
- X XtParseTranslationTable(yn_translations)); num_args++;
- X yn_label = XtCreateManagedWidget("yn_label",
- X labelWidgetClass,
- X yn_popup,
- X args, num_args);
- X
- X XtRealizeWidget(yn_popup);
- X }
- X
- X if(appResources.slow)
- X input_func = yn_key;
- X
- X num_args = 0;
- X XtSetArg(args[num_args], XtNlabel, buf); num_args++;
- X XtSetValues(yn_label, args, num_args);
- X
- X if(!appResources.slow) {
- X /*
- X * Due to some kind of weird bug in the X11R4 and X11R5 shell, we
- X * need to set the label twice to get the size to change.
- X */
- X num_args = 0;
- X XtSetArg(args[num_args], XtNlabel, buf); num_args++;
- X XtSetValues(yn_label, args, num_args);
- X
- X positionpopup(yn_popup);
- X nh_XtPopup(yn_popup, XtGrabExclusive, yn_label);
- X }
- X
- X yn_getting_num = FALSE;
- X (void) x_event(EXIT_ON_EXIT);
- X
- X if(appResources.slow) {
- X input_func = 0;
- X num_args = 0;
- X XtSetArg(args[num_args], XtNlabel, " "); num_args++;
- X XtSetValues(yn_label, args, num_args);
- X } else {
- X nh_XtPopdown(yn_popup); /* this removes the event grab */
- X }
- X
- X return yn_return;
- X}
- X
- X/* End global functions ==================================================== */
- X
- X/*
- X * Before we wait for input via nhgetch() and nh_poskey(), we need to
- X * do some pre-processing.
- X */
- Xstatic int
- Xinput_event(exit_condition)
- X int exit_condition;
- X{
- X if (WIN_STATUS != WIN_ERR) /* hilighting on the fancy status window */
- X check_turn_events();
- X if (WIN_MAP != WIN_ERR) /* make sure cursor is not clipped */
- X check_cursor_visibility(&window_list[WIN_MAP]);
- X if (WIN_MESSAGE != WIN_ERR) /* reset pause line */
- X set_last_pause(&window_list[WIN_MESSAGE]);
- X
- X return x_event(exit_condition);
- X}
- X
- X
- X/*ARGSUSED*/
- Xvoid
- Xmsgkey(w, data, event)
- X Widget w;
- X XtPointer data;
- X XEvent *event;
- X{
- X extern_map_input(event);
- X}
- X
- X/*
- X * Set up the playing console. This has three major parts: the
- X * message window, the map, and the status window.
- X */
- Xstatic void
- Xinit_standard_windows()
- X{
- X Widget form, message_viewport, map_viewport, status;
- X Arg args[8];
- X Cardinal num_args;
- X Dimension message_vp_width, map_vp_width, status_width, max_width;
- X int map_vp_hd, status_hd;
- X struct xwindow *wp;
- X
- X
- X num_args = 0;
- X XtSetArg(args[num_args], XtNallowShellResize, True); num_args++;
- X form = XtCreateManagedWidget("nethack",
- X formWidgetClass,
- X toplevel, args, num_args);
- X
- X XtAddEventHandler(form, KeyPressMask, False,
- X (XtEventHandler) msgkey, (XtPointer) 0);
- X
- X /*
- X * Create message window.
- X */
- X WIN_MESSAGE = message_win = find_free_window();
- X wp = &window_list[message_win];
- X wp->cursx = wp->cursy = wp->pixel_width = wp->pixel_height = 0;
- X wp->popup = (Widget) 0;
- X create_message_window(wp, FALSE, form);
- X message_viewport = XtParent(wp->w);
- X
- X
- X /* Tell the form that contains it that resizes are OK. */
- X num_args = 0;
- X XtSetArg(args[num_args], XtNresizable, True); num_args++;
- X XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
- X XtSetArg(args[num_args], XtNtop, XtChainTop); num_args++;
- X XtSetValues(message_viewport, args, num_args);
- X
- X if(appResources.slow) {
- X num_args = 0;
- X XtSetArg(args[num_args], XtNtranslations,
- X XtParseTranslationTable(yn_translations)); num_args++;
- X yn_label = XtCreateManagedWidget("yn_label",
- X labelWidgetClass,
- X form,
- X args, num_args);
- X num_args = 0;
- X XtSetArg(args[num_args], XtNfromVert, message_viewport); num_args++;
- X XtSetArg(args[num_args], XtNresizable, True); num_args++;
- X XtSetArg(args[num_args], XtNlabel, " "); num_args++;
- X XtSetValues(yn_label, args, num_args);
- X }
- X
- X /*
- X * Create the map window & viewport and chain the viewport beneath the
- X * message_viewport.
- X */
- X map_win = find_free_window();
- X wp = &window_list[map_win];
- X wp->cursx = wp->cursy = wp->pixel_width = wp->pixel_height = 0;
- X wp->popup = (Widget) 0;
- X create_map_window(wp, FALSE, form);
- X map_viewport = XtParent(wp->w);
- X
- X /* Chain beneath message_viewport or yn window. */
- X num_args = 0;
- X if(appResources.slow) {
- X XtSetArg(args[num_args], XtNfromVert, yn_label); num_args++;
- X } else {
- X XtSetArg(args[num_args], XtNfromVert, message_viewport);num_args++;
- X }
- X XtSetArg(args[num_args], XtNbottom, XtChainBottom); num_args++;
- X XtSetValues(map_viewport, args, num_args);
- X
- X /* Create the status window, with the form as it's parent. */
- X status_win = find_free_window();
- X wp = &window_list[status_win];
- X wp->cursx = wp->cursy = wp->pixel_width = wp->pixel_height = 0;
- X wp->popup = (Widget) 0;
- X create_status_window(wp, FALSE, form);
- X status = wp->w;
- X
- X /*
- X * Chain the status window beneath the viewport. Mark the left and right
- X * edges so that they stay a fixed distance from the left edge of the
- X * parent, as well as the top and bottom edges so that they stay a fixed
- X * distance from the bottom of the parent. We do this so that the status
- X * will never expand or contract.
- X */
- X num_args = 0;
- X XtSetArg(args[num_args], XtNfromVert, map_viewport); num_args++;
- X XtSetArg(args[num_args], XtNleft, XtChainLeft); num_args++;
- X XtSetArg(args[num_args], XtNright, XtChainLeft); num_args++;
- X XtSetArg(args[num_args], XtNtop, XtChainBottom); num_args++;
- X XtSetArg(args[num_args], XtNbottom, XtChainBottom); num_args++;
- X XtSetValues(status, args, num_args);
- X
- X
- X /*
- X * Realize the popup so that the status widget knows it's size.
- X *
- X * If we unset MappedWhenManaged then the DECwindow driver doesn't
- X * attach the nethack toplevel to the highest virtual root window.
- X * So don't do it.
- X */
- X /* XtSetMappedWhenManaged(toplevel, False); */
- X XtRealizeWidget(toplevel);
- X /*
- X * The message window was the size we want the viewport to take (when
- X * realized). Now change to our real height. Do this before we resize
- X * so that the vertical scrollbar is activated and is taken into account
- X * when calculating the widget size. If we do this last, then the
- X * message window ends up being short by one scrollbar width. [Brain-dead
- X * viewport widget.]
- X */
- X set_message_height(&window_list[message_win], (int) flags.msg_history);
- X
- X /*
- X * Now get the default widths of the windows.
- X */
- X XtSetArg(args[0], XtNwidth, &message_vp_width);
- X XtGetValues(message_viewport, args, ONE);
- X XtSetArg(args[0], XtNwidth, &map_vp_width);
- X XtSetArg(args[1], XtNhorizDistance, &map_vp_hd);
- X XtGetValues(map_viewport, args, TWO);
- X XtSetArg(args[0], XtNwidth, &status_width);
- X XtSetArg(args[1], XtNhorizDistance, &status_hd);
- X XtGetValues(status, args, TWO);
- X
- X /*
- X * Adjust positions and sizes. The message viewport widens out to the
- X * widest width. Both the map and status are centered by adjusting
- X * their horizDistance.
- X */
- X if (map_vp_width < status_width || map_vp_width < message_vp_width) {
- X if (status_width > message_vp_width) {
- X XtSetArg(args[0], XtNwidth, status_width);
- X XtSetValues(message_viewport, args, ONE);
- X max_width = status_width;
- X } else {
- X/***** The status display looks better when left justified.
- X XtSetArg(args[0], XtNhorizDistance,
- X status_hd+((message_vp_width-status_width)/2));
- X XtSetValues(status, args, ONE);
- X*****/
- X max_width = message_vp_width;
- X }
- X XtSetArg(args[0], XtNhorizDistance, map_vp_hd+((int)(max_width-map_vp_width)/2));
- X XtSetValues(map_viewport, args, ONE);
- X
- X } else { /* map is widest */
- X XtSetArg(args[0], XtNwidth, map_vp_width);
- X XtSetValues(message_viewport, args, ONE);
- X
- X/***** The status display looks better when left justified.
- X XtSetArg(args[0], XtNhorizDistance,
- X status_hd+((map_vp_width-status_width)/2));
- X
- X XtSetValues(status, args, ONE);
- X*****/
- X }
- X /*
- X * Clear all data values on the fancy status widget so that the values
- X * used for spacing don't appear. This needs to be called some time
- X * after the fancy status widget is realized (above, with the game popup),
- X * but before it is popped up.
- X */
- X null_out_status();
- X /*
- X * Set the map size to its standard size. As with the message window
- X * above, the map window needs to be set to its constrained size until
- X * its parent (the viewport widget) was realized.
- X *
- X * Move the message window's slider to the bottom.
- X */
- X set_map_size(&window_list[map_win], COLNO, ROWNO);
- X set_message_slider(&window_list[message_win]);
- X
- X /* grab initial input focus */
- X if (appResources.autofocus) {
- X Display *dpy = XtDisplay(toplevel);
- X Window win = XtWindow(toplevel), current;
- X int revert;
- X
- X /*
- X * We don't actually care about the `revert' value; this mainly serves
- X * the purpose of synchronizing with the popup.
- X */
- X XGetInputFocus(dpy, ¤t, &revert);
- X
- X /* attach the keyboard to the main window */
- X if (win != current) {
- X sleep(1); /* ugh, delay so window is showing.. */
- X XSetInputFocus(dpy, win, revert, CurrentTime);
- X }
- X }
- X
- X /* attempt to catch fatal X11 errors before the program quits */
- X (void) XtAppSetErrorHandler(app_context, (XtErrorHandler) hangup);
- X
- X /* We can now print to the message window. */
- X flags.window_inited = 1;
- X}
- X
- X
- Xvoid
- Xnh_XtPopup(w, g, childwid)
- X Widget w; /* widget */
- X int g; /* type of grab */
- X Widget childwid; /* child to recieve focus (can be None) */
- X{
- X XtPopup(w, (XtGrabKind)g);
- X if (appResources.autofocus) XtSetKeyboardFocus(toplevel, childwid);
- X}
- X
- Xvoid
- Xnh_XtPopdown(w)
- X Widget w;
- X{
- X XtPopdown(w);
- X if (appResources.autofocus) XtSetKeyboardFocus(toplevel, None);
- X}
- X
- Xvoid
- Xwin_X11_init()
- X{
- X#ifdef OPENWINBUG
- X /* With the OpenWindows 3.0 libraries and the SunOS 4.1.2 ld, these
- X * two routines will not be found when linking. An apparently correct
- X * executable is produced, along with nasty messages and a failure code
- X * returned to make. The routines are in the static libXmu.a and
- X * libXmu.sa.4.0, but not in libXmu.so.4.0. Rather than fiddle with
- X * static linking, we do this.
- X */
- X if (rn2(2) > 2) {
- X /* i.e., FALSE that an optimizer probably can't find */
- X get_wmShellWidgetClass();
- X get_applicationShellWidgetClass();
- X }
- X#endif
- X return;
- X}
- X
- X/*winX.c*/
- END_OF_FILE
- if test 45228 -ne `wc -c <'win/X11/winX.c'`; then
- echo shar: \"'win/X11/winX.c'\" unpacked with wrong size!
- fi
- # end of 'win/X11/winX.c'
- fi
- echo shar: End of archive 16 \(of 108\).
- cp /dev/null ark16isdone
- MISSING=""
- for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
- 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
- 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
- 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
- 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
- 101 102 103 104 105 106 107 108 ; do
- if test ! -f ark${I}isdone ; then
- MISSING="${MISSING} ${I}"
- fi
- done
- if test "${MISSING}" = "" ; then
- echo You have unpacked all 108 archives.
- echo "Now execute 'rebuild.sh'"
- rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
- else
- echo You still need to unpack the following archives:
- echo " " ${MISSING}
- fi
- ## End of shell archive.
- exit 0
-