From e5fea0291ecc772506e1aaf1c647245390eb509f Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 4 Apr 2019 13:52:14 -0700 Subject: [PATCH 1/4] curses prompting Make the same fix to curses that was done for tty in 3.6.1: don't let MSGTYPE entries be matched against prompt strings. Like tty, curses was using ordinary pline() to issue prompts; something like MSGTYPE=hide"yn" could wreak havoc. Switch to custompline(OVERRIDE_MSGTYPE,...). --- doc/fixes36.2 | 3 ++- win/curses/cursdial.c | 8 +++++--- 2 files changed, 7 insertions(+), 4 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index ea7eab82d..788d819bf 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.296 $ $NHDT-Date: 1554136021 2019/04/01 16:27:01 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.297 $ $NHDT-Date: 1554411130 2019/04/04 20:52:10 $ 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, @@ -535,6 +535,7 @@ curses: highlighting of status conditions was broken by the fix for timing out curses: if player pressed ESC at More>> prompt to suppress remaining messages for the current move and then hero got another move on the same turn, messages and most prompts would stay suppressed during that extra move +curses: don't let MSGTYPE=hide block prompts from being shown vms: add compile of isaac64.c to Makefile.src and vmsbuild.com vms+curses: add compile support but it is known to fail to build diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 8ec5d20b5..062400b93 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -276,7 +276,9 @@ curses_character_input_dialog(const char *prompt, const char *choices, wrefresh(askwin); } else { - pline("%s", askstr); + /* TODO: add SUPPRESS_HISTORY flag, then after getting a response, + append it and use put_msghistory() on combined prompt+answer */ + custompline(OVERRIDE_MSGTYPE, "%s", askstr); curs_set(1); } @@ -348,7 +350,7 @@ curses_character_input_dialog(const char *prompt, const char *choices, /* Kludge to make prompt visible after window is dismissed when inputting a number */ if (digit(answer)) { - pline("%s", askstr); + custompline(OVERRIDE_MSGTYPE, "%s", askstr); curs_set(1); } @@ -403,7 +405,7 @@ curses_ext_cmd() extwin = newwin(1, messagew - 2, winy, winx); if (messagew - 4 < maxlen) maxlen = messagew - 4; - pline("#"); + custompline(OVERRIDE_MSGTYPE, "#"); } cur_choice[0] = '\0'; From e0e937e7b63a45dae1a5e9cf2093ad6a6d830311 Mon Sep 17 00:00:00 2001 From: keni Date: Thu, 4 Apr 2019 17:00:51 -0400 Subject: [PATCH 2/4] Solaris hints files from Kevin Smolkowski --- sys/unix/hints/solaris | 44 ++++++++++++++++++++++++++++ sys/unix/hints/solaris-playground | 48 +++++++++++++++++++++++++++++++ 2 files changed, 92 insertions(+) create mode 100644 sys/unix/hints/solaris create mode 100644 sys/unix/hints/solaris-playground diff --git a/sys/unix/hints/solaris b/sys/unix/hints/solaris new file mode 100644 index 000000000..2140330dd --- /dev/null +++ b/sys/unix/hints/solaris @@ -0,0 +1,44 @@ +# +# NetHack 3.6 unix $NHDT-Date: 1554411633 2019/04/04 21:00:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.0 $ +# Copyright (c) Kevin Smolkowski "Snivik", Elgin Oregon 2019. +# NetHack may be freely redistributed. See license for details. +# +#-PRE +# solaris hints file +# This hints file provides a single-user x11 build for Solaris, specifically +# for Solaris 10 and 11, but should work just fine on older versions + +# Build using using included gcc and gmake, optional flex and bison come from csw for solaris 10 and included +# with Solaris 11 + +# Build NetHack off your home directory +HACKDIR=$(HOME)/nethackdir +INSTDIR=$(HACKDIR) +VARDIR=$(HACKDIR) +SHELLDIR=$(HOME) + +POSTINSTALL= cp sys/unix/sysconf $(INSTDIR)/sysconf; + +CC=gcc +CFLAGS=-O -I../include +LINK=$(CC) + +WINSRC = $(WINTTYSRC) +WINOBJ = $(WINTTYOBJ) +WINLIB = $(WINTTYLIB) + +WINTTYLIB=-ltermlib + +CHOWN=true +CHGRP=true + +GAMEUID = games +GAMEGRP = bin + +GAMEPERM = 04755 +VARFILEPERM = 0644 +VARDIRPERM = 0755 + +# Optional Tools to build level compiler +#LEX=flex +#YACC=bison -y diff --git a/sys/unix/hints/solaris-playground b/sys/unix/hints/solaris-playground new file mode 100644 index 000000000..5e51df6f2 --- /dev/null +++ b/sys/unix/hints/solaris-playground @@ -0,0 +1,48 @@ +# +# NetHack 3.6 unix $NHDT-Date: 1554411633 2019/04/04 21:00:33 $ $NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.0 $ +# Copyright (c) Kevin Smolkowski "Snivik", Elgin Oregon 2019. +# NetHack may be freely redistributed. See license for details. +# +#-PRE +# This hints file provides a shared playground build for Solaris, specifically +# for Solaris 10 and 11, but should work just fine on older versions + +# Nethack will install suid games, and will expect to read a users .nethackrc file from +# their home directory which may be a problem on secure systems with read restricted home +# directories, not that you would problably run NetHack on such a system anyway. :) + +# Build using using included gcc and gmake, optional flex and bison come from csw for solaris 10 +# and included on Solaris 11 + + +PREFIX=/usr +HACKDIR=$(PREFIX)/games/lib/$(GAME)dir +INSTDIR=$(HACKDIR) +VARDIR=$(HACKDIR) +SHELLDIR=$(PREFIX)/games + +POSTINSTALL= cp sys/unix/sysconf $(INSTDIR)/sysconf; $(CHOWN) $(GAMEUID) $(INSTDIR)/sysconf;$(CHGRP) $(GAMEGRP) $(INSTDIR)/sysconf; chmod $(VARFILEPERM) $(INSTDIR)/sysconf; + +CC=gcc +CFLAGS=-O -I../include +LINK=$(CC) + +WINSRC = $(WINTTYSRC) +WINOBJ = $(WINTTYOBJ) +WINLIB = $(WINTTYLIB) + +WINTTYLIB=-ltermlib + +CHOWN=chown +CHGRP=chgrp + +GAMEUID = games +GAMEGRP = bin + +GAMEPERM = 04755 +VARFILEPERM = 0644 +VARDIRPERM = 0755 + +# Optional Tools to build level compiler +#LEX=flex +#YACC=bison -y \ No newline at end of file From 00aa7206f76521abbc08e15050e209b4604c2cfa Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 4 Apr 2019 15:08:56 -0700 Subject: [PATCH 3/4] opthelp bit --- dat/opthelp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dat/opthelp b/dat/opthelp index 560acc463..ee9092ede 100644 --- a/dat/opthelp +++ b/dat/opthelp @@ -17,7 +17,7 @@ cmdassist give help for errors on direction & other commands [TRUE] confirm ask before hitting tame or peaceful monsters [TRUE] dark_room show floor not in sight in different color [TRUE] eight_bit_tty send 8-bit characters straight to terminal [FALSE] -extmenu tty: use a menu for selecting extended commands (#)[FALSE] +extmenu tty, curses: use menu for # (extended commands) [FALSE] X11: menu has all commands (T) or traditional subset (F) fixinv try to retain the same letter for the same object [TRUE] force_invmenu commands asking for inventory item show a menu [FALSE] From 8c4e7927708ec6ebeb2b5ef1b291233d861e9d8c Mon Sep 17 00:00:00 2001 From: PatR Date: Thu, 4 Apr 2019 17:55:40 -0700 Subject: [PATCH 4/4] curses ">>" (terse "--More--") I've noticed many instances of the game pausing and not being sure why, then pressing and having it resume. The curses interface had a tendency to put its equivalent of the --More-- prompt, >>, somewhere where that wasn't visible, either off the right hand edge (possibly) or underneath the window borders if those were enabled. Especially the very last one it issues prior to exit. (An extra one compared to tty behavior.) This ended up being a pretty substantial overhaul of message window handling. I wouldn't be surprised if it has off-by-one errors which happen to be paired up and cancel each other out. ">>" is still drawn in orange if guicolor is on, now in inverse video when that is off. If it happens to be drawn at the same screen location in consecutive instances, the first ">" will toggle between blink and not blink so that there'll be no doubt as to whether the keypress registered when dismissing it (moot if the text preceding it is different but there's no attempt to be smart enough to check that, just screen placement). --- doc/fixes36.2 | 4 +- include/wincurs.h | 1 + win/curses/cursdial.c | 6 +- win/curses/cursmain.c | 4 +- win/curses/cursmesg.c | 192 ++++++++++++++++++++++++++---------------- win/curses/cursmesg.h | 1 + win/curses/cursmisc.c | 3 + 7 files changed, 131 insertions(+), 80 deletions(-) diff --git a/doc/fixes36.2 b/doc/fixes36.2 index 788d819bf..68709069d 100644 --- a/doc/fixes36.2 +++ b/doc/fixes36.2 @@ -1,4 +1,4 @@ -$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.297 $ $NHDT-Date: 1554411130 2019/04/04 20:52:10 $ +$NHDT-Branch: NetHack-3.6.2-beta01 $:$NHDT-Revision: 1.298 $ $NHDT-Date: 1554425733 2019/04/05 00:55:33 $ 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, @@ -536,6 +536,8 @@ curses: if player pressed ESC at More>> prompt to suppress remaining messages for the current move and then hero got another move on the same turn, messages and most prompts would stay suppressed during that extra move curses: don't let MSGTYPE=hide block prompts from being shown +curses: the --More-- prompt (">>") wasn't always placed in a visible location, + especially when window borders were displayed vms: add compile of isaac64.c to Makefile.src and vmsbuild.com vms+curses: add compile support but it is known to fail to build diff --git a/include/wincurs.h b/include/wincurs.h index 1dc6400d5..18b3be289 100644 --- a/include/wincurs.h +++ b/include/wincurs.h @@ -213,6 +213,7 @@ extern void curses_cleanup(void); /* cursmesg.c */ extern void curses_message_win_puts(const char *message, boolean recursed); +extern void curses_got_input(void); extern int curses_block(boolean require_tab); /* for MSGTYPE=STOP */ extern int curses_more(void); extern void curses_clear_unhighlight_message_window(void); diff --git a/win/curses/cursdial.c b/win/curses/cursdial.c index 062400b93..fd5385b90 100644 --- a/win/curses/cursdial.c +++ b/win/curses/cursdial.c @@ -17,8 +17,6 @@ #define strncasecmp strncmpi #endif -extern long curs_mesg_suppress_turn; /* from cursmesg.c */ - /* * Note: * @@ -127,7 +125,7 @@ curses_line_input_dialog(const char *prompt, char *answer, int buffer) /* if messages were being suppressed for the remainder of the turn, re-activate them now that input is being requested */ - curs_mesg_suppress_turn = -1; + curses_got_input(); if (buffer >= (int) sizeof input) buffer = (int) sizeof input - 1; @@ -212,7 +210,7 @@ curses_character_input_dialog(const char *prompt, const char *choices, /* if messages were being suppressed for the remainder of the turn, re-activate them now that input is being requested */ - curs_mesg_suppress_turn = -1; + curses_got_input(); if (invent || (moves > 1)) { curses_get_window_size(MAP_WIN, &map_height, &map_width); diff --git a/win/curses/cursmain.c b/win/curses/cursmain.c index c3cceb1f7..9757e111a 100644 --- a/win/curses/cursmain.c +++ b/win/curses/cursmain.c @@ -232,6 +232,7 @@ curses_get_nh_event() if (do_reset) { getmaxyx(base_term, term_rows, term_cols); + curses_got_input(); /* reset More>> */ /* status_initialize, create_main_windows, last_messages, doredraw */ curs_reset_windows(TRUE, TRUE); } @@ -689,9 +690,6 @@ curses_nhgetch() { int ch; - /* if messages are being suppressed, reenable them */ - curs_mesg_suppress_turn = -1; - curses_prehousekeeping(); ch = curses_read_char(); curses_posthousekeeping(); diff --git a/win/curses/cursmesg.c b/win/curses/cursmesg.c index 2c1decb9a..656dce57d 100644 --- a/win/curses/cursmesg.c +++ b/win/curses/cursmesg.c @@ -9,10 +9,14 @@ #include "cursmesg.h" #include +/* + * Note: references to "More>>" mean ">>", the curses rendition of "--More--". + */ + /* player can type ESC at More>> prompt to avoid seeing more messages for the current move; but hero might get more than one move per turn, so the input routines need to be able to cancel this */ -long curs_mesg_suppress_turn = -1; /* also used in cursdial.c && cursmain.c */ +long curs_mesg_suppress_turn = -1; /* Message window routines for curses interface */ @@ -31,30 +35,30 @@ static void directional_scroll(winid wid, int nlines); static void mesg_add_line(const char *mline); static nhprev_mesg *get_msg_line(boolean reverse, int mindex); -static int turn_lines = 1; +static int turn_lines = 0; static int mx = 0; static int my = 0; /* message window text location */ static nhprev_mesg *first_mesg = NULL; static nhprev_mesg *last_mesg = NULL; static int max_messages; static int num_messages = 0; +static int last_messages = 0; /* Write string to the message window. Attributes set by calling function. */ void curses_message_win_puts(const char *message, boolean recursed) { - int height, width, linespace; + int height, width, border_space, linespace; char *tmpstr; WINDOW *win = curses_get_nhwin(MESSAGE_WIN); - boolean border = curses_window_has_border(MESSAGE_WIN); - int message_length = strlen(message); - int border_space = 0; + boolean bold, border = curses_window_has_border(MESSAGE_WIN); + int message_length = (int) strlen(message); #if 0 /* * This was useful when curses used genl_putmsghistory() but is not - * needed now that it has its own curses_putmsghistory() that's + * needed now that it has its own curses_putmsghistory() which is * capable of putting something into the ^P recall history without * displaying it at the same time. */ @@ -69,17 +73,11 @@ curses_message_win_puts(const char *message, boolean recursed) } curses_get_window_size(MESSAGE_WIN, &height, &width); - if (border) { - border_space = 1; - if (mx < 1) { - mx = 1; - } - if (my < 1) { - my = 1; - } - } - - linespace = ((width + border_space) - 3) - mx; + border_space = (border ? 1 : 0); + if (mx < border_space) + mx = border_space; + if (my < border_space) + my = border_space; if (strcmp(message, "#") == 0) { /* Extended command or Count: */ if ((strcmp(toplines, "#") != 0) @@ -90,7 +88,6 @@ curses_message_win_puts(const char *message, boolean recursed) my--; strcpy(toplines, message); } - return; } @@ -99,88 +96,142 @@ curses_message_win_puts(const char *message, boolean recursed) mesg_add_line(message); } + linespace = width - 3 - (mx - border_space); + if (linespace < message_length) { - if (my >= (height - 1 + border_space)) { + if (my - border_space >= height - 1) { /* bottom of message win */ - if ((turn_lines > height) || (height == 1)) { + if (++turn_lines >= height) { /* || height == 1) */ /* Pause until key is hit - Esc suppresses any further messages that turn */ if (curses_more() == '\033') { curs_mesg_suppress_turn = moves; return; } + /* turn_lines reset to 0 by more()->block()->got_input() */ } else { scroll_window(MESSAGE_WIN); - turn_lines++; } } else { if (mx != border_space) { my++; mx = border_space; + ++turn_lines; } } } - if (height > 1) { + bold = (height > 1 && !last_messages); + if (bold) curses_toggle_color_attr(win, NONE, A_BOLD, ON); - } - if ((mx == border_space) && ((message_length + 2) > width)) { + /* will this message fit as-is or do we need to split it? */ + if (mx == border_space && message_length > width - 2) { + /* split needed */ tmpstr = curses_break_str(message, (width - 2), 1); - mvwprintw(win, my, mx, "%s", tmpstr); - mx += strlen(tmpstr); - if (strlen(tmpstr) < (size_t) (width - 2)) { - mx++; - } + mvwprintw(win, my, mx, "%s", tmpstr), mx += (int) strlen(tmpstr); + /* one space to separate first part of message from rest [is this + actually useful?] */ + if (mx < width - 2) + ++mx; free(tmpstr); - if (height > 1) { + if (bold) curses_toggle_color_attr(win, NONE, A_BOLD, OFF); - } tmpstr = curses_str_remainder(message, (width - 2), 1); curses_message_win_puts(tmpstr, TRUE); free(tmpstr); } else { - mvwprintw(win, my, mx, "%s", message); - curses_toggle_color_attr(win, NONE, A_BOLD, OFF); - mx += message_length + 1; + mvwprintw(win, my, mx, "%s", message), mx += message_length; + /* two spaces to separate this message from next one if they happen + to fit on the same line; (FIXME: it would be better if this was + done at start of next message rather than end of this one since + it impacts placement of "More>>") */ + if (mx < width - 2) { + if (++mx < width - 2) + ++mx; + } + if (bold) + curses_toggle_color_attr(win, NONE, A_BOLD, OFF); } wrefresh(win); } +void +curses_got_input(void) +{ + /* if messages are being suppressed, reenable them */ + curs_mesg_suppress_turn = -1; + + /* misleadingly named; represents number of lines delivered since + player was sure to have had a chance to read them; if player + has just given input then there aren't any such lines right; + that includes responding to More>> even though it stays same turn */ + turn_lines = 0; +} int curses_block(boolean noscroll) /* noscroll - blocking because of msgtype * = stop/alert else blocking because * window is full, so need to scroll after */ { - int height, width, ret = 0; + static const char resp[] = " \r\n\033"; /* space, enter, esc */ + static int prev_x = -1, prev_y = -1, blink = 0; + int height, width, moreattr, oldcrsr, ret = 0, + brdroffset = curses_window_has_border(MESSAGE_WIN) ? 1 : 0; WINDOW *win = curses_get_nhwin(MESSAGE_WIN); - const char *resp = " \r\n\033"; /* space, enter, esc */ - - /* if messages are being suppressed, reenable them */ - curs_mesg_suppress_turn = -1; curses_get_window_size(MESSAGE_WIN, &height, &width); - curses_toggle_color_attr(win, MORECOLOR, NONE, ON); - mvwprintw(win, my, mx, ">>"); - curses_toggle_color_attr(win, MORECOLOR, NONE, OFF); + if (mx - brdroffset > width - 3) { /* -3: room for ">>_" */ + if (my - brdroffset < height - 1) + ++my, mx = brdroffset; + else + mx = width - 3 + brdroffset; + } + /* if ">>" (--More--) is being rendered at the same spot as before, + toggle attributes so that the first '>' starts blinking if it wasn't + or stops blinking if it was */ + if (mx == prev_x && my == prev_y) { + blink = 1 - blink; + } else { + prev_x = mx, prev_y = my; + blink = 0; + } + moreattr = !iflags.wc2_guicolor ? A_REVERSE : NONE; + curses_toggle_color_attr(win, MORECOLOR, moreattr, ON); + if (blink) { + wattron(win, A_BLINK); + mvwprintw(win, my, mx, ">"), mx += 1; + wattroff(win, A_BLINK); + waddstr(win, ">"), mx += 1; + } else { + mvwprintw(win, my, mx, ">>"), mx += 2; + } + curses_toggle_color_attr(win, MORECOLOR, moreattr, OFF); wrefresh(win); - /* msgtype=stop should require space/enter rather than - * just any key, as we want to prevent YASD from - * riding direction keys. */ - while ((ret = wgetch(win)) != 0 && !index(resp, (char) ret)) - continue; + + /* cancel mesg suppression; all messages will have had chance to be read */ + curses_got_input(); + + oldcrsr = curs_set(1); + do { + ret = wgetch(win); + if (ret == ERR || ret == '\0') + ret = '\n'; + /* msgtype=stop should require space/enter rather than any key, + as we want to prevent YASD from direction keys. */ + } while (!index(resp, (char) ret)); + if (oldcrsr >= 0) + (void) curs_set(oldcrsr); + if (height == 1) { curses_clear_unhighlight_message_window(); } else { - mvwprintw(win, my, mx, " "); + mx -= 2, mvwprintw(win, my, mx, " "); /* back up and blank out ">>" */ if (!noscroll) { scroll_window(MESSAGE_WIN); - turn_lines = 1; } wrefresh(win); } - return ret; } @@ -196,34 +247,25 @@ curses_more() void curses_clear_unhighlight_message_window() { - int mh, mw, count; - boolean border = curses_window_has_border(MESSAGE_WIN); + int mh, mw, count, + brdroffset = curses_window_has_border(MESSAGE_WIN) ? 1 : 0; WINDOW *win = curses_get_nhwin(MESSAGE_WIN); - turn_lines = 1; + turn_lines = 0; curses_get_window_size(MESSAGE_WIN, &mh, &mw); - mx = 0; - if (border) { - mx++; - } - if (mh == 1) { curses_clear_nhwin(MESSAGE_WIN); + mx = my = brdroffset; } else { - mx += mw; /* Force new line on new turn */ + mx = mw + brdroffset; /* Force new line on new turn */ - if (border) { - for (count = 0; count < mh; count++) { - mvwchgat(win, count + 1, 1, mw, COLOR_PAIR(8), A_NORMAL, NULL); - } - } else { - for (count = 0; count < mh; count++) { - mvwchgat(win, count, 0, mw, COLOR_PAIR(8), A_NORMAL, NULL); - } - } + for (count = 0; count < mh; count++) + mvwchgat(win, count + brdroffset, brdroffset, + mw, COLOR_PAIR(8), A_NORMAL, NULL); wnoutrefresh(win); } + wmove(win, my, mx); } @@ -235,19 +277,23 @@ curses_last_messages() { boolean border = curses_window_has_border(MESSAGE_WIN); nhprev_mesg *mesg; - int i; + int i, j, height, width; + + curses_get_window_size(MESSAGE_WIN, &height, &width); if (border) mx = my = 1; else mx = my = 0; - for (i = (num_messages - 1); i > 0; i--) { + ++last_messages; + for (j = 0, i = num_messages - 1; i > 0 && j < height; --i, ++j) { mesg = get_msg_line(TRUE, i); if (mesg && mesg->str && *mesg->str) curses_message_win_puts(mesg->str, TRUE); } curses_message_win_puts(toplines, TRUE); + --last_messages; } @@ -402,7 +448,7 @@ curses_message_win_getline(const char *prompt, char *answer, int buffer) maxlines = buffer / width * 2; Strcpy(tmpbuf, prompt); Strcat(tmpbuf, " "); - nlines = curses_num_lines(tmpbuf,width); + nlines = curses_num_lines(tmpbuf, width); maxlines += nlines * 2; linestarts = (char **) alloc((unsigned) (maxlines * sizeof (char *))); p_answer = tmpbuf + strlen(tmpbuf); @@ -463,6 +509,7 @@ curses_message_win_getline(const char *prompt, char *answer, int buffer) wmove(win, my, mx); curs_set(1); wrefresh(win); + curses_got_input(); /* despite its name, before rathre than after... */ #ifdef PDCURSES ch = wgetch(win); #else @@ -786,6 +833,7 @@ boolean restoring_msghist; --stash_count; mesg_turn = mesg->turn; mesg_add_line(mesg->str); + /* added line became new tail */ last_mesg->turn = mesg_turn; free((genericptr_t) mesg->str); free((genericptr_t) mesg); diff --git a/win/curses/cursmesg.h b/win/curses/cursmesg.h index 803b0fb5b..ca0752eea 100644 --- a/win/curses/cursmesg.h +++ b/win/curses/cursmesg.h @@ -10,6 +10,7 @@ /* Global declarations */ void curses_message_win_puts(const char *message, boolean recursed); +void curses_got_input(void); int curses_block(boolean require_tab); int curses_more(void); void curses_clear_unhighlight_message_window(void); diff --git a/win/curses/cursmisc.c b/win/curses/cursmisc.c index fd712fac6..223a8be82 100644 --- a/win/curses/cursmisc.c +++ b/win/curses/cursmisc.c @@ -42,6 +42,9 @@ curses_read_char() { int ch, tmpch; + /* cancel message suppression; all messages have had a chance to be read */ + curses_got_input(); + ch = getch(); tmpch = ch; ch = curses_convert_keys(ch);