diff -Naurd ../nethack-3.3.1/win/X11/Install.X11 ./win/X11/Install.X11
--- ../nethack-3.3.1/win/X11/Install.X11 Tue Nov 23 02:42:51 1999
+++ ./win/X11/Install.X11 Fri Mar 22 14:40:55 2002
@@ -40,6 +40,12 @@
 the VARDATND setting in the top Makefile to contain the tile files before
 you do your 'make all'.
 
+If you get a linker error referring to `substitute_tiles' then most
+likely you have overlooked the WINSRC, WINOBJ, WINLIB step above.
+Alternatively, you are building with more than one non-tty interface
+specified but haven't followed the direction in src/Makefile to remove
+all but one instance of tile.o from the WINxxxOBJ values used for WINOBJ.
+
 When using tiles, you have the option of defining USE_XPM in config.h.
 This causes NetHack to use the XPM file format for the "x11tiles" file
 rather than a custom format.  Since the XPM format can be processed by
diff -Naurd ../nethack-3.3.1/win/X11/NetHack.ad ./win/X11/NetHack.ad
--- ../nethack-3.3.1/win/X11/NetHack.ad Tue Jan 4 22:57:45 2000
+++ ./win/X11/NetHack.ad Fri Mar 22 14:40:55 2002
@@ -59,10 +59,10 @@
 ! It is not guaranteed that the window manager will honor the icon selection.
 !NetHack*icon: nh56
 !
-! If True, a popup for single character prompts such as y/n questions is _not_
-! used.
-!NetHack*slow: True
-!
+! If True, the default, a popup for single character prompts such as y/n
+! questions is _not_ used.
+NetHack*slow: True
+
 ! The number of lines the message window will show without scrolling.
 !NetHack*message_lines: 12
 !
diff -Naurd ../nethack-3.3.1/win/X11/nh32icon ./win/X11/nh32icon
--- ../nethack-3.3.1/win/X11/nh32icon Mon Nov 15 00:24:26 1999
+++ ./win/X11/nh32icon Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)nh32icon	3.3	95/07/19			*/
+/*	SCCS Id: @(#)nh32icon	3.4	2002/02/12			*/
 /*	Copyright (C) 1993,1995 by Robert Patrick Rankin		*/
 /* NetHack may be freely redistributed.  See license for details.	*/
 
@@ -10,9 +10,9 @@
    0xff, 0x7f, 0xfe, 0xff, 0x01, 0xc0, 0x03, 0x80, 0x01, 0x00, 0x40, 0x82,
    0x21, 0x25, 0xc0, 0x83, 0x61, 0x25, 0x80, 0x81, 0xe1, 0x3d, 0x80, 0x81,
    0xa1, 0x25, 0x80, 0x81, 0x21, 0x25, 0x80, 0x81, 0x01, 0x00, 0xe0, 0x87,
-   0x71, 0x38, 0x90, 0x89, 0x81, 0x40, 0x80, 0x81, 0x61, 0x30, 0x80, 0x81,
-   0x81, 0x40, 0x80, 0x81, 0x71, 0x3a, 0x84, 0x81, 0x03, 0x00, 0x8a, 0xc1,
-   0x02, 0x00, 0x84, 0x41, 0x32, 0x73, 0x80, 0x41, 0xf3, 0x7f, 0x80, 0xc1,
+   0x71, 0x48, 0x90, 0x89, 0x81, 0x48, 0x80, 0x81, 0x61, 0x78, 0x80, 0x81,
+   0x81, 0x40, 0x80, 0x81, 0x71, 0x42, 0x84, 0x81, 0x03, 0x00, 0x8a, 0xc1,
+   0x02, 0x00, 0x84, 0x41, 0x32, 0x67, 0x80, 0x41, 0xf3, 0x7f, 0x80, 0xc1,
    0xf1, 0x7f, 0x84, 0x81, 0x71, 0x77, 0x8a, 0x81, 0xb1, 0x68, 0x84, 0x81,
    0x71, 0x77, 0x80, 0x81, 0x71, 0x77, 0x80, 0x81, 0xb1, 0x68, 0x84, 0x81,
    0x71, 0x77, 0x8a, 0x81, 0xf1, 0x7f, 0x84, 0x81, 0xe1, 0x3f, 0x80, 0x81,
diff -Naurd ../nethack-3.3.1/win/X11/nh56icon ./win/X11/nh56icon
--- ../nethack-3.3.1/win/X11/nh56icon Mon Nov 15 00:24:26 1999
+++ ./win/X11/nh56icon Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)nh56icon	3.3	95/07/19			*/
+/*	SCCS Id: @(#)nh56icon	3.4	2002/02/12			*/
 /*	Copyright (c) 1993,1995 by M. Stephenson			*/
 /* NetHack may be freely redistributed.  See license for details.	*/
 
@@ -25,12 +25,12 @@
    0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00,
    0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03,
    0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00,
-   0xc0, 0x43, 0x10, 0x21, 0x38, 0x70, 0x80, 0xc3, 0xc3, 0x10, 0x21, 0x38,
-   0x88, 0x40, 0xc4, 0xc3, 0x10, 0x21, 0x38, 0x80, 0x00, 0xc4, 0x43, 0x11,
-   0x21, 0x38, 0x80, 0x00, 0xc4, 0x43, 0x12, 0x3f, 0x38, 0x70, 0x80, 0xc3,
-   0x43, 0x12, 0x21, 0x38, 0x80, 0x00, 0xc4, 0x43, 0x14, 0x21, 0x38, 0x80,
-   0x00, 0xc4, 0x43, 0x18, 0x21, 0x38, 0x80, 0x00, 0xc4, 0x43, 0x18, 0x21,
-   0x38, 0x88, 0x4c, 0xc4, 0x43, 0x10, 0x21, 0x38, 0x70, 0x8c, 0xc3, 0x03,
+   0xc0, 0x43, 0x10, 0x21, 0x38, 0x70, 0x20, 0xc2, 0xc3, 0x10, 0x21, 0x38,
+   0x88, 0x20, 0xc2, 0xc3, 0x10, 0x21, 0x38, 0x80, 0x20, 0xc2, 0x43, 0x11,
+   0x21, 0x38, 0x80, 0x20, 0xc2, 0x43, 0x12, 0x3f, 0x38, 0x70, 0xe0, 0xc3,
+   0x43, 0x12, 0x21, 0x38, 0x80, 0x00, 0xc2, 0x43, 0x14, 0x21, 0x38, 0x80,
+   0x00, 0xc2, 0x43, 0x18, 0x21, 0x38, 0x80, 0x00, 0xc2, 0x43, 0x18, 0x21,
+   0x38, 0x88, 0x0c, 0xc2, 0x43, 0x10, 0x21, 0x38, 0x70, 0x0c, 0xc2, 0x03,
    0x00, 0x00, 0x38, 0x00, 0x00, 0xc0, 0x03, 0x00, 0x00, 0x38, 0x00, 0x00,
    0xc0, 0xfb, 0xff, 0xff, 0x39, 0xff, 0xff, 0xdf, 0x0b, 0x00, 0x80, 0x7c,
    0x02, 0x00, 0xd0, 0x0b, 0x00, 0x80, 0xee, 0x02, 0x00, 0xd0, 0xfb, 0xff,
diff -Naurd ../nethack-3.3.1/win/X11/nh72icon ./win/X11/nh72icon
--- ../nethack-3.3.1/win/X11/nh72icon Fri Aug 6 04:56:25 1999
+++ ./win/X11/nh72icon Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)nh72icon	3.3	93/01/21			*/
+/*	SCCS Id: @(#)nh72icon	3.4	1993/01/21			*/
 /*	Copyright (c) 1993 by M. Stephenson				*/
 /* NetHack may be freely redistributed.  See license for details.	*/
 
diff -Naurd ../nethack-3.3.1/win/X11/tile2x11.c ./win/X11/tile2x11.c
--- ../nethack-3.3.1/win/X11/tile2x11.c Thu Dec 30 20:45:02 1999
+++ ./win/X11/tile2x11.c Fri Mar 22 14:40:55 2002
@@ -15,7 +15,7 @@
 
 
 x11_header	header;
-unsigned char	tile_bytes[TILE_X*TILE_Y*MAX_GLYPH];
+unsigned char	tile_bytes[TILE_X*TILE_Y*(MAX_GLYPH+TILES_PER_ROW)];
 unsigned char	*curr_tb = tile_bytes;
 unsigned char	x11_colormap[MAXCOLORMAPSIZE][3];
 
@@ -44,8 +44,9 @@
 
 /* Convert the tiles in the file to our format of bytes. */
 static unsigned long
-convert_tiles(tb_ptr)
+convert_tiles(tb_ptr, total)
     unsigned char **tb_ptr;	/* pointer to a tile byte pointer */
+    unsigned long total;	/* total tiles so far */
 {
     unsigned char *tb = *tb_ptr;
     unsigned long count = 0;
@@ -54,12 +55,20 @@
 
     while (read_text_tile(tile)) {
 	count++;
-	for (y = 0; y < TILE_Y; y++)
+	total++;
+	for (y = 0; y < TILE_Y; y++) {
 	    for (x = 0; x < TILE_X; x++)
-		*tb++ = pix_to_colormap(tile[y][x]);
+		tb[x] = pix_to_colormap(tile[y][x]);
+	    tb += TILE_X * header.per_row;
+	}
+
+	/* repoint at the upper-left corner of the next tile */
+	*tb_ptr += TILE_X;
+	if (header.per_row == 1 || (total % header.per_row) == 0)
+	    *tb_ptr += TILE_X * (TILE_Y - 1) * header.per_row;
+	tb = *tb_ptr;
     }
 
-    *tb_ptr = tb;	/* update return val */
     return count;
 }
 
@@ -108,9 +117,9 @@
     if (!fopen_text_file(fname, RDTMODE)) {
 	Fprintf(stderr, "can't open file \"%s\"\n", fname);
 	exit(1);
-	}
+    }
     merge_text_colormap();
-    count = convert_tiles(&curr_tb);
+    count = convert_tiles(&curr_tb, header.ntiles);
     Fprintf(stderr, "%s: %lu tiles\n", fname, count);
     header.ntiles += count;
     fclose_text_file();
@@ -122,7 +131,7 @@
 xpm_write(fp)
 FILE *fp;
 {
-    int i,j,n;
+    int i, j, n;
 
     if (header.ncolors > 64) {
 	Fprintf(stderr, "Sorry, only configured for up to 64 colors\n");
@@ -130,34 +139,32 @@
 	/* All you need to do is add more char per color - below */
     }
 
-    fprintf(fp, "/* XPM */\n");
-    fprintf(fp, "static char* nhtiles[] = {\n");
-    fprintf(fp, "\"%lu %lu %lu %d\",\n",
-		header.tile_width,
-		header.tile_height*header.ntiles,
+    Fprintf(fp, "/* XPM */\n");
+    Fprintf(fp, "static char* nhtiles[] = {\n");
+    Fprintf(fp, "\"%lu %lu %lu %d\",\n",
+		header.tile_width*header.per_row,
+		(header.tile_height*header.ntiles)/header.per_row,
 		header.ncolors,
 		1 /* char per color */);
     for (i = 0; i < header.ncolors; i++)
-	fprintf(fp, "\"%c  c #%02x%02x%02x\",\n",
+	Fprintf(fp, "\"%c  c #%02x%02x%02x\",\n",
 		i+'0', /* just one char per color */
 		x11_colormap[i][0],
 		x11_colormap[i][1],
 		x11_colormap[i][2]);
 
-    n=0;
-    for (i = 0; i < header.tile_height*header.ntiles; i++) {
-	fprintf(fp, "\"");
-	for (j = 0; j < header.tile_width; j++) {
+    n = 0;
+    for (i = 0; i < (header.tile_height*header.ntiles)/header.per_row; i++) {
+	Fprintf(fp, "\"");
+	for (j = 0; j < header.tile_width*header.per_row; j++) {
 	    /* just one char per color */
 	    fputc(tile_bytes[n++]+'0', fp);
 	}
-	if (j==header.tile_width-1)
-	    fprintf(fp, "\"\n");
-	else
-	    fprintf(fp, "\",\n");
+
+	Fprintf(fp, "\",\n");
     }
 
-    return fprintf(fp, "};\n")>=0;
+    return fprintf(fp, "};\n") >= 0;
 }
 #endif	/* USE_XPM */
 
@@ -169,11 +176,12 @@
     FILE *fp;
     int i;
 
-    header.version	= 1;
+    header.version	= 2;		/* version 1 had no per_row field */
     header.ncolors	= 0;
     header.tile_width	= TILE_X;
     header.tile_height	= TILE_Y;
     header.ntiles	= 0;		/* updated as we read in files */
+    header.per_row	= TILES_PER_ROW;
 
     if (argc == 1) {
 	Fprintf(stderr, "usage: %s txt_file1 [txt_file2 ...]\n", argv[0]);
@@ -184,12 +192,20 @@
     if (!fp) {
 	Fprintf(stderr, "can't open output file\n");
 	exit(1);
-	}
+    }
+
+    /* don't leave garbage at end of partial row */
+    (void) memset((genericptr_t)tile_bytes, 0, sizeof(tile_bytes));
 
     for (i = 1; i < argc; i++)
 	process_file(argv[i]);
     Fprintf(stderr, "Total tiles: %ld\n", header.ntiles);
 
+    /* round size up to the end of the row */
+    if ((header.ntiles % header.per_row) != 0) {
+	header.ntiles += header.per_row - (header.ntiles % header.per_row);
+    }
+
 #ifdef USE_XPM
     if (xpm_write(fp) == 0) {
 	Fprintf(stderr, "can't write XPM file\n");
@@ -199,7 +215,7 @@
     if (fwrite((char *)&header, sizeof(x11_header), 1, fp) == 0) {
 	Fprintf(stderr, "can't open output header\n");
 	exit(1);
-	}
+    }
 
     if (fwrite((char *)x11_colormap, 1, header.ncolors*3, fp) == 0) {
 	Fprintf(stderr, "can't write output colormap\n");
diff -Naurd ../nethack-3.3.1/win/X11/Window.c ./win/X11/Window.c
--- ../nethack-3.3.1/win/X11/Window.c Fri Aug 6 04:56:25 1999
+++ ./win/X11/Window.c Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)Window.c	3.3	93/02/02	*/
+/*	SCCS Id: @(#)Window.c	3.4	1993/02/02	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
diff -Naurd ../nethack-3.3.1/win/X11/winmap.c ./win/X11/winmap.c
--- ../nethack-3.3.1/win/X11/winmap.c Sat Jul 22 01:59:19 2000
+++ ./win/X11/winmap.c Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)winmap.c	3.3	96/04/05	*/
+/*	SCCS Id: @(#)winmap.c	3.4	1996/04/05	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -100,75 +100,16 @@
 
     } else {
 	uchar			ch;
-	register int		offset;
 	register unsigned char *ch_ptr;
+	int			color,och;
+	unsigned		special;
 #ifdef TEXTCOLOR
-	int			color;
 	register unsigned char *co_ptr;
-
-#define zap_color(n)  color = zapcolors[n]
-#define cmap_color(n) color = defsyms[n].color
-#define obj_color(n)  color = objects[n].oc_color
-#define mon_color(n)  color = mons[n].mcolor
-#define invis_color(n) color = NO_COLOR
-#define pet_color(n)  color = mons[n].mcolor
-#define warn_color(n) color = iflags.use_color ? def_warnsyms[n].color : NO_COLOR
-# else /* no text color */
-
-#define zap_color(n)
-#define cmap_color(n)
-#define obj_color(n)
-#define mon_color(n)
-#define invis_color(n)
-#define pet_color(n)
-#define warn_color(n)
-
 #endif
-
-	/*
-	 *  Map the glyph back to a character.
-	 *
-	 *  Warning:  For speed, this makes an assumption on the order of
-	 *            offsets.  The order is set in display.h.
-	 */
-	if ((offset = (glyph - GLYPH_WARNING_OFF)) >= 0) { 	/* a warning flash */
-		ch = warnsyms[offset];
-		warn_color(offset);
-	} else if ((offset = (glyph - GLYPH_SWALLOW_OFF)) >= 0) {	/* swallow */
-	    /* see swallow_to_glyph() in display.c */
-	    ch = (uchar) showsyms[S_sw_tl + (offset & 0x7)];
-	    mon_color(offset >> 3);
-	} else if ((offset = (glyph - GLYPH_ZAP_OFF)) >= 0) {	/* zap beam */
-	    /* see zapdir_to_glyph() in display.c */
-	    ch = showsyms[S_vbeam + (offset & 0x3)];
-	    zap_color((offset >> 2));
-	} else if ((offset = (glyph - GLYPH_CMAP_OFF)) >= 0) {	/* cmap */
-	    ch = showsyms[offset];
-	    cmap_color(offset);
-	} else if ((offset = (glyph - GLYPH_OBJ_OFF)) >= 0) {	/* object */
-	    ch = oc_syms[(int) objects[offset].oc_class];
-	    obj_color(offset);
-	} else if ((offset = (glyph - GLYPH_RIDDEN_OFF)) >= 0) {/* ridden mon */
-	    ch = monsyms[(int) mons[offset].mlet];
-	    mon_color(offset);
-	} else if ((offset = (glyph - GLYPH_BODY_OFF)) >= 0) {	/* a corpse */
-	    ch = oc_syms[(int) objects[CORPSE].oc_class];
-	    mon_color(offset);
-	} else if ((offset = (glyph - GLYPH_DETECT_OFF)) >= 0) {
-	    /* monster detection; should really be inverse */
-	    ch = monsyms[(int) mons[offset].mlet];
-	    mon_color(offset);
-	} else if ((offset = (glyph - GLYPH_INVIS_OFF)) >= 0) {	/* invisible */
-	    ch = DEF_INVISIBLE;
-	    invis_color(offset);
-	} else if ((offset = (glyph - GLYPH_PET_OFF)) >= 0) {	/* a pet */
-	    ch = monsyms[(int) mons[offset].mlet];
-	    pet_color(offset);
-	} else {						/* a monster */
-	    ch = monsyms[(int) mons[glyph].mlet];
-	    mon_color(glyph);
-	}
-
+	/* map glyph to character and color */
+        mapglyph(glyph, &och, &color, &special, x, y);
+	ch = (uchar)och;
+	
 	/* Only update if we need to. */
 	ch_ptr = &map_info->mtype.text_map->text[y][x];
 
@@ -186,12 +127,6 @@
 	    update_bbox = TRUE;
 	} else
 	    update_bbox = FALSE;
-
-#undef zap_color
-#undef cmap_color
-#undef obj_color
-#undef mon_color
-#undef pet_color
     }
 
     if (update_bbox) {		/* update row bbox */
@@ -271,11 +206,11 @@
     Display *dpy = XtDisplay(toplevel);
     unsigned int width, height;
 
-    height = tile_height * tile_count;
-    width  = tile_width;
-
     if (tile_image == 0) return;	/* no tiles */
 
+    height = tile_image->height;
+    width  = tile_image->width;
+
     tile_pixmap = XCreatePixmap(dpy, XtWindow(toplevel),
 			width,
     			height,
@@ -304,7 +239,10 @@
 init_tiles(wp)
     struct xwindow *wp;
 {
-#ifndef USE_XPM
+#ifdef USE_XPM
+    XpmAttributes attributes;
+    int errorcode;
+#else
     FILE *fp = (FILE *)0;
     x11_header header;
     unsigned char *cp, *colormap = (unsigned char *)0;
@@ -313,13 +251,14 @@
     XColor *colors = (XColor *)0;
     int i, x, y;
     int bitmap_pad;
-    unsigned int image_height, image_width;
     int ddepth;
 #endif
+    char buf[BUFSZ];
     Display *dpy = XtDisplay(toplevel);
     Screen *screen = DefaultScreenOfDisplay(dpy);
     struct map_info_t *map_info = (struct map_info_t *)0;
     struct tile_map_info_t *tile_info = (struct tile_map_info_t *)0;
+    unsigned int image_height = 0, image_width = 0;
     boolean result = TRUE;
     XGCValues values;
     XtGCMask mask;
@@ -334,54 +273,63 @@
 				sizeof(struct tile_map_info_t));
 
 #ifdef USE_XPM
-    {
-	char buf[BUFSZ];
-	XpmAttributes attributes;
-	int errorcode;
+    attributes.valuemask = XpmCloseness;
+    attributes.closeness = 25000;
 
-	attributes.valuemask = XpmCloseness;
-	attributes.closeness = 25000;
+    errorcode = XpmReadFileToImage(dpy, appResources.tile_file,
+				   &tile_image, 0, &attributes);
 
-	errorcode=XpmReadFileToImage(dpy,appResources.tile_file,&tile_image,0,&attributes);
+    if (errorcode == XpmColorFailed) {
+	Sprintf(buf, "Insufficient colors available to load %s.",
+		appResources.tile_file);
+	X11_raw_print(buf);
+	X11_raw_print("Try closing other colorful applications and restart.");
+	X11_raw_print("Attempting to load with inferior colors.");
+	attributes.closeness = 50000;
+	errorcode = XpmReadFileToImage(dpy, appResources.tile_file,
+				       &tile_image, 0, &attributes);
+    }
 
+    if (errorcode != XpmSuccess) {
 	if (errorcode == XpmColorFailed) {
-	    Sprintf(buf, "Insufficient colors available to load %s.",appResources.tile_file);
+	    Sprintf(buf, "Insufficient colors available to load %s.",
+		    appResources.tile_file);
+	    X11_raw_print(buf);
+	} else {
+	    Sprintf(buf, "Failed to load %s: %s", appResources.tile_file,
+		    XpmGetErrorString(errorcode));
 	    X11_raw_print(buf);
-	    X11_raw_print("Try closing other colorful applications and restart.");
-	    X11_raw_print("Attempting to load with inferior colors.");
-	    attributes.closeness = 50000;
-	    errorcode=XpmReadFileToImage(dpy,appResources.tile_file,&tile_image,0,&attributes);
 	}
+	result = FALSE;
+	X11_raw_print("Switching to text-based mode.");
+	goto tiledone;
+    }
 
-	if (errorcode!=XpmSuccess) {
-	    if (errorcode == XpmColorFailed) {
-		Sprintf(buf, "Insufficient colors available to load %s.",appResources.tile_file);
-		X11_raw_print(buf);
-	    } else {
-		Sprintf(buf, "Failed to load %s: %s",appResources.tile_file,
-			XpmGetErrorString(errorcode));
-		X11_raw_print(buf);
-	    }
-	    result = FALSE;
-	    X11_raw_print("Switching to text-based mode.");
-	    goto tiledone;
-	}
+    /* assume a fixed number of tiles per row */
+    if (tile_image->width % TILES_PER_ROW != 0) {
+	Sprintf(buf,
+		"%s is not a multiple of %d (number of tiles/row) pixels wide",
+		appResources.tile_file, TILES_PER_ROW);
+	X11_raw_print(buf);
+	XDestroyImage(tile_image);
+	tile_image = 0;
+	result = FALSE;
+	goto tiledone;
+    }
 
-	if (tile_image->height%total_tiles_used != 0) {
-	    Sprintf(buf,
-		"%s is not a multiple of %d (the number of tiles) pixels high",
-		appResources.tile_file, total_tiles_used);
-	    X11_raw_print(buf);
-	    XDestroyImage(tile_image);
-	    tile_image = 0;
-	    result = FALSE;
-	    goto tiledone;
-	}
+    /* infer tile dimensions from image size, assume square tiles */
+    image_width = tile_image->width;
+    image_height = tile_image->height;
+    tile_width = image_width / TILES_PER_ROW;
+    tile_height = tile_width;
+    tile_count = (image_width * image_height) / (tile_width * tile_height);
 
-	/* infer tile dimensions from image size */
-	tile_count=total_tiles_used;
-	tile_width=tile_image->width;
-	tile_height=tile_image->height/tile_count;
+    if (tile_count < total_tiles_used) {
+	Sprintf(buf, "%s incomplete, expecting %d tiles, found %d",
+		appResources.tile_file, total_tiles_used, tile_count);
+	X11_raw_print(buf);
+	result = FALSE;
+	goto tiledone;
     }
 #else
     /* any less than 16 colours makes tiles useless */
@@ -405,12 +353,21 @@
 	goto tiledone;
     }
 
+    if (header.version != 2) {
+	Sprintf(buf, "Wrong tile file version, expected 2, got %lu",
+		header.version);
+	X11_raw_print(buf);
+	result = FALSE;
+	goto tiledone;
+    }
+
 # ifdef VERBOSE
-    fprintf(stderr, "X11 tile file:\n    version %ld\n    ncolors %ld\n    tile width %ld\n    tile height %ld\n    ntiles %ld\n",
+    fprintf(stderr, "X11 tile file:\n    version %ld\n    ncolors %ld\n    tile width %ld\n    tile height %ld\n    per row %ld\n    ntiles %ld\n",
 	header.version,
 	header.ncolors,
 	header.tile_width,
 	header.tile_height,
+	header.per_row,
 	header.ntiles);
 # endif
 
@@ -439,9 +396,8 @@
 	if (!XAllocColor(dpy, DefaultColormapOfScreen(screen), &colors[i]) &&
 	    !nhApproxColor(screen, DefaultColormapOfScreen(screen),
 			   (char *)0, &colors[i])) {
-	    char buf[BUFSZ];
 	    Sprintf(buf, "%dth out of %ld color allocation failed",
-		i, header.ncolors);
+		    i, header.ncolors);
 	    X11_raw_print(buf);
 	    result = FALSE;
 	    goto tiledone;
@@ -453,8 +409,11 @@
      * This alloc() and the one below require 32-bit ints, since tile_bytes
      * is currently ~200k and alloc() takes an int
      */
-    tile_bytes = (unsigned char *) alloc((unsigned)header.ntiles*size);
     tile_count = header.ntiles;
+    if ((tile_count % header.per_row) != 0) {
+	tile_count += header.per_row - (tile_count % header.per_row);
+    }
+    tile_bytes = (unsigned char *) alloc((unsigned)tile_count*size);
     if (fread((char *) tile_bytes, size, tile_count, fp) != tile_count) {
 	X11_raw_print("read of tile bytes failed");
 	result = FALSE;
@@ -462,7 +421,6 @@
     }
 
     if (header.ntiles < total_tiles_used) {
-	char buf[BUFSZ];
 	Sprintf(buf, "tile file incomplete, expecting %d tiles, found %lu",
 		total_tiles_used, header.ntiles);
 	X11_raw_print(buf);
@@ -479,8 +437,8 @@
 	tile_height = header.tile_height;
     }
 
-    image_height = tile_height * tile_count;
-    image_width  = tile_width;
+    image_height = tile_height * tile_count / header.per_row;
+    image_width  = tile_width * header.per_row;
 
     /* calculate bitmap_pad */
     if (ddepth > 16)
@@ -509,19 +467,19 @@
 
     if (appResources.double_tile_size) {
 	unsigned long *expanded_row =
-	    (unsigned long *)alloc(sizeof(unsigned long)*(unsigned)tile_width);
+	    (unsigned long *)alloc(sizeof(unsigned long)*(unsigned)image_width);
 
 	tb = tile_bytes;
 	for (y = 0; y < image_height; y++) {
-	    for (x = 0; x < header.tile_width; x++)
+	    for (x = 0; x < image_width/2; x++)
 		expanded_row[2*x] =
 			    expanded_row[(2*x)+1] = colors[*tb++].pixel;
 
-	    for (x = 0; x < tile_width; x++)
+	    for (x = 0; x < image_width; x++)
 		XPutPixel(tile_image, x, y, expanded_row[x]);
 
 	    y++;	/* duplicate row */
-	    for (x = 0; x < tile_width; x++)
+	    for (x = 0; x < image_width; x++)
 		XPutPixel(tile_image, x, y, expanded_row[x]);
 	}
 	free((genericptr_t)expanded_row);
@@ -554,12 +512,8 @@
      */
     mask = GCFunction | GCForeground | GCGraphicsExposures;
     values.graphics_exposures = False;
-#if 1
     values.foreground = WhitePixelOfScreen(screen) ^
 	XGetPixel(tile_image, 0, tile_height*glyph2tile[cmap_to_glyph(S_corr)]);
-#else
-    values.foreground = ~((unsigned long) 0);
-#endif
     values.function = GXxor;
     tile_info->white_gc = XtGetGC(wp->w, mask, &values);
 
@@ -567,7 +521,7 @@
     values.function = GXCopy;
     values.graphics_exposures = False;
     tile_info->black_gc = XtGetGC(wp->w, mask, &values);
-#endif
+#endif /* USE_WHITE */
 
 tiledone:
 #ifndef USE_XPM
@@ -582,6 +536,8 @@
 	map_info->square_width = tile_width;
 	map_info->square_ascent = 0;
 	map_info->square_lbearing = 0;
+	tile_info->image_width = image_width;
+	tile_info->image_height = image_height;
     } else {
 	if (tile_info) free((genericptr_t)tile_info);
 	tile_info = 0;
@@ -623,7 +579,9 @@
 	XtSetArg(arg[1], XtNtopOfThumb, &top);
 	XtGetValues(horiz_sb, arg, TWO);
 
-	cursor_middle = (((float) wp->cursx) + 0.5) / (float) COLNO;
+	/* [ALI] Don't assume map widget is the same size as actual map */
+	cursor_middle = (wp->cursx + 0.5) * wp->map_information->square_width /
+	  wp->pixel_width;
 	do_call = True;
 
 #ifdef VERBOSE
@@ -669,7 +627,8 @@
 	XtSetArg(arg[1], XtNtopOfThumb, &top);
 	XtGetValues(vert_sb, arg, TWO);
 
-	cursor_middle = (((float) wp->cursy) + 0.5) / (float) ROWNO;
+	cursor_middle = (wp->cursy + 0.5) * wp->map_information->square_height /
+	  wp->pixel_height;
 	do_call = True;
 
 #ifdef VERBOSE
@@ -743,11 +702,30 @@
     /* Only do cursor check if new size is smaller. */
     if (new_width < map_info->viewport_width
 		    || new_height < map_info->viewport_height) {
+	/* [ALI] If the viewport was larger than the map (and so the map
+	 * widget was contrained to be larger than the actual map) then we
+	 * may be able to shrink the map widget as the viewport shrinks.
+	 */
+	wp->pixel_width = map_info->square_width * COLNO;
+	if (wp->pixel_width < new_width)
+	    wp->pixel_width = new_width;
+	wp->pixel_height = map_info->square_height * ROWNO;
+	if (wp->pixel_height < new_height)
+	    wp->pixel_height = new_height;
+	XtSetArg(arg[0], XtNwidth, wp->pixel_width);
+	XtSetArg(arg[1], XtNheight, wp->pixel_height);
+	XtSetValues(wp->w, arg, TWO);
+
 	check_cursor_visibility(wp);
     }
 
     map_info->viewport_width = new_width;
     map_info->viewport_height = new_height;
+
+    /* [ALI] These may have changed if the user has re-sized the viewport */
+    XtSetArg(arg[0], XtNwidth, &wp->pixel_width);
+    XtSetArg(arg[1], XtNheight, &wp->pixel_height);
+    XtGetValues(wp->w, arg, TWO);
 }
 
 /*
@@ -948,7 +926,7 @@
 
 #ifdef VERBOSE
     printf("Font information:\n");
-    printf("fid = %d, direction = %d\n", fs->fid, fs->direction);
+    printf("fid = %ld, direction = %d\n", fs->fid, fs->direction);
     printf("first = %d, last = %d\n",
 			fs->min_char_or_byte2, fs->max_char_or_byte2);
     printf("all chars exist? %s\n", fs->all_chars_exist?"yes":"no");
@@ -960,7 +938,7 @@
 		fs->max_bounds.lbearing, fs->max_bounds.rbearing,
 		fs->max_bounds.width, fs->max_bounds.ascent,
 		fs->max_bounds.descent, fs->max_bounds.attributes);
-    printf("per_char = 0x%x\n", fs->per_char);
+    printf("per_char = 0x%lx\n", (unsigned long) fs->per_char);
     printf("Text: (max) width = %d, height = %d\n",
 	    map_info->square_width, map_info->square_height);
 #endif
@@ -1217,28 +1195,26 @@
     if (map_info->is_tile) {
 	struct tile_map_info_t *tile_map = map_info->mtype.tile_map;
 	int cur_col;
-	Display* dpy=XtDisplay(wp->w);
-	Screen* screen=DefaultScreenOfDisplay(dpy);
+	Display* dpy = XtDisplay(wp->w);
+	Screen* screen = DefaultScreenOfDisplay(dpy);
 
 	for (row = start_row; row <= stop_row; row++) {
 	    for (cur_col = start_col; cur_col <= stop_col; cur_col++) {
 		int glyph = tile_map->glyphs[row][cur_col];
 		int tile = glyph2tile[glyph];
+		int src_x, src_y;
 		int dest_x = cur_col * map_info->square_width;
 		int dest_y = row * map_info->square_height;
 
+		src_x = (tile % TILES_PER_ROW) * tile_width;
+		src_y = (tile / TILES_PER_ROW) * tile_height;
 		XCopyArea(dpy, tile_pixmap, XtWindow(wp->w),
-			tile_map->black_gc,	/* no grapics_expose */
-			0,
-			tile * map_info->square_height,
-			tile_width, tile_height,
-			dest_x,dest_y);
+			  tile_map->black_gc,	/* no grapics_expose */
+			  src_x, src_y,
+			  tile_width, tile_height,
+			  dest_x, dest_y);
 
-		if (glyph_is_pet(glyph)
-#ifdef TEXTCOLOR
-			&& iflags.hilite_pet
-#endif
-			) {
+		if (glyph_is_pet(glyph) && iflags.hilite_pet) {
 		    /* draw pet annotation (a heart) */
 		    XSetForeground(dpy, tile_map->black_gc, pet_annotation.foreground);
 		    XSetClipOrigin(dpy, tile_map->black_gc, dest_x, dest_y);
diff -Naurd ../nethack-3.3.1/win/X11/winmenu.c ./win/X11/winmenu.c
--- ../nethack-3.3.1/win/X11/winmenu.c Mon May 8 21:43:42 2000
+++ ./win/X11/winmenu.c Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)winmenu.c	3.3	96/08/15	*/
+/*	SCCS Id: @(#)winmenu.c	3.4	1996/08/15	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
diff -Naurd ../nethack-3.3.1/win/X11/winmesg.c ./win/X11/winmesg.c
--- ../nethack-3.3.1/win/X11/winmesg.c Fri Aug 6 04:56:26 1999
+++ ./win/X11/winmesg.c Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)winmesg.c	3.3	96/04/05	*/
+/*	SCCS Id: @(#)winmesg.c	3.4	1996/04/05	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
diff -Naurd ../nethack-3.3.1/win/X11/winmisc.c ./win/X11/winmisc.c
--- ../nethack-3.3.1/win/X11/winmisc.c Mon May 22 18:31:44 2000
+++ ./win/X11/winmisc.c Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)winmisc.c	3.3	2000/05/21	*/
+/*	SCCS Id: @(#)winmisc.c	3.4	2000/05/21	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -265,15 +265,21 @@
 	i, availcount, availindex;
     Widget popup, player_form;
     const char **choices;
-    const char *namep;
-    char qbuf[QBUFSZ];
+    char qbuf[QBUFSZ], plbuf[QBUFSZ];
+
+    /* avoid unnecessary prompts further down */
+    rigid_role_checks();
+
+    (void)  root_plselection_prompt(plbuf, QBUFSZ - 1,
+			flags.initrole, flags.initrace, flags.initgend, flags.initalign);
 
     while (flags.initrole < 0) {
-	if (flags.initrole == ROLE_RANDOM) {
+	if (flags.initrole == ROLE_RANDOM || flags.randomall) {
 	    flags.initrole = pick_role(flags.initrace,
-				       flags.initgend, flags.initalign);
+				       flags.initgend, flags.initalign, PICK_RANDOM);
 	    break;
 	}
+
 	/* select a role */
 	for (num_roles = 0; roles[num_roles].name.m; ++num_roles) continue;
 	choices = (const char **)alloc(sizeof(char *) * num_roles);
@@ -295,7 +301,8 @@
 	    else if (flags.initrace >= 0) flags.initrace = -1;
 	    else panic("no available ROLE+race+gender+alignment combinations");
 	}
-	popup = make_menu("player_selection", "Choose a Role",
+	Sprintf(qbuf, "Choose your %s Role", s_suffix(plbuf));
+	popup = make_menu("player_selection", qbuf,
 		    player_select_translations,
 		    "quit", ps_quit,
 		    "random", ps_random,
@@ -325,10 +332,13 @@
 	}
     }
 
+    (void)  root_plselection_prompt(plbuf, QBUFSZ - 1,
+			flags.initrole, flags.initrace, flags.initgend, flags.initalign);
+
     while (!validrace(flags.initrole, flags.initrace)) {
-	if (flags.initrace == ROLE_RANDOM) {
+	if (flags.initrace == ROLE_RANDOM || flags.randomall) {
 	    flags.initrace = pick_race(flags.initrole,
-				       flags.initgend, flags.initalign);
+				       flags.initgend, flags.initalign, PICK_RANDOM);
 	    break;
 	}
 	/* select a race */
@@ -355,11 +365,7 @@
 	    flags.initrace = availindex;
 	    free((genericptr_t)choices), choices = 0;
 	} else {
-	    namep = roles[flags.initrole].name.m;
-	    if (flags.initgend >= 0 && flags.female &&
-		    roles[flags.initrole].name.f)
-		namep = roles[flags.initrole].name.f;
-	    Sprintf(qbuf, "Pick your %s race", s_suffix(namep));
+	    Sprintf(qbuf, "Pick your %s race", s_suffix(plbuf));
 	    popup = make_menu("race_selection", qbuf,
 			race_select_translations,
 			"quit", ps_quit,
@@ -392,10 +398,13 @@
 	} /* more than one race choice available */
     }
 
+    (void)  root_plselection_prompt(plbuf, QBUFSZ - 1,
+			flags.initrole, flags.initrace, flags.initgend, flags.initalign);
+
     while (!validgend(flags.initrole, flags.initrace, flags.initgend)) {
-	if (flags.initgend == ROLE_RANDOM) {
+	if (flags.initgend == ROLE_RANDOM || flags.randomall) {
 	    flags.initgend = pick_gend(flags.initrole, flags.initrace,
-				       flags.initalign);
+				       flags.initalign, PICK_RANDOM);
 	    break;
 	}
 	/* select a gender */
@@ -421,12 +430,7 @@
 	    flags.initgend = availindex;
 	    free((genericptr_t)choices), choices = 0;
 	} else {
-	    namep = roles[flags.initrole].name.m;
-	    if (flags.initgend >= 0 && flags.female &&
-		    roles[flags.initrole].name.f)
-		namep = roles[flags.initrole].name.f;
-	    Sprintf(qbuf, "Your %s %s gender?",
-		    races[flags.initrace].adj, s_suffix(namep));
+	    Sprintf(qbuf, "Your %s gender?", s_suffix(plbuf));
 	    popup = make_menu("gender_selection", qbuf,
 			gend_select_translations,
 			"quit", ps_quit,
@@ -459,10 +463,13 @@
 	} /* more than one gender choice available */
     }
 
+    (void)  root_plselection_prompt(plbuf, QBUFSZ - 1,
+			flags.initrole, flags.initrace, flags.initgend, flags.initalign);
+
     while (!validalign(flags.initrole, flags.initrace, flags.initalign)) {
-	if (flags.initalign == ROLE_RANDOM) {
+	if (flags.initalign == ROLE_RANDOM || flags.randomall) {
 	    flags.initalign = pick_align(flags.initrole, flags.initrace,
-					 flags.initgend);
+					 flags.initgend, PICK_RANDOM);
 	    break;
 	}
 	/* select an alignment */
@@ -487,14 +494,7 @@
 	    flags.initalign = availindex;
 	    free((genericptr_t)choices), choices = 0;
 	} else {
-	    namep = roles[flags.initrole].name.m;
-	    if (flags.initgend >= 0 && flags.female &&
-		    roles[flags.initrole].name.f)
-		namep = roles[flags.initrole].name.f;
-	    Sprintf(qbuf, "%s %s %s alignment?",
-		    genders[flags.initgend].adj,
-		    races[flags.initrace].adj, s_suffix(namep));
-	    qbuf[0] = highc(qbuf[0]);
+	    Sprintf(qbuf, "Your %s alignment?", s_suffix(plbuf));
 	    popup = make_menu("alignment_selection", qbuf,
 			algn_select_translations,
 			"quit", ps_quit,
diff -Naurd ../nethack-3.3.1/win/X11/winstat.c ./win/X11/winstat.c
--- ../nethack-3.3.1/win/X11/winstat.c Tue May 2 03:08:09 2000
+++ ./win/X11/winstat.c Fri Mar 22 14:41:14 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)winstat.c	3.3	96/04/05	*/
+/*	SCCS Id: @(#)winstat.c	3.4	1996/04/05	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -111,9 +111,7 @@
     XtSetArg(args[num_args], XtNrightMargin,  &right_margin);  num_args++;
     XtGetValues(wp->w, args, num_args);
 
-    /* font height is ascent + descent */
-    wp->pixel_height = 2 * (fs->ascent + fs->descent) +
-						top_margin + bottom_margin;
+    wp->pixel_height = 2 * nhFontHeight(wp->w) + top_margin + bottom_margin;
     wp->pixel_width  = COLNO * fs->max_bounds.width +
 						left_margin + right_margin;
 
diff -Naurd ../nethack-3.3.1/win/X11/wintext.c ./win/X11/wintext.c
--- ../nethack-3.3.1/win/X11/wintext.c Wed May 10 02:03:37 2000
+++ ./win/X11/wintext.c Fri Mar 22 14:41:14 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)wintext.c	3.3	96/04/05	*/
+/*	SCCS Id: @(#)wintext.c	3.4	1996/04/05	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -156,13 +156,14 @@
     struct text_info_t *text_info;
     Arg args[8];
     Cardinal num_args;
-    Dimension width, height;
+    Dimension width, height, font_height;
     int nlines;
 
     text_info = wp->text_information;
     width  = text_info->max_width + text_info->extra_width;
     text_info->blocked = blocking;
     text_info->destroy_on_ack = FALSE;
+    font_height = nhFontHeight(wp->w);
 
     /*
      * Calculate the number of lines to use.  First, find the number of
@@ -172,17 +173,14 @@
      * _some_ lines.  Finally, use the number of lines in the text if
      * there are fewer than the max.
      */
-    nlines = (XtScreen(wp->w)->height - text_info->extra_height) /
-			(text_info->fs->ascent + text_info->fs->descent);
+    nlines = (XtScreen(wp->w)->height - text_info->extra_height) / font_height;
     nlines -= 4;
 
     if (nlines > text_info->text.num_lines)
 	nlines = text_info->text.num_lines;
     if (nlines <= 0) nlines = 1;
 
-    /* Font height is ascent + descent. */
-    height = (nlines * (text_info->fs->ascent + text_info->fs->descent))
-						    + text_info->extra_height;
+    height = nlines * font_height + text_info->extra_height;
 
     num_args = 0;
 
@@ -469,8 +467,8 @@
 	Sprintf(rip_line[NAME_LINE], "%s", plname);
 
 	/* Put $ on stone */
-	Sprintf(rip_line[GOLD_LINE], "%ld Au", u.ugold);
-
+	Sprintf(rip_line[GOLD_LINE], "%ld Au",
+		u.ugold);
 	/* Put together death description */
 	switch (killer_format) {
 		default: impossible("bad killer format?");
diff -Naurd ../nethack-3.3.1/win/X11/winval.c ./win/X11/winval.c
--- ../nethack-3.3.1/win/X11/winval.c Fri Aug 6 04:56:26 1999
+++ ./win/X11/winval.c Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)winval.c	3.3	92/3/7	*/
+/*	SCCS Id: @(#)winval.c	3.4	1992/3/7	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
diff -Naurd ../nethack-3.3.1/win/X11/winX.c ./win/X11/winX.c
--- ../nethack-3.3.1/win/X11/winX.c Sun Jan 30 19:24:47 2000
+++ ./win/X11/winX.c Fri Mar 22 14:40:55 2002
@@ -1,4 +1,4 @@
-/*	SCCS Id: @(#)winX.c	3.3	1999/12/21	*/
+/*	SCCS Id: @(#)winX.c	3.4	1999/12/21	*/
 /* Copyright (c) Dean Luick, 1992				  */
 /* NetHack may be freely redistributed.  See license for details. */
 
@@ -92,6 +92,7 @@
 /* Interface definition, for windows.c */
 struct window_procs X11_procs = {
     "X11",
+    WC_COLOR|WC_HILITE_PET,
     X11_init_nhwindows,
     X11_player_selection,
     X11_askname,
@@ -144,6 +145,7 @@
 #else
     genl_outrip,
 #endif
+    genl_preference_update,
 };
 
 /*
@@ -265,7 +267,7 @@
     long	cdiff = 16777216; /* 2^24; hopefully our map is smaller */
     XColor	tmp;
     static	XColor *table = 0;
-    register	i, j;
+    register int i, j;
     register long tdiff;
 
     /* if the screen doesn't have a big colormap, don't waste our time */
@@ -450,6 +452,38 @@
     }
 }
 
+/* [ALI] Utility function to ask Xaw for font height, since the previous
+ * assumption of ascent + descent is not always valid.
+ */
+Dimension
+nhFontHeight(w)
+Widget w;
+#ifdef _XawTextSink_h
+{
+    Widget sink;
+    XawTextPosition pos = 0;
+    int resWidth, resHeight;
+    Arg args[1];
+
+    XtSetArg(args[0], XtNtextSink, &sink);
+    XtGetValues(w, args, 1);
+
+    XawTextSinkFindPosition(sink, pos, 0, 0, 0, &pos, &resWidth, &resHeight);
+    return resHeight;
+}
+#else
+{
+    XFontStruct *fs;
+    Arg args[1];
+
+    XtSetArg(args[0], XtNfont, &fs);
+    XtGetValues(w, args, 1);
+
+    /* Assume font height is ascent + descent. */
+    return = fs->ascent + fs->descent;
+}
+#endif
+
 /* Global Functions ======================================================== */
 void
 X11_raw_print(str)
@@ -870,7 +904,7 @@
 
 static XtResource resources[] = {
     { "slow", "Slow", XtRBoolean, sizeof(Boolean),
-      XtOffset(AppResources *,slow), XtRString, "False" },
+      XtOffset(AppResources *,slow), XtRString, "True" },
     { "autofocus", "AutoFocus", XtRBoolean, sizeof(Boolean),
       XtOffset(AppResources *,autofocus), XtRString, "False" },
     { "message_line", "Message_line", XtRBoolean, sizeof(Boolean),
@@ -1178,12 +1212,20 @@
     XtPointer client_data;
     XtPointer call_data;
 {
+    int len;
     char *s;
     Widget dialog = (Widget) client_data;
 
     s = (char *) GetDialogResponse(dialog);
-    Strcpy(getline_input, s);
+    len = strlen(s);
+
+    /* Truncate input if necessary */
+    if (len >= BUFSZ) len = BUFSZ - 1;
+
+    (void) strncpy(getline_input, s, len);
+    getline_input[len] = '\0';
     XtFree(s);
+
     nh_XtPopdown(XtParent(dialog));
     exit_x_event = TRUE;
 }
@@ -1389,12 +1431,10 @@
     XtGetValues(dispfile, args, num_args);
 
     /*
-     * Font height is ascent + descent.
-     *
      * The data files are currently set up assuming an 80 char wide window
      * and a fixed width font.  Soo..
      */
-    new_height = num_lines * (fs->ascent + fs->descent) +
+    new_height = num_lines * nhFontHeight(dispfile) +
 						top_margin + bottom_margin;
     new_width  = 80 * fs->max_bounds.width + left_margin + right_margin;
 

