home *** CD-ROM | disk | FTP | other *** search
/ NetNews Usenet Archive 1993 #3 / NN_1993_3.iso / spool / comp / sources / games / 324 < prev    next >
Encoding:
Internet Message Format  |  1993-01-28  |  57.0 KB

  1. Path: sparky!uunet!news.tek.com!master!saab!billr
  2. From: billr@saab.CNA.TEK.COM (Bill Randle)
  3. Newsgroups: comp.sources.games
  4. Subject: v16i016:  nethack31 - display oriented dungeons & dragons (Ver. 3.1), Part16/108
  5. Message-ID: <4299@master.CNA.TEK.COM>
  6. Date: 28 Jan 93 19:13:58 GMT
  7. Sender: news@master.CNA.TEK.COM
  8. Lines: 1874
  9. Approved: billr@saab.CNA.TEK.COM
  10.  
  11. Submitted-by: izchak@linc.cis.upenn.edu (Izchak Miller)
  12. Posting-number: Volume 16, Issue 16
  13. Archive-name: nethack31/Part16
  14. Supersedes: nethack3p9: Volume 10, Issue 46-102
  15. Environment: Amiga, Atari, Mac, MS-DOS, OS2, Unix, VMS, X11
  16.  
  17.  
  18.  
  19. #! /bin/sh
  20. # This is a shell archive.  Remove anything before this line, then unpack
  21. # it by saving it into a file and typing "sh file".  To overwrite existing
  22. # files, type "sh file -c".  You can also feed this as standard input via
  23. # unshar, or by typing "sh <file", e.g..  If this archive is complete, you
  24. # will see the following message at the end:
  25. #        "End of archive 16 (of 108)."
  26. # Contents:  sys/atari/Install.tos win/X11/winX.c
  27. # Wrapped by billr@saab on Wed Jan 27 16:08:51 1993
  28. PATH=/bin:/usr/bin:/usr/ucb ; export PATH
  29. if test -f 'sys/atari/Install.tos' -a "${1}" != "-c" ; then 
  30.   echo shar: Will not clobber existing file \"'sys/atari/Install.tos'\"
  31. else
  32. echo shar: Extracting \"'sys/atari/Install.tos'\" \(8575 characters\)
  33. sed "s/^X//" >'sys/atari/Install.tos' <<'END_OF_FILE'
  34. X    Instructions for compiling and installing NetHack 3.1
  35. X                  on a TOS system
  36. X    =====================================================
  37. X              (or, How to make ST NetHack 3.1)
  38. X             Last revision: 23 Jan 1993
  39. X
  40. X1.  Make sure all the NetHack files are in the appropriate directory structure.
  41. X    You should have a main directory with subdirectories dat, doc, include,
  42. X    src, util, sys\atari, sys\share, and sys\unix.  You may have other sub-
  43. X    directories under sys, but they needn't concern you. If you do not follow
  44. X    this structure, the Makefiles will not function properly.  The .c files
  45. X    for the main program belong in src, those for utility programs in util,
  46. X    and Atari-specific ones in sys\atari.  All the .h files belong in include,
  47. X    the documentation in doc, and assorted data files in dat.  You may also
  48. X    use random.c from sys\share.  The Makefiles belong in sys\unix (except
  49. X    for the Atari-specific Makefile.utl found in this directory).
  50. X    (A more detailed explanation of the directory structure may be found in
  51. X    Files, which should be in the top directory.)
  52. X
  53. X2.  If you don't already have a good command line interpreter, get one.
  54. X    Doing all of the following from the desktop or a GEM shell will
  55. X    probably be a *big* pain.  If you can get a Bourne shell compatible
  56. X    one, and put it in \bin\sh, then you'll save yourself some trouble
  57. X    with the Makefiles.  There are several good shells on various
  58. X    FTP sites (including atari.archive.umich.edu).
  59. X
  60. X    Run the "setup.g" shell script in sys\atari.  This will move all the
  61. X    makefiles and other files to the appropriate directories.
  62. X
  63. X    The file termcap.uu is the fixed version of the Fred Fish termcap library.
  64. X    You will need to run a uudecode utility on it to generate the file
  65. X    termcap.arc.  termcap.arc contains several files of termcap routines.
  66. X    Using them with NetHack involves very little knowledge of the UNIX concept
  67. X    of a termcap database; mostly you need to know enough to set a TERM
  68. X    environment variable.  You can unarc termcap.arc here in the sys\share
  69. X    directory, but if you are going to use it, it is probably best to unarc a
  70. X    copy in the src directory.  That way you will not miss copying any
  71. X    files over.  Some compilers (notably the gcc) already have a termcap
  72. X    library; if so, you won't need this one.
  73. X
  74. X3.  Now go to the include subdirectory to edit a couple of the header files
  75. X    there.
  76. X
  77. X    First edit config.h according to the comments to match your system and
  78. X    desired set of features.  In particular:
  79. X       make sure that UNIX is *not* defined, and TOS is (if you're using
  80. X          the MiNT library, and/or the -mint option to gcc, this will
  81. X      be done automatically)
  82. X       make sure the HACKDIR is defined properly (or not at all)
  83. X       make sure that COMPRESS is not defined
  84. X
  85. X    If you want to build a NetHack that will run on a 1 megabyte machine,
  86. X    I'm afraid you're going to have to disable some options.  Just what
  87. X    to disable is a tough choice; NetHack *almost* fits in 1 meg, but
  88. X    almost isn't quite good enough :-(.  On the other hand, if you can
  89. X    compile NetHack, you almost certainly have at least 2 megabytes;
  90. X    certainly gcc won't compile NetHack with less than 4.
  91. X
  92. X    Also edit tosconf.h; this shouldn't need much changing. If you are not
  93. X    going to include random.c you will need to comment out RANDOM. Gcc users
  94. X    don't need RANDOM, since the gcc and MiNT libraries have a Berkeley
  95. X    derived srandom() function already. If you have no termcap support and
  96. X    don't want to use the supplied termcap.uu, comment out TERMLIB. Gcc has
  97. X    a termcap library, so TERMLIB should always be "on" with gcc (and you
  98. X    don't need to worry about termcap.uu at all).
  99. X
  100. X4.  If you're using a compiler other than the gcc, you may want to look
  101. X    through system.h, in the include directory.  This file matches the return
  102. X    and parameter types for system calls and library routines with various
  103. X    flavors of compilers and operating systems.  Leaving this file alone is
  104. X    unlikely to cause problems, but if you get compile errors with any
  105. X    functions in the standard library, it's worth checking the declarations
  106. X    there.
  107. X
  108. X5.  If you want to change the high score list behavior, examine the top of
  109. X    topten.c, in the src directory.  You may want to change the definitions of
  110. X    PERSMAX, POINTSMIN, and ENTRYMAX.  I set POINTSMIN to 51 and ENTRYMAX to
  111. X    50 to keep the size of the score list down.
  112. X
  113. X6.  Go to the src directory and edit your Makefile.  You'll want the Systos
  114. X    target configuration; the comments explain most of what needs to be done,
  115. X    at least for the gcc.  If your compiler doesn't like directories separated
  116. X    by /'s, then change these to \'s.
  117. X
  118. X    Next, go to the top, util, dat, and doc directories, and edit the Makefiles
  119. X    there, as necessary.  You'll need nroff and/or TeX to do the files in doc;
  120. X    if you don't have one/both of these, you can skip it (docs?? we don't need
  121. X    no steenking docs :-)).
  122. X
  123. X    If you elected to use Fred Fish's termcap library (bundled in as
  124. X    termcap.arc), you will have to generate termcap.a from those sources.
  125. X
  126. X    If you are recompiling after patching your sources, or if you got your
  127. X    files from somewhere other than the official distribution, "touch
  128. X    makedefs.c" to ensure that certain files (onames.h and pm.h) are remade,
  129. X    lest potentially troublesome timestamps fool "make."
  130. X
  131. X8.  Now, enter "make all", and take a long siesta; your computer will be
  132. X    occupied for a long time.  If all goes well, you will get an executable.
  133. X    If you tried to compile in too many features, you will probably get a
  134. X    dysfunctional executable, and will have to start over.
  135. X
  136. X    Hint 1:  If you're short on memory, you might enter "make -n all
  137. X    >make.bat," and then run script.bat with some sort of batch
  138. X        program or with the gulam command "script make.bat."
  139. X
  140. X    Hint 2: You'll save yourself a lot of grief if you use the GNU
  141. X    version of the "make" program. Some of the smaller makes aren't
  142. X    completely compatible. GNU software for the Atari is widely
  143. X    available; for example, by anonymous FTP from atari.archive.umich.edu.
  144. X
  145. X9.  Make sure the support files-- data, rumors, cmdhelp, opthelp, help, hh,
  146. X    history, license, and oracles (if ORACLES was #define'd)-- were copied
  147. X    to the game directory.  If not, move them there from the auxil directory
  148. X    yourself.  rumors can be created manually by entering "makedefs -r;"
  149. X    data by entering "makedefs -d."
  150. X
  151. X    Also, make sure that the various level files (*.lev, from the dat
  152. X    subdirectory) were copied over correctly. If you're not sure what files
  153. X    should have been made, double check with Makefile.dat.
  154. X
  155. X10. Go to the src\atari directory.  Copy atari.cnf to your game directory
  156. X    as NetHack.cnf. Edit it to reflect your particular setup and personal
  157. X    preferences, following the comments.
  158. X
  159. X    If you compiled in the TERMLIB feature, also move the "termcap" file to
  160. X    your game directory.  (Note:  gcc's termcap routines have built-in
  161. X    defaults, so the termcap file is not necessary with that compiler.)
  162. X
  163. X    To use funky graphics characters in TOS, uudecode "atarifnt.uue" and unarc
  164. X    the resulting "atarifnt.arc".  This contains a program to run that makes
  165. X    some line graphics characters available to NetHack.  To use them, uncomment
  166. X    the appropriate line in your NetHack.cnf file, and run the program before
  167. X    running NetHack (you can put the program in an AUTO folder if you want).
  168. X    This font won't work if you're running Speedo GDOS (and possibly other
  169. X    GDOS variants). I hope to have a bitmapped GDOS font suitable for
  170. X    NetHack 3.1 "Real Soon Now."
  171. X
  172. X    If you're running NetHack from the MultiTOS desktop, and you want a
  173. X    more useful set of drop down menus than the plain system "File/Edit"
  174. X    ones, copy nethack.mnu to your games directory. This file contains a
  175. X    menu definition that puts a lot of the common commands into the menu.
  176. X
  177. X11. Play NetHack.  If it works, you're done!
  178. X
  179. X
  180. XNotes
  181. X-----
  182. X
  183. X1)  Save files and bones files from previous versions will not work with
  184. X    NetHack 3.1.  Don't bother trying to keep them.  
  185. X
  186. X2)  To install an update of NetHack after changing something, enter "make"
  187. X    from the src directory.  If you add, delete, or reorder monsters or
  188. X    objects, or you change the format of saved level files, delete any save
  189. X    and bones files.  (Trying to use such files sometimes produces amusing
  190. X    confusions on the game's part, but more often produces crashes.)
  191. X
  192. END_OF_FILE
  193. if test 8575 -ne `wc -c <'sys/atari/Install.tos'`; then
  194.     echo shar: \"'sys/atari/Install.tos'\" unpacked with wrong size!
  195. fi
  196. # end of 'sys/atari/Install.tos'
  197. fi
  198. if test -f 'win/X11/winX.c' -a "${1}" != "-c" ; then 
  199.   echo shar: Will not clobber existing file \"'win/X11/winX.c'\"
  200. else
  201. echo shar: Extracting \"'win/X11/winX.c'\" \(45228 characters\)
  202. sed "s/^X//" >'win/X11/winX.c' <<'END_OF_FILE'
  203. X/*    SCCS Id: @(#)winX.c    3.1    93/01/22          */
  204. X/* Copyright (c) Dean Luick, 1992                  */
  205. X/* NetHack may be freely redistributed.  See license for details. */
  206. X
  207. X/*
  208. X * "Main" file for the X window-port.  This contains most of the interface
  209. X * routines.  Please see doc/window.doc for an description of the window
  210. X * interface.
  211. X */
  212. X#include <X11/Intrinsic.h>
  213. X#include <X11/StringDefs.h>
  214. X#include <X11/Shell.h>
  215. X#include <X11/Xaw/AsciiText.h>
  216. X#include <X11/Xaw/Label.h>
  217. X#include <X11/Xaw/Form.h>
  218. X#include <X11/Xaw/Cardinals.h>
  219. X#include <X11/Xatom.h>
  220. X#include <X11/Xos.h>
  221. X/* for color support; should be ifdef TEXTCOLOR, but must come before hack.h */
  222. X#include <X11/IntrinsicP.h>
  223. X
  224. X#include "hack.h"
  225. X#include "winX.h"
  226. X
  227. X/* Should be defined in <X11/Intrinsic.h> but you never know */
  228. X#ifndef XtSpecificationRelease
  229. X#define XtSpecificationRelease 0
  230. X#endif
  231. X
  232. X/*
  233. X * Icons.
  234. X */
  235. X#include "../win/X11/nh72icon"
  236. X#include "../win/X11/nh56icon"
  237. X#include "../win/X11/nh32icon"
  238. X
  239. Xstatic struct icon_info {
  240. X    const char *name;
  241. X    char *bits;
  242. X    unsigned width, height;
  243. X} icon_data[] = {
  244. X    { "nh72", nh72icon_bits, nh72icon_width, nh72icon_height },
  245. X    { "nh56", nh56icon_bits, nh56icon_width, nh56icon_height },
  246. X    { "nh32", nh32icon_bits, nh32icon_width, nh32icon_height },
  247. X    { NULL, NULL, 0, 0 }
  248. X};
  249. X
  250. X/*
  251. X * Private global variables (shared among the window port files).
  252. X */
  253. Xstruct xwindow window_list[MAX_WINDOWS];
  254. XAppResources appResources;
  255. Xvoid (*input_func)();
  256. Xint click_x, click_y, click_button;    /* Click position on a map window   */
  257. X                    /* (filled by set_button_values()). */
  258. X
  259. X
  260. X/* Interface definition, for windows.c */
  261. Xstruct window_procs X11_procs = {
  262. X    "X11",
  263. X    X11_init_nhwindows,
  264. X    X11_player_selection,
  265. X    X11_askname,
  266. X    X11_get_nh_event,
  267. X    X11_exit_nhwindows,
  268. X    X11_suspend_nhwindows,
  269. X    X11_resume_nhwindows,
  270. X    X11_create_nhwindow,
  271. X    X11_clear_nhwindow,
  272. X    X11_display_nhwindow,
  273. X    X11_destroy_nhwindow,
  274. X    X11_curs,
  275. X    X11_putstr,
  276. X    X11_display_file,
  277. X    X11_start_menu,
  278. X    X11_add_menu,
  279. X    X11_end_menu,
  280. X    X11_select_menu,
  281. X    X11_update_inventory,
  282. X    X11_mark_synch,
  283. X    X11_wait_synch,
  284. X#ifdef CLIPPING
  285. X    X11_cliparound,
  286. X#endif
  287. X    X11_print_glyph,
  288. X    X11_raw_print,
  289. X    X11_raw_print_bold,
  290. X    X11_nhgetch,
  291. X    X11_nh_poskey,
  292. X    X11_nhbell,
  293. X    X11_doprev_message,
  294. X    X11_yn_function,
  295. X    X11_getlin,
  296. X#ifdef COM_COMPL
  297. X    X11_get_ext_cmd,
  298. X#endif /* COM_COMPL */
  299. X    X11_number_pad,
  300. X    X11_delay_output,
  301. X    /* other defs that really should go away (they're tty specific) */
  302. X    X11_start_screen,
  303. X    X11_end_screen,
  304. X};
  305. X
  306. X/*
  307. X * Local functions.
  308. X */
  309. Xstatic void FDECL(dismiss_file, (Widget, XEvent*, String*, Cardinal*));
  310. Xstatic void FDECL(yn_key, (Widget, XEvent*, String*, Cardinal*));
  311. Xstatic int FDECL(input_event, (int));
  312. Xstatic void NDECL(init_standard_windows);
  313. X
  314. X
  315. X/*
  316. X * Local variables.
  317. X */
  318. Xstatic boolean x_inited = FALSE;    /* TRUE if window system is set up. */
  319. Xstatic winid message_win = WIN_ERR,    /* These are the winids of the        */
  320. X         map_win     = WIN_ERR,    /*   message, map, and status        */
  321. X         status_win  = WIN_ERR;    /*   windows, when they are created */
  322. X                    /*   in init_windows().            */
  323. Xstatic Pixmap icon_pixmap = None;    /* Pixmap for icon.            */
  324. X
  325. X/*
  326. X * Find the window structure that corresponds to the given widget.  Note
  327. X * that this is not the popup widget, nor the viewport, but the child.
  328. X */
  329. Xstruct xwindow *
  330. Xfind_widget(w)
  331. X    Widget w;
  332. X{
  333. X    int windex;
  334. X    struct xwindow *wp;
  335. X
  336. X    /* This is sad.  Search to find the corresponding window. */
  337. X    for (windex = 0, wp = window_list; windex < MAX_WINDOWS; windex++, wp++)
  338. X    if (wp->type != NHW_NONE && wp->w == w) break;
  339. X    if (windex == MAX_WINDOWS) panic("find_widget:  can't match widget");
  340. X    return wp;
  341. X}
  342. X
  343. X/*
  344. X * Find a free window slot for use.
  345. X */
  346. Xstatic winid
  347. Xfind_free_window()
  348. X{
  349. X    int windex;
  350. X    struct xwindow *wp;
  351. X
  352. X    for (windex = 0, wp = &window_list[0]; windex < MAX_WINDOWS; windex++, wp++)
  353. X    if (wp->type == NHW_NONE) break;
  354. X
  355. X    if (windex == MAX_WINDOWS)
  356. X    panic("find_free_window: no free windows!");
  357. X    return (winid) windex;
  358. X}
  359. X
  360. X#ifdef TEXTCOLOR
  361. X/*
  362. X * Color conversion.  The default X11 color converters don't try very
  363. X * hard to find matching colors in PseudoColor visuals.  If they can't
  364. X * allocate the exact color, they puke and give you something stupid.
  365. X * This is an attempt to find some close readonly cell and use it.
  366. X */
  367. XXtConvertArgRec const nhcolorConvertArgs[] = {
  368. X    {XtWidgetBaseOffset, (XtPointer)XtOffset(Widget, core.screen),
  369. X     sizeof(Screen *)},
  370. X    {XtWidgetBaseOffset, (XtPointer)XtOffset(Widget, core.colormap),
  371. X     sizeof(Colormap)}
  372. X};
  373. X
  374. X#define done(type, value) \
  375. X    {                            \
  376. X        if (toVal->addr != NULL) {                \
  377. X        if (toVal->size < sizeof(type)) {        \
  378. X            toVal->size = sizeof(type);            \
  379. X            return False;                \
  380. X        }                        \
  381. X        *(type*)(toVal->addr) = (value);        \
  382. X        }                            \
  383. X        else {                        \
  384. X        static type static_val;                \
  385. X        static_val = (value);                \
  386. X        toVal->addr = (genericptr_t)&static_val;    \
  387. X        }                            \
  388. X        toVal->size = sizeof(type);                \
  389. X        return True;                    \
  390. X    }
  391. X
  392. X/* decl.h declares these, but it screws up structure references -dlc */
  393. X#undef red
  394. X#undef green
  395. X#undef blue
  396. X
  397. X/* Return True if something close was found. */
  398. XBoolean
  399. XnhCloseColor(screen, colormap, str, color)
  400. XScreen     *screen;    /* screen to use */
  401. XColormap colormap;    /* the colormap to use */
  402. Xchar     *str;        /* color name */
  403. XXColor   *color;    /* the X color structure; changed only if successful */
  404. X{
  405. X    int        ncells;
  406. X    long    cdiff = 16777216; /* 2^24; hopefully our map is smaller */
  407. X    XColor    tmp;
  408. X    static    XColor *table = 0;
  409. X    register    i, j;
  410. X    register long tdiff;
  411. X
  412. X    /* if the screen doesn't have a big colormap, don't waste our time */
  413. X    /* or if it's huge, and _some_ match should have been possible */
  414. X    if((ncells = CellsOfScreen(screen)) < 256 || ncells > 4096)
  415. X    return False;
  416. X
  417. X    if (!XParseColor(DisplayOfScreen(screen), colormap, str, &tmp))
  418. X    return False;
  419. X
  420. X    if (!table) {
  421. X    table = (XColor *) XtCalloc(ncells, sizeof(XColor));
  422. X    for(i=0; i<ncells; i++)
  423. X        table[i].pixel = i;
  424. X    XQueryColors(DisplayOfScreen(screen), colormap, table, ncells);
  425. X    }
  426. X
  427. X    /* go thru cells and look for the one with smallest diff */
  428. X    /* diff is calculated abs(reddiff)+abs(greendiff)+abs(bluediff) */
  429. X    /* a more knowledgeable color person might improve this -dlc */
  430. X    for(i=0; i<ncells; i++) {
  431. X    if(table[i].flags == tmp.flags) {
  432. X        j = (int)table[i].red - (int)tmp.red;
  433. X        if(j < 0) j = -j;
  434. X        tdiff = j;
  435. X        j = (int)table[i].green - (int)tmp.green;
  436. X        if(j < 0) j = -j;
  437. X        tdiff += j;
  438. X        j = (int)table[i].blue - (int)tmp.blue;
  439. X        if(j < 0) j = -j;
  440. X        tdiff += j;
  441. X        if(tdiff < cdiff) {
  442. X        cdiff = tdiff;
  443. X        tmp.pixel = i; /* table[i].pixel == i */
  444. X        }
  445. X    }
  446. X    }
  447. X
  448. X    if(cdiff == 16777216) return False;    /* nothing found?! */
  449. X
  450. X    /*
  451. X     * Found something.  Return it and mark this color as used to avoid
  452. X     * reuse.  Reuse causes major contrast problems :-)
  453. X     */
  454. X    color->pixel = tmp.pixel;
  455. X    table[tmp.pixel].flags = 0;
  456. X    return True;
  457. X}
  458. X
  459. XBoolean
  460. XnhCvtStringToPixel(dpy, args, num_args, fromVal, toVal, closure_ret)
  461. XDisplay*    dpy;
  462. XXrmValuePtr    args;
  463. XCardinal    *num_args;
  464. XXrmValuePtr    fromVal;
  465. XXrmValuePtr    toVal;
  466. XXtPointer    *closure_ret;
  467. X{
  468. X    String        str = (String)fromVal->addr;
  469. X    XColor        screenColor;
  470. X    XColor        exactColor;
  471. X    Screen        *screen;
  472. X    XtAppContext    app = XtDisplayToApplicationContext(dpy);
  473. X    Colormap        colormap;
  474. X    Status        status;
  475. X    String          params[1];
  476. X    Cardinal        num_params=1;
  477. X
  478. X    if (*num_args != 2) {
  479. X     XtAppWarningMsg(app, "wrongParameters", "cvtStringToPixel",
  480. X    "XtToolkitError",
  481. X    "String to pixel conversion needs screen and colormap arguments",
  482. X        (String *)NULL, (Cardinal *)NULL);
  483. X     return False;
  484. X    }
  485. X
  486. X    screen = *((Screen **) args[0].addr);
  487. X    colormap = *((Colormap *) args[1].addr);
  488. X
  489. X    /* If Xt colors, use the Xt routine and hope for the best */
  490. X#if (XtSpecificationRelease >= 5)
  491. X    if ((strcmpi(str, XtDefaultBackground) == 0) ||
  492. X    (strcmpi(str, XtDefaultForeground) == 0)) {
  493. X    return
  494. X      XtCvtStringToPixel(dpy, args, num_args, fromVal, toVal, closure_ret);
  495. X    }
  496. X#else
  497. X    if (strcmpi(str, XtDefaultBackground) == 0) {
  498. X    *closure_ret = (char*)False;
  499. X    done(Pixel, WhitePixelOfScreen(screen));
  500. X    }
  501. X    if (strcmpi(str, XtDefaultForeground) == 0) {
  502. X    *closure_ret = (char*)False;
  503. X    done(Pixel, BlackPixelOfScreen(screen));
  504. X    }
  505. X#endif
  506. X
  507. X    status = XAllocNamedColor(DisplayOfScreen(screen), colormap,
  508. X                  (char*)str, &screenColor, &exactColor);
  509. X    if (status == 0) {
  510. X    String msg, type;
  511. X    params[0] = str;
  512. X    /* Server returns a specific error code but Xlib discards it.  Ugh */
  513. X    if (XLookupColor(DisplayOfScreen(screen), colormap, (char*)str,
  514. X             &exactColor, &screenColor)) {
  515. X        /* try to find another color that will do */
  516. X        if (nhCloseColor(screen, colormap, (char*) str, &screenColor)) {
  517. X        *closure_ret = (char*)True;
  518. X        done(Pixel, screenColor.pixel);
  519. X        }
  520. X        type = "noColormap";
  521. X        msg = "Cannot allocate colormap entry for \"%s\"";
  522. X    }
  523. X    else {
  524. X        type = "badValue";
  525. X        msg = "Color name \"%s\" is not defined";
  526. X    }
  527. X
  528. X    XtAppWarningMsg(app, type, "cvtStringToPixel",
  529. X            "XtToolkitError", msg, params, &num_params);
  530. X    *closure_ret = False;
  531. X    return False;
  532. X    } else {
  533. X    *closure_ret = (char*)True;
  534. X        done(Pixel, screenColor.pixel);
  535. X    }
  536. X}
  537. X
  538. X/* ARGSUSED */
  539. Xstatic void
  540. XnhFreePixel(app, toVal, closure, args, num_args)
  541. XXtAppContext    app;
  542. XXrmValuePtr    toVal;
  543. XXtPointer    closure;
  544. XXrmValuePtr    args;
  545. XCardinal    *num_args;
  546. X{
  547. X    Screen        *screen;
  548. X    Colormap        colormap;
  549. X
  550. X    if (*num_args != 2) {
  551. X     XtAppWarningMsg(app, "wrongParameters",
  552. X             "freePixel", "XtToolkitError",
  553. X             "Freeing a pixel requires screen and colormap arguments",
  554. X             (String *)NULL, (Cardinal *)NULL);
  555. X     return;
  556. X    }
  557. X
  558. X    screen = *((Screen **) args[0].addr);
  559. X    colormap = *((Colormap *) args[1].addr);
  560. X
  561. X    if (closure) {
  562. X    XFreeColors( DisplayOfScreen(screen), colormap,
  563. X             (unsigned long*)toVal->addr, 1, (unsigned long)0
  564. X            );
  565. X    }
  566. X}
  567. X#endif /* TEXTCOLOR */
  568. X
  569. X/* Global Functions ======================================================== */
  570. Xvoid
  571. XX11_raw_print(str)
  572. X    const char *str;
  573. X{
  574. X    (void) puts(str);
  575. X}
  576. X
  577. Xvoid
  578. XX11_raw_print_bold(str)
  579. X    const char *str;
  580. X{
  581. X    (void) puts(str);
  582. X}
  583. X
  584. Xvoid
  585. XX11_curs(window, x, y)
  586. X    winid window;
  587. X    int x, y;
  588. X{
  589. X    check_winid(window);
  590. X
  591. X    if (x < 0 || x >= COLNO) {
  592. X    impossible("curs:  bad x value [%d]", x);
  593. X    x = 0;
  594. X    }
  595. X    if (y < 0 || y >= ROWNO) {
  596. X    impossible("curs:  bad y value [%d]", y);
  597. X    y = 0;
  598. X    }
  599. X
  600. X    window_list[window].cursx = x;
  601. X    window_list[window].cursy = y;
  602. X}
  603. X
  604. Xvoid
  605. XX11_putstr(window, attr, str)
  606. X    winid window;
  607. X    int attr;
  608. X    const char *str;
  609. X{
  610. X    winid new_win;
  611. X    struct xwindow *wp;
  612. X
  613. X    check_winid(window);
  614. X    wp = &window_list[window];
  615. X
  616. X    switch (wp->type) {
  617. X    case NHW_MESSAGE:
  618. X        Strcpy(toplines, str);    /* for Norep(). */
  619. X        append_message(wp, str);
  620. X        break;
  621. X    case NHW_STATUS:
  622. X        adjust_status(wp, str);
  623. X        break;
  624. X    case NHW_MAP:
  625. X        impossible("putstr: called on map window \"%s\"", str);
  626. X        break;
  627. X    case NHW_MENU:
  628. X        if (wp->menu_information->is_menu) {
  629. X        impossible(
  630. X            "putstr:  called on a menu window, \"%s\" discarded",
  631. X            str);
  632. X        break;
  633. X        }
  634. X        /*
  635. X         * Change this menu window into a text window by creating a
  636. X         * new text window, then copying it to this winid.
  637. X         */
  638. X        new_win = X11_create_nhwindow(NHW_TEXT);
  639. X        X11_destroy_nhwindow(window);
  640. X        *wp = window_list[new_win];
  641. X        window_list[new_win].type = NHW_NONE;    /* allow re-use */
  642. X        /* fall though to add text */
  643. X    case NHW_TEXT:
  644. X        add_to_text_window(wp, attr, str);
  645. X        break;
  646. X    default:
  647. X        impossible("putstr: unknown window type [%d] \"%s\"",
  648. X                                wp->type, str);
  649. X    }
  650. X}
  651. X
  652. X/* We do event processing as a callback, so this is a null routine. */
  653. Xvoid X11_get_nh_event() { return; }
  654. X
  655. Xint
  656. XX11_nhgetch()
  657. X{
  658. X    return input_event(EXIT_ON_KEY_PRESS);
  659. X}
  660. X
  661. X
  662. Xint
  663. XX11_nh_poskey(x, y, mod)
  664. X    int *x, *y, *mod;
  665. X{
  666. X    int val = input_event(EXIT_ON_KEY_OR_BUTTON_PRESS);
  667. X
  668. X    if (val == 0) {    /* user clicked on a map window */
  669. X    *x   = click_x;
  670. X    *y   = click_y;
  671. X    *mod = click_button;
  672. X    }
  673. X    return val;
  674. X}
  675. X
  676. X
  677. Xwinid
  678. XX11_create_nhwindow(type)
  679. X    int type;
  680. X{
  681. X    winid window;
  682. X    struct xwindow *wp;
  683. X
  684. X    if (!x_inited)
  685. X    panic("create_nhwindow:  windows not initialized");
  686. X
  687. X    /*
  688. X     * We have already created the standard message, map, and status
  689. X     * windows in the window init routine.  The first window of that
  690. X     * type to be created becomes the standard.
  691. X     *
  692. X     * A better way to do this would be to say that init_nhwindows()
  693. X     * has already defined these three windows.
  694. X     */
  695. X    if (type == NHW_MAP && map_win != WIN_ERR) {
  696. X    window = map_win;
  697. X    map_win = WIN_ERR;
  698. X    return window;
  699. X    }
  700. X    if (type == NHW_MESSAGE && message_win != WIN_ERR) {
  701. X    window = message_win;
  702. X    message_win = WIN_ERR;
  703. X    return window;
  704. X    }
  705. X    if (type == NHW_STATUS && status_win != WIN_ERR) {
  706. X    window = status_win;
  707. X    status_win = WIN_ERR;
  708. X    return window;
  709. X    }
  710. X
  711. X    window = find_free_window();
  712. X    wp = &window_list[window];
  713. X
  714. X    /* The create routines will set type, popup, w, and Win_info. */
  715. X    wp->prevx = wp->prevy = wp->cursx = wp->cursy =
  716. X                wp->pixel_width = wp->pixel_height = 0;
  717. X
  718. X    switch (type) {
  719. X    case NHW_MAP:
  720. X        create_map_window(wp, TRUE, (Widget) 0);
  721. X        break;
  722. X    case NHW_MESSAGE:
  723. X        create_message_window(wp, TRUE, (Widget) 0);
  724. X        break;
  725. X    case NHW_STATUS:
  726. X        create_status_window(wp, TRUE, (Widget) 0);
  727. X        break;
  728. X    case NHW_MENU:
  729. X        create_menu_window(wp);
  730. X        break;
  731. X    case NHW_TEXT:
  732. X        create_text_window(wp);
  733. X        break;
  734. X    default:
  735. X        panic("create_nhwindow: unknown type [%d]\n", type);
  736. X        break;
  737. X    }
  738. X    return window;
  739. X}
  740. X
  741. Xvoid
  742. XX11_clear_nhwindow(window)
  743. X    winid window;
  744. X{
  745. X    struct xwindow *wp;
  746. X
  747. X    check_winid(window);
  748. X    wp = &window_list[window];
  749. X
  750. X    switch (wp->type) {
  751. X    case NHW_MAP:
  752. X        clear_map_window(wp);
  753. X        break;
  754. X    case NHW_STATUS:
  755. X    case NHW_TEXT:
  756. X    case NHW_MENU:
  757. X    case NHW_MESSAGE:
  758. X        /* do nothing for these window types */
  759. X        break;
  760. X    default:
  761. X        panic("clear_nhwindow: unknown window type [%d]\n", wp->type);
  762. X        break;
  763. X    }
  764. X}
  765. X
  766. Xvoid
  767. XX11_display_nhwindow(window, blocking)
  768. X    winid window;
  769. X    boolean blocking;
  770. X{
  771. X    struct xwindow *wp;
  772. X    check_winid(window);
  773. X
  774. X    wp = &window_list[window];
  775. X
  776. X    switch (wp->type) {
  777. X    case NHW_MAP:
  778. X        if (wp->popup)
  779. X        nh_XtPopup(wp->popup, XtGrabNone, wp->w);
  780. X        /*else
  781. X         *  XtMapWidget(toplevel);
  782. X         *
  783. X         * We don't need to do the above because we never have
  784. X         * MappedWhenManaged unset because the DEC server doesn't
  785. X         * like it.  See comment above XtSetMappedWhenManaged() in
  786. X         * init_standard_windows().
  787. X         */
  788. X        display_map_window(wp);    /* flush map */
  789. X
  790. X        /*
  791. X         * We need to flush the message window here due to the way the tty
  792. X         * port is set up.  To flush a window, you need to call this
  793. X         * routine.  However, the tty port _pauses_ with a --more-- if we
  794. X         * do a display_nhwindow(WIN_MESSAGE, FALSE).  Thus, we can't call
  795. X         * display_nhwindow(WIN_MESSAGE,FALSE) in parse() because then we
  796. X         * get a --more-- after every line.
  797. X         *
  798. X         * Perhaps the window document should mention that when the map
  799. X         * is flushed, everything on the three main windows should be
  800. X         * flushed.  Note: we don't need to flush the status window
  801. X         * because we don't buffer changes.
  802. X         */
  803. X        if (WIN_MESSAGE != WIN_ERR)
  804. X        display_message_window(&window_list[WIN_MESSAGE]);
  805. X        if (blocking)
  806. X        (void) x_event(EXIT_ON_KEY_OR_BUTTON_PRESS);
  807. X        break;
  808. X    case NHW_MESSAGE:
  809. X        if (wp->popup)
  810. X         nh_XtPopup(wp->popup, XtGrabNone, wp->w);
  811. X        /*else
  812. X         *    XtMapWidget(toplevel);
  813. X         *
  814. X         * See comment in NHW_MAP case.
  815. X         */
  816. X
  817. X        display_message_window(wp);    /* flush messages */
  818. X        break;
  819. X    case NHW_STATUS:
  820. X        if (wp->popup)
  821. X        nh_XtPopup(wp->popup, XtGrabNone, wp->w);
  822. X        /*else
  823. X         *    XtMapWidget(toplevel);
  824. X         *
  825. X         * See comment in NHW_MAP case.
  826. X         */
  827. X
  828. X        break;            /* no flushing necessary */
  829. X    case NHW_MENU:
  830. X        (void) X11_select_menu(window); /* pop up menu (global routine) */
  831. X        break;
  832. X    case NHW_TEXT:
  833. X        display_text_window(wp, blocking);    /* pop up text window */
  834. X        break;
  835. X    default:
  836. X        panic("display_nhwindow: unknown window type [%d]\n", wp->type);
  837. X        break;
  838. X    }
  839. X}
  840. X
  841. Xvoid
  842. XX11_destroy_nhwindow(window)
  843. X    winid window;
  844. X{
  845. X    struct xwindow *wp;
  846. X    check_winid(window);
  847. X
  848. X    /*
  849. X     * "Zap" known windows, but don't destroy them.  We need to keep the
  850. X     * toplevel widget popped up so that later windows (e.g. tombstone)
  851. X     * are visible on DECWindow systems.  This is due to the virtual
  852. X     * roots that the DECWindow wm creates.
  853. X     */
  854. X    if (window == WIN_MESSAGE) {
  855. X    WIN_MESSAGE = WIN_ERR;
  856. X    flags.window_inited = 0;
  857. X    return;
  858. X    } else if (window == WIN_MAP) {
  859. X    WIN_MAP = WIN_ERR;
  860. X    return;
  861. X    } else if (window == WIN_STATUS) {
  862. X    WIN_STATUS = WIN_ERR;
  863. X    return;
  864. X    } else if (window == WIN_INVEN) {
  865. X    WIN_INVEN = WIN_ERR;
  866. X    return;
  867. X    }
  868. X
  869. X    wp = &window_list[window];
  870. X
  871. X    switch (wp->type) {
  872. X    case NHW_MAP:
  873. X        destroy_map_window(wp);
  874. X        break;
  875. X    case NHW_MENU:
  876. X        destroy_menu_window(wp);
  877. X        break;
  878. X    case NHW_TEXT:
  879. X        destroy_text_window(wp);
  880. X        break;
  881. X    case NHW_STATUS:
  882. X        destroy_status_window(wp);
  883. X        break;
  884. X    case NHW_MESSAGE:
  885. X        destroy_message_window(wp);
  886. X        break;
  887. X    default:
  888. X        panic("destroy_nhwindow: unknown window type [%d]", wp->type);
  889. X        break;
  890. X    }
  891. X}
  892. X
  893. X/* We don't implement a continous invent screen, so this is null. */
  894. Xvoid X11_update_inventory() { return; }
  895. X
  896. X/* The current implementation has all of the saved lines on the screen. */
  897. Xint X11_doprev_message() { return 0; }
  898. X
  899. Xvoid
  900. XX11_nhbell()
  901. X{
  902. X    /* We can't use XBell until toplevel has been initialized. */
  903. X    if (x_inited)
  904. X    XBell(XtDisplay(toplevel), 0);
  905. X    /* else print ^G ?? */
  906. X}
  907. X
  908. Xvoid X11_mark_synch()
  909. X{
  910. X    if (x_inited) {
  911. X    /*
  912. X     * the window document is a bit unclear about the status of text
  913. X     * that has been pline()d but not displayed w/display_nhwindow(),
  914. X     * though the main code and tty code assume that a pline() followed
  915. X     * by mark_synch() results in the text being seen, even if
  916. X     * display_nhwindow() wasn't called.  Duplicate this behavior.
  917. X     */
  918. X    if (WIN_MESSAGE != WIN_ERR)
  919. X        display_message_window(&window_list[WIN_MESSAGE]);
  920. X    XSync(XtDisplay(toplevel), False);
  921. X    }
  922. X}
  923. X
  924. Xvoid X11_wait_synch() {if (x_inited) XFlush(XtDisplay(toplevel)); }
  925. X
  926. X
  927. X/* Both resume_ and suspend_ are called from ioctl.c and unixunix.c. */
  928. Xvoid X11_resume_nhwindows() { return; }
  929. X
  930. X/* ARGSUSED */
  931. Xvoid X11_suspend_nhwindows(str) const char *str; { return; }
  932. X
  933. X/* Under X, we don't need to initialize the number pad. */
  934. X/* ARGSUSED */
  935. Xvoid X11_number_pad(state) int state; { return; } /* called from options.c */
  936. X
  937. X
  938. Xvoid X11_start_screen() { return; } /* called from setftty() in unixtty.c */
  939. Xvoid X11_end_screen() { return; }   /* called from settty() in unixtty.c */
  940. X
  941. X
  942. X/* init and exit nhwindows ------------------------------------------------- */
  943. X
  944. XXtAppContext app_context;        /* context of application */
  945. XWidget         toplevel = (Widget) 0;    /* toplevel widget */
  946. X
  947. Xstatic XtActionsRec actions[] = {
  948. X    {"dismiss_file",    dismiss_file},    /* action for file viewing widget */
  949. X    {"dismiss_text",    dismiss_text},    /* button action for text widget */
  950. X    {"key_dismiss_text",key_dismiss_text},/* key action for text widget */
  951. X    {"menu_key",    menu_key},    /* action for menu accelerators */
  952. X    {"yn_key",        yn_key},    /* action for yn accelerators */
  953. X    {"ec_key",        ec_key},    /* action for extended commands */
  954. X    {"ps_key",        ps_key},    /* action for player selection */
  955. X};
  956. X
  957. Xstatic XtResource resources[] = {
  958. X    { "slow", "Slow", XtRBoolean, sizeof(Boolean),
  959. X      XtOffset(AppResources *,slow), XtRString, "False" },
  960. X    { "autofocus", "AutoFocus", XtRBoolean, sizeof(Boolean),
  961. X      XtOffset(AppResources *,autofocus), XtRString, "False" },
  962. X    { "message_line", "Message_line", XtRBoolean, sizeof(Boolean),
  963. X      XtOffset(AppResources *,message_line), XtRString, "False" },
  964. X    { "icon", "Icon", XtRString, sizeof(String),
  965. X      XtOffset(AppResources *,icon), XtRString, "nh72" },
  966. X};
  967. X
  968. Xvoid
  969. XX11_init_nhwindows()
  970. X{
  971. X    static const char *banner_text[] = {
  972. X    "NetHack",
  973. X    "Copyright 1985, 1986, 1987, 1988, 1989, 1990, 1991, 1992, 1993",
  974. X    "by Stichting Mathematisch Centrum and M. Stephenson.",
  975. X    "See license for details.",
  976. X    "",
  977. X    "",
  978. X    0
  979. X    };
  980. X    static const char *av[] = { "nethack" };
  981. X    register const char **pp;
  982. X    int i;
  983. X    Cardinal num_args;
  984. X    Arg args[4];
  985. X
  986. X    /* Init windows to nothing. */
  987. X    for (i = 0; i < MAX_WINDOWS; i++)
  988. X    window_list[i].type = NHW_NONE;
  989. X
  990. X    XSetIOErrorHandler((XIOErrorHandler) hangup);
  991. X
  992. X    i = 1;
  993. X    num_args = 0;
  994. X    XtSetArg(args[num_args], XtNallowShellResize, True);    num_args++;
  995. X    toplevel = XtAppInitialize(
  996. X            &app_context,
  997. X            "NetHack",        /* application class */
  998. X            NULL, 0,        /* options list */
  999. X            &i, av,        /* command line args */
  1000. X            NULL,        /* fallback resources */
  1001. X            args, num_args);
  1002. X
  1003. X    /* We don't need to realize the top level widget. */
  1004. X
  1005. X#ifdef TEXTCOLOR
  1006. X    /* add new color converter to deal with overused colormaps */
  1007. X    XtSetTypeConverter(XtRString, XtRPixel, nhCvtStringToPixel,
  1008. X               nhcolorConvertArgs, XtNumber(nhcolorConvertArgs),
  1009. X               XtCacheByDisplay, nhFreePixel);
  1010. X#endif /* TEXTCOLOR */
  1011. X
  1012. X    /* Register the actions mentioned in "actions". */
  1013. X    XtAppAddActions(app_context, actions, XtNumber(actions));
  1014. X
  1015. X    /* Get application-wide resources */
  1016. X    XtGetApplicationResources(toplevel,(XtPointer)&appResources,
  1017. X                  resources,XtNumber(resources),NULL,ZERO);
  1018. X
  1019. X    /* Initialize other things. */
  1020. X    init_standard_windows();
  1021. X    init_extended_commands_popup();
  1022. X
  1023. X    /* Give the window manager an icon to use;  toplevel must be realized. */
  1024. X    if (appResources.icon && *appResources.icon) {
  1025. X    struct icon_info *ip;
  1026. X
  1027. X    for (ip = icon_data; ip->name; ip++)
  1028. X        if (!strcmp(appResources.icon, ip->name)) {
  1029. X        icon_pixmap = XCreateBitmapFromData(XtDisplay(toplevel),
  1030. X                    XtWindow(toplevel),
  1031. X                    ip->bits, ip->width, ip->height);
  1032. X        if (icon_pixmap != None) {
  1033. X            XWMHints hints;
  1034. X
  1035. X            hints.flags = IconPixmapHint;
  1036. X            hints.icon_pixmap = icon_pixmap;
  1037. X            XSetWMHints(XtDisplay(toplevel),
  1038. X                XtWindow(toplevel), &hints);
  1039. X        }
  1040. X        break;
  1041. X        }
  1042. X    }
  1043. X
  1044. X    x_inited = TRUE;    /* X is now initialized */
  1045. X
  1046. X    /* Display the startup banner in the message window. */
  1047. X    for (pp = banner_text; *pp; pp++)
  1048. X    X11_putstr(WIN_MESSAGE, 0, *pp);
  1049. X}
  1050. X
  1051. X/*
  1052. X * Let the OS take care of almost everything.  This includes the "main"
  1053. X * three windows:  message, map, and status.  Note that if I destroy one of
  1054. X * the three main windows, they all will be destroyed, due to their shared
  1055. X * parent.  I currently don't check such a thing occuring, so the whole mess
  1056. X * will probably crash&burn if I tried it.
  1057. X */
  1058. X/* ARGSUSED */
  1059. Xvoid X11_exit_nhwindows(dummy)
  1060. X    const char *dummy;
  1061. X{
  1062. X    /* explicitly free the icon pixmap */
  1063. X    if (icon_pixmap != None) {
  1064. X    XFreePixmap(XtDisplay(toplevel), icon_pixmap);
  1065. X    icon_pixmap = None;
  1066. X    }
  1067. X}
  1068. X
  1069. X
  1070. X/* delay_output ------------------------------------------------------------ */
  1071. X
  1072. X/*
  1073. X * Timeout callback for delay_output().  Send a fake message to the map
  1074. X * window.
  1075. X */
  1076. X/* ARGSUSED */
  1077. Xstatic void
  1078. Xd_timeout(client_data, id)
  1079. X    XtPointer client_data;
  1080. X    XtIntervalId *id;
  1081. X{
  1082. X    XEvent event;
  1083. X    XClientMessageEvent *mesg;
  1084. X
  1085. X    /* Set up a fake message to the event handler. */
  1086. X    mesg = (XClientMessageEvent *) &event;
  1087. X    mesg->type = ClientMessage;
  1088. X    mesg->message_type = XA_STRING;
  1089. X    mesg->format = 8;
  1090. X    XSendEvent(XtDisplay(window_list[WIN_MAP].w),
  1091. X        XtWindow(window_list[WIN_MAP].w),
  1092. X        False,
  1093. X        NoEventMask,
  1094. X        (XEvent*) mesg);
  1095. X}
  1096. X
  1097. X/*
  1098. X * Delay for 50ms.  This is not implemented asynch.  Maybe later.
  1099. X * Start the timeout, then wait in the event loop.  The timeout
  1100. X * function will send an event to the map window which will be waiting
  1101. X * for a sent event.
  1102. X */
  1103. Xvoid
  1104. XX11_delay_output()
  1105. X{
  1106. X    if (!x_inited) return;
  1107. X
  1108. X    (void) XtAppAddTimeOut(app_context, 30L, d_timeout, (XtPointer) 0);
  1109. X
  1110. X    /* The timeout function will enable the event loop exit. */
  1111. X    (void) x_event(EXIT_ON_SENT_EVENT);
  1112. X}
  1113. X
  1114. X
  1115. X/* askname ----------------------------------------------------------------- */
  1116. X/* Callback for askname dialog widget. */
  1117. X/* ARGSUSED */
  1118. Xstatic void
  1119. Xaskname_done(w, client_data, call_data)
  1120. X    Widget w;
  1121. X    XtPointer client_data;
  1122. X    XtPointer call_data;
  1123. X{
  1124. X    int len;
  1125. X    char *s;
  1126. X    Widget dialog = (Widget) client_data;
  1127. X
  1128. X    s = (char *) GetDialogResponse(dialog);
  1129. X
  1130. X    len = strlen(s);
  1131. X    if (len == 0) {
  1132. X    X11_nhbell();
  1133. X    return;
  1134. X    }
  1135. X
  1136. X    /* Truncate name if necessary */
  1137. X    if (len >= sizeof(plname)-1)
  1138. X    len = sizeof(plname)-1;
  1139. X
  1140. X    (void) strncpy(plname, s, len);
  1141. X    plname[len] = '\0';
  1142. X
  1143. X    nh_XtPopdown(XtParent(dialog));
  1144. X    exit_x_event = TRUE;
  1145. X}
  1146. X
  1147. Xvoid
  1148. XX11_askname()
  1149. X{
  1150. X    Widget popup, dialog;
  1151. X    Arg args[1];
  1152. X
  1153. X    XtSetArg(args[0], XtNallowShellResize, True);
  1154. X
  1155. X    popup = XtCreatePopupShell("askname", transientShellWidgetClass,
  1156. X                   toplevel, args, ONE);
  1157. X
  1158. X    dialog = CreateDialog(popup, "dialog",
  1159. X                    askname_done, (XtCallbackProc) 0);
  1160. X
  1161. X    SetDialogPrompt(dialog, "What is your name?");    /* set prompt */
  1162. X    SetDialogResponse(dialog, "");        /* set default answer */
  1163. X
  1164. X    XtRealizeWidget(popup);
  1165. X    positionpopup(popup);        /* center on cursor */
  1166. X
  1167. X    nh_XtPopup(popup, XtGrabExclusive, dialog);
  1168. X
  1169. X    /* The callback will enable the event loop exit. */
  1170. X    (void) x_event(EXIT_ON_EXIT);
  1171. X}
  1172. X
  1173. X
  1174. X/* getline ----------------------------------------------------------------- */
  1175. X/* This uses Tim Theisen's dialog widget set (from GhostView). */
  1176. X
  1177. Xstatic Widget getline_popup, getline_dialog;
  1178. X
  1179. X#define CANCEL_STR "\033"
  1180. Xstatic char *getline_input;
  1181. X
  1182. X
  1183. X/* Callback for getline dialog widget. */
  1184. X/* ARGSUSED */
  1185. Xstatic void
  1186. Xdone_button(w, client_data, call_data)
  1187. X    Widget w;
  1188. X    XtPointer client_data;
  1189. X    XtPointer call_data;
  1190. X{
  1191. X    char *s;
  1192. X    Widget dialog = (Widget) client_data;
  1193. X
  1194. X    s = (char *) GetDialogResponse(dialog);
  1195. X
  1196. X    if (strlen(s) == 0)
  1197. X    Strcpy(getline_input, CANCEL_STR);
  1198. X    else
  1199. X    Strcpy(getline_input, s);
  1200. X
  1201. X    nh_XtPopdown(XtParent(dialog));
  1202. X    exit_x_event = TRUE;
  1203. X}
  1204. X
  1205. X/* Callback for getline dialog widget. */
  1206. X/* ARGSUSED */
  1207. Xstatic void
  1208. Xabort_button(w, client_data, call_data)
  1209. X    Widget w;
  1210. X    XtPointer client_data;
  1211. X    XtPointer call_data;
  1212. X{
  1213. X    Widget dialog = (Widget) client_data;
  1214. X
  1215. X    Strcpy(getline_input, CANCEL_STR);
  1216. X    nh_XtPopdown(XtParent(dialog));
  1217. X    exit_x_event = TRUE;
  1218. X}
  1219. X
  1220. X
  1221. Xvoid
  1222. XX11_getlin(question, input)
  1223. X    const char *question;
  1224. X    char *input;
  1225. X{
  1226. X    static boolean need_to_init = True;
  1227. X
  1228. X    getline_input = input;
  1229. X
  1230. X    flush_screen(1);
  1231. X    if (need_to_init) {
  1232. X    Arg args[1];
  1233. X
  1234. X    need_to_init = False;
  1235. X
  1236. X    XtSetArg(args[0], XtNallowShellResize, True);
  1237. X
  1238. X    getline_popup = XtCreatePopupShell("getline",transientShellWidgetClass,
  1239. X                   toplevel, args, ONE);
  1240. X
  1241. X    getline_dialog = CreateDialog(getline_popup, "dialog",
  1242. X                    done_button, abort_button);
  1243. X
  1244. X    XtRealizeWidget(getline_popup);
  1245. X    }
  1246. X    SetDialogPrompt(getline_dialog, question);    /* set prompt */
  1247. X    SetDialogResponse(getline_dialog, "");    /* set default answer */
  1248. X    positionpopup(getline_popup);        /* center on cursor */
  1249. X
  1250. X    nh_XtPopup(getline_popup, XtGrabNone, getline_dialog);
  1251. X
  1252. X    /* The callback will enable the event loop exit. */
  1253. X    (void) x_event(EXIT_ON_EXIT);
  1254. X}
  1255. X
  1256. X
  1257. X/* Display file ------------------------------------------------------------ */
  1258. Xstatic const char display_translations[] =
  1259. X    "#override\n\
  1260. X     <BtnDown>: dismiss_file()";
  1261. X
  1262. X
  1263. X/* Callback for file dismissal. */
  1264. X/*ARGSUSED*/
  1265. Xstatic void
  1266. Xdismiss_file(w, event, params, num_params)
  1267. X    Widget w;
  1268. X    XEvent *event;
  1269. X    String *params;
  1270. X    Cardinal *num_params;
  1271. X{
  1272. X    Widget popup = XtParent(w);
  1273. X    nh_XtPopdown(popup);
  1274. X    XtDestroyWidget(popup);
  1275. X}
  1276. X
  1277. Xvoid
  1278. XX11_display_file(str, complain)
  1279. X    const char *str;
  1280. X    boolean complain;
  1281. X{
  1282. X    FILE *fp;
  1283. X    Arg args[12];
  1284. X    Cardinal num_args;
  1285. X    Widget popup, dispfile;
  1286. X    Position top_margin, bottom_margin, left_margin, right_margin;
  1287. X    XFontStruct *fs;
  1288. X    int new_width, new_height;
  1289. X#define LLEN 128
  1290. X    char line[LLEN];
  1291. X    int num_lines;
  1292. X
  1293. X    /* Use the port-independent file opener to see if the file exists. */
  1294. X    fp = fopen_datafile(str, "r");
  1295. X
  1296. X    if (!fp) {
  1297. X    if(complain) pline("Cannot open %s.  Sorry.", str);
  1298. X
  1299. X    return;    /* it doesn't exist, ignore */
  1300. X    }
  1301. X
  1302. X    /*
  1303. X     * Count the number of lines in the file.  If under the max display
  1304. X     * size, use that instead.
  1305. X     */
  1306. X    num_lines = 0;
  1307. X    while (fgets(line, LLEN, fp)) {
  1308. X    num_lines++;
  1309. X    if (num_lines >= DISPLAY_FILE_SIZE) break;
  1310. X    }
  1311. X
  1312. X    (void) fclose(fp);
  1313. X
  1314. X    /* Ignore empty files */
  1315. X    if (num_lines == 0) return;
  1316. X
  1317. X    num_args = 0;
  1318. X    XtSetArg(args[num_args], XtNtitle, str);    num_args++;
  1319. X
  1320. X    popup = XtCreatePopupShell("display_file", topLevelShellWidgetClass,
  1321. X                           toplevel, args, num_args);
  1322. X
  1323. X    num_args = 0;
  1324. X    XtSetArg(args[num_args], XtNscrollHorizontal,
  1325. X                XawtextScrollWhenNeeded);    num_args++;
  1326. X    XtSetArg(args[num_args], XtNscrollVertical,
  1327. X                XawtextScrollWhenNeeded);    num_args++;
  1328. X    XtSetArg(args[num_args], XtNtype, XawAsciiFile);        num_args++;
  1329. X    XtSetArg(args[num_args], XtNstring, str);            num_args++;
  1330. X    XtSetArg(args[num_args], XtNdisplayCaret, False);        num_args++;
  1331. X    XtSetArg(args[num_args], XtNtranslations,
  1332. X    XtParseTranslationTable(display_translations));        num_args++;
  1333. X
  1334. X    dispfile = XtCreateManagedWidget(
  1335. X            "text",            /* name */
  1336. X            asciiTextWidgetClass,
  1337. X            popup,            /* parent widget */
  1338. X            args,            /* set some values */
  1339. X            num_args);        /* number of values to set */
  1340. X
  1341. X    /* Get font and border information. */
  1342. X    num_args = 0;
  1343. X    XtSetArg(args[num_args], XtNfont,          &fs);           num_args++;
  1344. X    XtSetArg(args[num_args], XtNtopMargin,    &top_margin);    num_args++;
  1345. X    XtSetArg(args[num_args], XtNbottomMargin, &bottom_margin); num_args++;
  1346. X    XtSetArg(args[num_args], XtNleftMargin,   &left_margin);   num_args++;
  1347. X    XtSetArg(args[num_args], XtNrightMargin,  &right_margin);  num_args++;
  1348. X    XtGetValues(dispfile, args, num_args);
  1349. X
  1350. X    /*
  1351. X     * Font height is ascent + descent.
  1352. X     *
  1353. X     * The data files are currently set up assuming an 80 char wide window
  1354. X     * and a fixed width font.  Soo..
  1355. X     */
  1356. X    new_height = num_lines * (fs->ascent + fs->descent) +
  1357. X                        top_margin + bottom_margin;
  1358. X    new_width  = 80 * fs->max_bounds.width + left_margin + right_margin;
  1359. X
  1360. X    /* Set the new width and height. */
  1361. X    num_args = 0;
  1362. X    XtSetArg(args[num_args], XtNwidth,  new_width);  num_args++;
  1363. X    XtSetArg(args[num_args], XtNheight, new_height); num_args++;
  1364. X    XtSetValues(dispfile, args, num_args);
  1365. X
  1366. X    nh_XtPopup(popup, XtGrabNone, None);
  1367. X}
  1368. X
  1369. X
  1370. X/* yn_function ------------------------------------------------------------- */
  1371. X/* (not threaded) */
  1372. X
  1373. Xstatic const char *yn_quitchars = " \n\r";
  1374. Xstatic const char *yn_choices;    /* string of acceptable input */
  1375. Xstatic char yn_def;
  1376. Xstatic char yn_return;        /* return value */
  1377. Xstatic char yn_esc_map;        /* ESC maps to this char. */
  1378. Xstatic Widget yn_popup;        /* popup for the yn fuction (created once) */
  1379. Xstatic Widget yn_label;        /* label for yn function (created once) */
  1380. Xstatic boolean yn_getting_num;    /* TRUE if accepting digits */
  1381. Xstatic int yn_ndigits;        /* digit count */
  1382. Xstatic long yn_val;        /* accumulated value */
  1383. X
  1384. Xstatic const char yn_translations[] =
  1385. X    "#override\n\
  1386. X     <Key>: yn_key()";
  1387. X
  1388. X/*
  1389. X * Convert the given key event into a character.  If the key maps to
  1390. X * more than one character only the first is returned.  If there is
  1391. X * no conversion (i.e. just the CTRL key hit) a NULL is returned.
  1392. X */
  1393. Xchar
  1394. Xkey_event_to_char(key)
  1395. X    XKeyEvent *key;
  1396. X{
  1397. X    char keystring[MAX_KEY_STRING];
  1398. X    int nbytes;
  1399. X
  1400. X    nbytes = XLookupString(key, keystring, MAX_KEY_STRING, NULL, NULL);
  1401. X
  1402. X    /* Modifier keys return a zero lengh string when pressed. */
  1403. X    if (nbytes == 0) return '\0';
  1404. X
  1405. X    return keystring[0];
  1406. X}
  1407. X
  1408. X/*
  1409. X * Called when we get a key press event on a yn window.
  1410. X */
  1411. X/* ARGSUSED */
  1412. Xstatic void
  1413. Xyn_key(w, event, params, num_params)
  1414. X    Widget w;
  1415. X    XEvent *event;
  1416. X    String *params;
  1417. X    Cardinal *num_params;
  1418. X{
  1419. X    char ch;
  1420. X
  1421. X    if(appResources.slow && !input_func)
  1422. X    extern_map_input(event);
  1423. X
  1424. X    ch = key_event_to_char((XKeyEvent *) event);
  1425. X
  1426. X    if (ch == '\0') {    /* don't accept nul char or modifier event */
  1427. X    /* no bell */
  1428. X    return;
  1429. X    }
  1430. X
  1431. X    if (!yn_choices) {            /* accept any input */
  1432. X    yn_return = ch;
  1433. X    } else {
  1434. X    ch = lowc(ch);            /* move to lower case */
  1435. X
  1436. X    if (ch == '\033') {
  1437. X        yn_getting_num = FALSE;
  1438. X        yn_return = yn_esc_map;
  1439. X    } else if (index(yn_quitchars, ch)) {
  1440. X        yn_return = yn_def;
  1441. X    } else if (index(yn_choices, ch)) {
  1442. X        if (ch == '#') {
  1443. X        if (yn_getting_num) {    /* don't select again */
  1444. X            X11_nhbell();
  1445. X            return;
  1446. X        }
  1447. X        yn_getting_num = TRUE;
  1448. X        yn_ndigits = 0;
  1449. X        yn_val = 0;
  1450. X        return;            /* wait for more input */
  1451. X        }
  1452. X        yn_return = ch;
  1453. X        if (ch != 'y') yn_getting_num = FALSE;
  1454. X    } else {
  1455. X        if (yn_getting_num) {
  1456. X        if (digit(ch)) {
  1457. X            yn_ndigits++;
  1458. X            yn_val = (yn_val * 10) + (long) (ch - '0');
  1459. X            return;            /* wait for more input */
  1460. X        }
  1461. X        if (yn_ndigits && (ch == '\b' || ch == 127/*DEL*/)) {
  1462. X            yn_ndigits--;
  1463. X            yn_val = yn_val/ 10;
  1464. X            return;            /* wait for more input */
  1465. X        }
  1466. X        }
  1467. X        X11_nhbell();        /* no match */
  1468. X        return;
  1469. X    }
  1470. X
  1471. X    if (yn_getting_num) {
  1472. X        yn_return = '#';
  1473. X        yn_number = yn_val;    /* assign global */
  1474. X    }
  1475. X    }
  1476. X    exit_x_event = TRUE;    /* exit our event handler */
  1477. X}
  1478. X
  1479. X
  1480. Xchar
  1481. XX11_yn_function(ques, choices, def)
  1482. X    const char *ques;
  1483. X    const char *choices;
  1484. X    char def;
  1485. X{
  1486. X    static Boolean need_to_init = True;
  1487. X    char buf[QBUFSZ];
  1488. X    Arg args[4];
  1489. X    Cardinal num_args;
  1490. X
  1491. X    yn_choices = choices;    /* set up globals for callback to use */
  1492. X    yn_def     = def;
  1493. X
  1494. X    /*
  1495. X     * This is sort of a kludge.  There are quite a few places in the main
  1496. X     * nethack code where a pline containing information is followed by a
  1497. X     * call to yn_function().  There is no flush of the message window
  1498. X     * (it is implicit in the tty window port), so the line never shows
  1499. X     * up for us!  Solution: do our own flush.
  1500. X     */
  1501. X    if (WIN_MESSAGE != WIN_ERR)
  1502. X    display_message_window(&window_list[WIN_MESSAGE]);
  1503. X
  1504. X    if (choices) {
  1505. X    /* ques [choices] (def) */
  1506. X    if ((1 + strlen(ques) + 2 + strlen(choices) + 4) >= QBUFSZ)
  1507. X        panic("yn_function:  question too long");
  1508. X    if (def)
  1509. X        Sprintf(buf, "%s [%s] (%c)", ques, choices, def);
  1510. X    else
  1511. X        Sprintf(buf, "%s [%s] ", ques, choices);
  1512. X
  1513. X    /* escape maps to 'q' or 'n' or default, in that order */
  1514. X    yn_esc_map = (index(choices, 'q') ? 'q' :
  1515. X             (index(choices, 'n') ? 'n' :
  1516. X                        def));
  1517. X    } else {
  1518. X    if ((1 + strlen(ques)) >= QBUFSZ)
  1519. X        panic("yn_function:  question too long");
  1520. X    Strcpy(buf, ques);
  1521. X    }
  1522. X
  1523. X    if (!appResources.slow && need_to_init) {
  1524. X    need_to_init = False;
  1525. X
  1526. X    XtSetArg(args[0], XtNallowShellResize, True);
  1527. X    yn_popup = XtCreatePopupShell("query", transientShellWidgetClass,
  1528. X                    toplevel, args, ONE);
  1529. X
  1530. X    num_args = 0;
  1531. X    XtSetArg(args[num_args], XtNtranslations,
  1532. X        XtParseTranslationTable(yn_translations));    num_args++;
  1533. X    yn_label = XtCreateManagedWidget("yn_label",
  1534. X                labelWidgetClass,
  1535. X                yn_popup,
  1536. X                args, num_args);
  1537. X
  1538. X    XtRealizeWidget(yn_popup);
  1539. X    }
  1540. X
  1541. X    if(appResources.slow)
  1542. X    input_func = yn_key;
  1543. X
  1544. X    num_args = 0;
  1545. X    XtSetArg(args[num_args], XtNlabel, buf);    num_args++;
  1546. X    XtSetValues(yn_label, args, num_args);
  1547. X
  1548. X    if(!appResources.slow) {
  1549. X    /*
  1550. X     * Due to some kind of weird bug in the X11R4 and X11R5 shell, we
  1551. X     * need to set the label twice to get the size to change.
  1552. X     */
  1553. X    num_args = 0;
  1554. X    XtSetArg(args[num_args], XtNlabel, buf); num_args++;
  1555. X    XtSetValues(yn_label, args, num_args);
  1556. X
  1557. X    positionpopup(yn_popup);
  1558. X    nh_XtPopup(yn_popup, XtGrabExclusive, yn_label);
  1559. X    }
  1560. X
  1561. X    yn_getting_num = FALSE;
  1562. X    (void) x_event(EXIT_ON_EXIT);
  1563. X
  1564. X    if(appResources.slow) {
  1565. X    input_func = 0;
  1566. X    num_args = 0;
  1567. X    XtSetArg(args[num_args], XtNlabel, " ");    num_args++;
  1568. X    XtSetValues(yn_label, args, num_args);
  1569. X    } else {
  1570. X    nh_XtPopdown(yn_popup);    /* this removes the event grab */
  1571. X    }
  1572. X
  1573. X    return yn_return;
  1574. X}
  1575. X
  1576. X/* End global functions ==================================================== */
  1577. X
  1578. X/*
  1579. X * Before we wait for input via nhgetch() and nh_poskey(), we need to
  1580. X * do some pre-processing.
  1581. X */
  1582. Xstatic int
  1583. Xinput_event(exit_condition)
  1584. X    int exit_condition;
  1585. X{
  1586. X    if (WIN_STATUS != WIN_ERR)    /* hilighting on the fancy status window */
  1587. X    check_turn_events();
  1588. X    if (WIN_MAP != WIN_ERR)    /* make sure cursor is not clipped */
  1589. X    check_cursor_visibility(&window_list[WIN_MAP]);
  1590. X    if (WIN_MESSAGE != WIN_ERR)    /* reset pause line */
  1591. X    set_last_pause(&window_list[WIN_MESSAGE]);
  1592. X
  1593. X    return x_event(exit_condition);
  1594. X}
  1595. X
  1596. X
  1597. X/*ARGSUSED*/
  1598. Xvoid
  1599. Xmsgkey(w, data, event)
  1600. X    Widget w;
  1601. X    XtPointer data;
  1602. X    XEvent *event;
  1603. X{
  1604. X    extern_map_input(event);
  1605. X}
  1606. X
  1607. X/*
  1608. X * Set up the playing console.  This has three major parts:  the
  1609. X * message window, the map, and the status window.
  1610. X */
  1611. Xstatic void
  1612. Xinit_standard_windows()
  1613. X{
  1614. X    Widget form, message_viewport, map_viewport, status;
  1615. X    Arg args[8];
  1616. X    Cardinal num_args;
  1617. X    Dimension message_vp_width, map_vp_width, status_width, max_width;
  1618. X    int map_vp_hd, status_hd;
  1619. X    struct xwindow *wp;
  1620. X
  1621. X
  1622. X    num_args = 0;
  1623. X    XtSetArg(args[num_args], XtNallowShellResize, True);    num_args++;
  1624. X    form = XtCreateManagedWidget("nethack",
  1625. X                formWidgetClass,
  1626. X                toplevel, args, num_args);
  1627. X
  1628. X    XtAddEventHandler(form, KeyPressMask, False,
  1629. X              (XtEventHandler) msgkey, (XtPointer) 0);
  1630. X
  1631. X    /*
  1632. X     * Create message window.
  1633. X     */
  1634. X    WIN_MESSAGE = message_win = find_free_window();
  1635. X    wp = &window_list[message_win];
  1636. X    wp->cursx = wp->cursy = wp->pixel_width = wp->pixel_height = 0;
  1637. X    wp->popup = (Widget) 0;
  1638. X    create_message_window(wp, FALSE, form);
  1639. X    message_viewport = XtParent(wp->w);
  1640. X
  1641. X
  1642. X    /* Tell the form that contains it that resizes are OK. */
  1643. X    num_args = 0;
  1644. X    XtSetArg(args[num_args], XtNresizable, True);        num_args++;
  1645. X    XtSetArg(args[num_args], XtNleft,       XtChainLeft);    num_args++;
  1646. X    XtSetArg(args[num_args], XtNtop,       XtChainTop);        num_args++;
  1647. X    XtSetValues(message_viewport, args, num_args);
  1648. X
  1649. X    if(appResources.slow) {
  1650. X    num_args = 0;
  1651. X    XtSetArg(args[num_args], XtNtranslations,
  1652. X         XtParseTranslationTable(yn_translations)); num_args++;
  1653. X    yn_label = XtCreateManagedWidget("yn_label",
  1654. X                     labelWidgetClass,
  1655. X                     form,
  1656. X                     args, num_args);
  1657. X    num_args = 0;
  1658. X    XtSetArg(args[num_args], XtNfromVert, message_viewport); num_args++;
  1659. X    XtSetArg(args[num_args], XtNresizable, True);    num_args++;
  1660. X    XtSetArg(args[num_args], XtNlabel, " ");    num_args++;
  1661. X    XtSetValues(yn_label, args, num_args);
  1662. X    }
  1663. X
  1664. X    /*
  1665. X     * Create the map window & viewport and chain the viewport beneath the
  1666. X     * message_viewport.
  1667. X     */
  1668. X    map_win = find_free_window();
  1669. X    wp = &window_list[map_win];
  1670. X    wp->cursx = wp->cursy = wp->pixel_width = wp->pixel_height = 0;
  1671. X    wp->popup = (Widget) 0;
  1672. X    create_map_window(wp, FALSE, form);
  1673. X    map_viewport = XtParent(wp->w);
  1674. X
  1675. X    /* Chain beneath message_viewport or yn window. */
  1676. X    num_args = 0;
  1677. X    if(appResources.slow) {
  1678. X    XtSetArg(args[num_args], XtNfromVert, yn_label);    num_args++;
  1679. X    } else {
  1680. X    XtSetArg(args[num_args], XtNfromVert, message_viewport);num_args++;
  1681. X    }
  1682. X    XtSetArg(args[num_args], XtNbottom, XtChainBottom);        num_args++;
  1683. X    XtSetValues(map_viewport, args, num_args);
  1684. X
  1685. X    /* Create the status window, with the form as it's parent. */
  1686. X    status_win = find_free_window();
  1687. X    wp = &window_list[status_win];
  1688. X    wp->cursx = wp->cursy = wp->pixel_width = wp->pixel_height = 0;
  1689. X    wp->popup = (Widget) 0;
  1690. X    create_status_window(wp, FALSE, form);
  1691. X    status = wp->w;
  1692. X
  1693. X    /*
  1694. X     * Chain the status window beneath the viewport.  Mark the left and right
  1695. X     * edges so that they stay a fixed distance from the left edge of the
  1696. X     * parent, as well as the top and bottom edges so that they stay a fixed
  1697. X     * distance from the bottom of the parent.  We do this so that the status
  1698. X     * will never expand or contract.
  1699. X     */
  1700. X    num_args = 0;
  1701. X    XtSetArg(args[num_args], XtNfromVert, map_viewport);    num_args++;
  1702. X    XtSetArg(args[num_args], XtNleft,      XtChainLeft);        num_args++;
  1703. X    XtSetArg(args[num_args], XtNright,      XtChainLeft);        num_args++;
  1704. X    XtSetArg(args[num_args], XtNtop,      XtChainBottom);    num_args++;
  1705. X    XtSetArg(args[num_args], XtNbottom,      XtChainBottom);    num_args++;
  1706. X    XtSetValues(status, args, num_args);
  1707. X
  1708. X
  1709. X    /*
  1710. X     * Realize the popup so that the status widget knows it's size.
  1711. X     *
  1712. X     * If we unset MappedWhenManaged then the DECwindow driver doesn't
  1713. X     * attach the nethack toplevel to the highest virtual root window.
  1714. X     * So don't do it.
  1715. X     */
  1716. X    /* XtSetMappedWhenManaged(toplevel, False); */
  1717. X    XtRealizeWidget(toplevel);
  1718. X    /*
  1719. X     * The message window was the size we want the viewport to take (when
  1720. X     * realized).  Now change to our real height.  Do this before we resize
  1721. X     * so that the vertical scrollbar is activated and is taken into account
  1722. X     * when calculating the widget size.  If we do this last, then the
  1723. X     * message window ends up being short by one scrollbar width.  [Brain-dead
  1724. X     * viewport widget.]
  1725. X     */
  1726. X    set_message_height(&window_list[message_win], (int) flags.msg_history);
  1727. X
  1728. X    /*
  1729. X     * Now get the default widths of the windows.
  1730. X     */
  1731. X    XtSetArg(args[0], XtNwidth, &message_vp_width);
  1732. X    XtGetValues(message_viewport, args, ONE);
  1733. X    XtSetArg(args[0], XtNwidth, &map_vp_width);
  1734. X    XtSetArg(args[1], XtNhorizDistance, &map_vp_hd);
  1735. X    XtGetValues(map_viewport, args, TWO);
  1736. X    XtSetArg(args[0], XtNwidth, &status_width);
  1737. X    XtSetArg(args[1], XtNhorizDistance, &status_hd);
  1738. X    XtGetValues(status, args, TWO);
  1739. X
  1740. X    /*
  1741. X     * Adjust positions and sizes.  The message viewport widens out to the
  1742. X     * widest width.  Both the map and status are centered by adjusting
  1743. X     * their horizDistance.
  1744. X     */
  1745. X    if (map_vp_width < status_width || map_vp_width < message_vp_width) {
  1746. X    if (status_width > message_vp_width) {
  1747. X        XtSetArg(args[0], XtNwidth, status_width);
  1748. X        XtSetValues(message_viewport, args, ONE);
  1749. X        max_width = status_width;
  1750. X    } else {
  1751. X/***** The status display looks better when left justified.
  1752. X        XtSetArg(args[0], XtNhorizDistance,
  1753. X                status_hd+((message_vp_width-status_width)/2));
  1754. X        XtSetValues(status, args, ONE);
  1755. X*****/
  1756. X        max_width = message_vp_width;
  1757. X    }
  1758. X    XtSetArg(args[0], XtNhorizDistance, map_vp_hd+((int)(max_width-map_vp_width)/2));
  1759. X    XtSetValues(map_viewport, args, ONE);
  1760. X
  1761. X    } else {    /* map is widest */
  1762. X    XtSetArg(args[0], XtNwidth, map_vp_width);
  1763. X    XtSetValues(message_viewport, args, ONE);
  1764. X
  1765. X/***** The status display looks better when left justified.
  1766. X    XtSetArg(args[0], XtNhorizDistance,
  1767. X                status_hd+((map_vp_width-status_width)/2));
  1768. X
  1769. X    XtSetValues(status, args, ONE);
  1770. X*****/
  1771. X    }
  1772. X    /*
  1773. X     * Clear all data values on the fancy status widget so that the values
  1774. X     * used for spacing don't appear.  This needs to be called some time
  1775. X     * after the fancy status widget is realized (above, with the game popup),
  1776. X     * but before it is popped up.
  1777. X     */
  1778. X    null_out_status();
  1779. X    /*
  1780. X     * Set the map size to its standard size.  As with the message window
  1781. X     * above, the map window needs to be set to its constrained size until
  1782. X     * its parent (the viewport widget) was realized.
  1783. X     *
  1784. X     * Move the message window's slider to the bottom.
  1785. X     */
  1786. X    set_map_size(&window_list[map_win], COLNO, ROWNO);
  1787. X    set_message_slider(&window_list[message_win]);
  1788. X
  1789. X    /* grab initial input focus */
  1790. X    if (appResources.autofocus) {
  1791. X    Display *dpy = XtDisplay(toplevel);
  1792. X    Window   win = XtWindow(toplevel), current;
  1793. X    int      revert;
  1794. X
  1795. X    /*
  1796. X     * We don't actually care about the `revert' value; this mainly serves
  1797. X     * the purpose of synchronizing with the popup.
  1798. X     */
  1799. X    XGetInputFocus(dpy, ¤t, &revert);
  1800. X
  1801. X    /* attach the keyboard to the main window */
  1802. X    if (win != current) {
  1803. X        sleep(1);    /* ugh, delay so window is showing.. */
  1804. X        XSetInputFocus(dpy, win, revert, CurrentTime);
  1805. X    }
  1806. X    }
  1807. X
  1808. X    /* attempt to catch fatal X11 errors before the program quits */
  1809. X    (void) XtAppSetErrorHandler(app_context, (XtErrorHandler) hangup);
  1810. X
  1811. X    /* We can now print to the message window. */
  1812. X    flags.window_inited = 1;
  1813. X}
  1814. X
  1815. X
  1816. Xvoid
  1817. Xnh_XtPopup(w, g, childwid)
  1818. X    Widget w;        /* widget */
  1819. X    int    g;        /* type of grab */
  1820. X    Widget childwid;    /* child to recieve focus (can be None) */
  1821. X{
  1822. X    XtPopup(w, (XtGrabKind)g);
  1823. X    if (appResources.autofocus) XtSetKeyboardFocus(toplevel, childwid);
  1824. X}
  1825. X
  1826. Xvoid
  1827. Xnh_XtPopdown(w)
  1828. X    Widget w;
  1829. X{
  1830. X    XtPopdown(w);
  1831. X    if (appResources.autofocus) XtSetKeyboardFocus(toplevel, None);
  1832. X}
  1833. X
  1834. Xvoid
  1835. Xwin_X11_init()
  1836. X{
  1837. X#ifdef OPENWINBUG
  1838. X    /* With the OpenWindows 3.0 libraries and the SunOS 4.1.2 ld, these
  1839. X     * two routines will not be found when linking.  An apparently correct
  1840. X     * executable is produced, along with nasty messages and a failure code
  1841. X     * returned to make.  The routines are in the static libXmu.a and
  1842. X     * libXmu.sa.4.0, but not in libXmu.so.4.0.  Rather than fiddle with
  1843. X     * static linking, we do this.
  1844. X     */
  1845. X    if (rn2(2) > 2) {
  1846. X    /* i.e., FALSE that an optimizer probably can't find */
  1847. X    get_wmShellWidgetClass();
  1848. X    get_applicationShellWidgetClass();
  1849. X    }
  1850. X#endif
  1851. X    return;
  1852. X}
  1853. X
  1854. X/*winX.c*/
  1855. END_OF_FILE
  1856. if test 45228 -ne `wc -c <'win/X11/winX.c'`; then
  1857.     echo shar: \"'win/X11/winX.c'\" unpacked with wrong size!
  1858. fi
  1859. # end of 'win/X11/winX.c'
  1860. fi
  1861. echo shar: End of archive 16 \(of 108\).
  1862. cp /dev/null ark16isdone
  1863. MISSING=""
  1864. for I in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 \
  1865. 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 \
  1866. 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 \
  1867. 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 \
  1868. 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 \
  1869. 101 102 103 104 105 106 107 108 ; do
  1870.     if test ! -f ark${I}isdone ; then
  1871.     MISSING="${MISSING} ${I}"
  1872.     fi
  1873. done
  1874. if test "${MISSING}" = "" ; then
  1875.     echo You have unpacked all 108 archives.
  1876.     echo "Now execute 'rebuild.sh'"
  1877.     rm -f ark10[0-8]isdone ark[1-9]isdone ark[1-9][0-9]isdone
  1878. else
  1879.     echo You still need to unpack the following archives:
  1880.     echo "        " ${MISSING}
  1881. fi
  1882. ##  End of shell archive.
  1883. exit 0
  1884.