home *** CD-ROM | disk | FTP | other *** search
/ Source Code 1994 March / Source_Code_CD-ROM_Walnut_Creek_March_1994.iso / compsrcs / games / volume16 / nethck31 / part16 < prev    next >
Encoding:
Internet Message Format  |  1993-01-31  |  57.0 KB

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