From 8e7fe38daec1ad5231f3c3d3bc82b7f827782d80 Mon Sep 17 00:00:00 2001 From: PatR Date: Tue, 12 Mar 2019 13:31:00 -0700 Subject: [PATCH] avoid crash for X11 tombstone If nethack is built to use graphical tombstone but file rip.xpm is missing from the playground, there would be a crash if the rip output was shown. My first attempt to fix it prevented the crash but didn't display any tombstone, just the last couple of lines of output which follow the tombstone. This keeps that in case of some other Xpm failure, but checks for rip.xpm via stdio and reverts to genl_outrip for text tombstone if it can't be opened. --- doc/fixes36.2 | 4 +++- win/X11/winX.c | 12 +++++++++++- win/X11/wintext.c | 28 ++++++++++++++++------------ 3 files changed, 30 insertions(+), 14 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 480df2705..f293fec72 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.271 $ $NHDT-Date: 1552254771 2019/03/10 21:52:51 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.272 $ $NHDT-Date: 1552422652 2019/03/12 20:30:52 $ This fixes36.2 file is here to capture information about updates in the 3.6.x lineage following the release of 3.6.1 in April 2018. Please note, however, @@ -566,6 +566,8 @@ X11: text popups on OSX wouldn't accept keyboard input unless the 'autofocus' resource was enabled; most noticeable when trying to dismiss 'things that are here' while walking over object piles X11: default to using XPM format tile file and rip screen +X11: when showing graphical tombstone, would crash if file rip.xpm is missing; + revert to text tombstone instead General New Features diff --git a/win/X11/winX.c b/win/X11/winX.c index 654e997e4..958625a0d 100644 --- a/win/X11/winX.c +++ b/win/X11/winX.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 winX.c $NHDT-Date: 1546081304 2018/12/29 11:01:44 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.71 $ */ +/* NetHack 3.6 winX.c $NHDT-Date: 1552422652 2019/03/12 20:30:52 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.72 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -1355,10 +1355,20 @@ int how; time_t when; { struct xwindow *wp; + FILE *rip_fp; check_winid(window); wp = &window_list[window]; + /* make sure the graphic_tombstone is available; it's not easy to + revert to ordinary text tombstone once we're past this point... */ + rip_fp = fopen(appResources.tombstone, "r"); /* "rip.xpm" */ + if (!rip_fp) { + genl_outrip(window, how, when); + return; + } + (void) fclose(rip_fp); + if (wp->type == NHW_TEXT) { wp->text_information->is_rip = TRUE; } else { diff --git a/win/X11/wintext.c b/win/X11/wintext.c index 122ef8e02..61615447c 100644 --- a/win/X11/wintext.c +++ b/win/X11/wintext.c @@ -1,4 +1,4 @@ -/* NetHack 3.6 wintext.c $NHDT-Date: 1546081305 2018/12/29 11:01:45 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.17 $ */ +/* NetHack 3.6 wintext.c $NHDT-Date: 1552422654 2019/03/12 20:30:54 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.18 $ */ /* Copyright (c) Dean Luick, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -181,8 +181,7 @@ boolean blocking; * _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) / font_height; + nlines = (XtScreen(wp->w)->height - text_info->extra_height) / font_height; nlines -= 4; if (nlines > text_info->text.num_lines) @@ -204,13 +203,16 @@ boolean blocking; #ifdef GRAPHIC_TOMBSTONE if (text_info->is_rip) { Widget rip = create_ripout_widget(XtParent(wp->w)); - XtSetArg(args[num_args], nhStr(XtNfromVert), rip); - num_args++; + + if (rip) { + XtSetArg(args[num_args], nhStr(XtNfromVert), rip); + num_args++; + } else + text_info->is_rip = FALSE; } #endif - if (width - > (Dimension) XtScreen(wp->w)->width) { /* too wide for screen */ + if (width > (Dimension) XtScreen(wp->w)->width) { /* too wide for screen */ /* Back off some amount - we really need to back off the scrollbar */ /* width plus some extra. */ width = XtScreen(wp->w)->width - 20; @@ -420,8 +422,7 @@ boolean concat; if (str) { (void) memcpy((tb->text + tb->text_last), str, length + 1); if (length) { - /* Remove all newlines. Otherwise we have a confused line count. - */ + /* Remove all newlines. Otherwise we have a confused line count. */ copy = (tb->text + tb->text_last); while ((copy = index(copy, '\n')) != (char *) 0) *copy = ' '; @@ -577,6 +578,7 @@ XtPointer widget_data; /* expose event from Window widget */ int len = strlen(rip_line[i]); XFontStruct *font = WindowFontStruct(w); int width = XTextWidth(font, rip_line[i], len); + XDrawString(dpy, XtWindow(w), gc, x - width / 2, y, rip_line[i], len); x += appResources.tombtext_dx; y += appResources.tombtext_dy; @@ -603,14 +605,16 @@ create_ripout_widget(Widget parent) attributes.valuemask = XpmCloseness; attributes.closeness = 65535; /* Try anything */ - errorcode = - XpmReadFileToImage(XtDisplay(parent), appResources.tombstone, - &rip_image, 0, &attributes); + errorcode = XpmReadFileToImage(XtDisplay(parent), + appResources.tombstone, + &rip_image, 0, &attributes); if (errorcode != XpmSuccess) { char buf[BUFSZ]; + Sprintf(buf, "Failed to load %s: %s", appResources.tombstone, XpmGetErrorString(errorcode)); X11_raw_print(buf); + return (Widget) 0; } rip_width = rip_image->width; rip_height = rip_image->height; -- 2.40.0