diff --git a/include/decl.h b/include/decl.h index 79d8f381a..128b7d93d 100644 --- a/include/decl.h +++ b/include/decl.h @@ -381,6 +381,7 @@ struct instance_globals_g { coordxy gbuf_stop[ROWNO]; /* do_name.c */ + coordxy getposx, getposy; /* cursor position in case of async resize */ struct selectionvar *gloc_filter_map; int gloc_filter_floodfill_match_glyph; diff --git a/include/extern.h b/include/extern.h index ee9befb6b..29a5a27a4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -3278,6 +3278,9 @@ ATTRNORETURN extern void error (const char *, ...) PRINTF_F(1, 2) NORETURN; #ifdef TIMED_DELAY extern void msleep(unsigned); #endif +#ifdef SIGWINCH +extern void getwindowsz(void); +#endif #ifdef ENHANCED_SYMBOLS extern void tty_utf8graphics_fixup(void); #endif diff --git a/include/hack.h b/include/hack.h index edb654a2c..860e7b8c8 100644 --- a/include/hack.h +++ b/include/hack.h @@ -775,6 +775,13 @@ struct sinfo { interface to suppress menu commands in similar conditions; readchar() alrways resets it to 'otherInp' prior to returning */ int input_state; /* whether next key pressed will be entering a command */ +#ifdef TTY_GRAPHICS + /* resize_pending only matters when handling a SIGWINCH signal for tty; + getting_char is used along with that and also separately for UNIX; + we minimize #if conditionals for them to avoid unnecessary clutter */ + volatile int resize_pending; /* set by signal handler */ + volatile int getting_char; /* referenced during signal handling */ +#endif }; /* value of program_state.input_state, significant during readchar(); diff --git a/include/wintty.h b/include/wintty.h index 8d272cf56..87152ff54 100644 --- a/include/wintty.h +++ b/include/wintty.h @@ -45,16 +45,17 @@ typedef struct tty_mi { /* descriptor for tty-based windows */ struct WinDesc { - int flags; /* window flags */ - xint16 type; /* type of window */ - boolean active; /* true if window is active */ - short offx, offy; /* offset from topleft of display */ - long rows, cols; /* dimensions */ - long curx, cury; /* current cursor position */ - long maxrow, maxcol; /* the maximum size used -- for MENU wins */ + int flags; /* window flags */ + xint16 type; /* type of window */ + boolean active; /* true if window is active */ + boolean blanked; /* for erase_tty_screen(); not used [yet?] */ + short offx, offy; /* offset from topleft of display */ + long rows, cols; /* dimensions */ + long curx, cury; /* current cursor position */ + long maxrow, maxcol; /* the maximum size used -- for MENU wins; + * maxcol is also used by WIN_MESSAGE for + * tracking the ^P command */ unsigned long mbehavior; /* menu behavior flags (MENU) */ - /* maxcol is also used by WIN_MESSAGE for */ - /* tracking the ^P command */ short *datlen; /* allocation size for *data */ char **data; /* window data [row][column] */ char *morestr; /* string to display instead of default */ @@ -218,6 +219,7 @@ E void g_putch(int); E void g_pututf8(uint8 *); #endif #endif /* ENHANCED_SYMBOLS */ +extern void erase_tty_screen(void); E void win_tty_init(int); /* external declarations */ diff --git a/src/decl.c b/src/decl.c index 42ed0f7d3..3191180d5 100644 --- a/src/decl.c +++ b/src/decl.c @@ -374,6 +374,7 @@ const struct instance_globals_g g_init_g = { UNDEFINED_VALUES, /* gbug_stop */ /* do_name.c */ + 0, 0, /* getposx, getposy */ UNDEFINED_PTR, /* gloc_filter_map */ UNDEFINED_VALUE, /* gloc_filter_floodfill_match_glyph */ /* dog.c */ diff --git a/src/do_name.c b/src/do_name.c index 4a458d448..b520277da 100644 --- a/src/do_name.c +++ b/src/do_name.c @@ -826,8 +826,8 @@ getpos(coord *ccp, boolean force, const char *goal) visctrl(gc.Cmd.spkeys[NHKF_GETPOS_HELP])); msg_given = TRUE; } - cx = ccp->x; - cy = ccp->y; + cx = gg.getposx = ccp->x; + cy = gg.getposy = ccp->y; #ifdef CLIPPING cliparound(cx, cy); #endif @@ -1134,7 +1134,7 @@ getpos(coord *ccp, boolean force, const char *goal) break; } nxtc: - ; + gg.getposx = cx, gg.getposy = cy; #ifdef CLIPPING cliparound(cx, cy); #endif @@ -1150,6 +1150,7 @@ getpos(coord *ccp, boolean force, const char *goal) clear_nhwindow(WIN_MESSAGE); ccp->x = cx; ccp->y = cy; + gg.getposx = gg.getposy = 0; for (i = 0; i < NUM_GLOCS; i++) if (garr[i]) free((genericptr_t) garr[i]); diff --git a/sys/vms/vmstty.c b/sys/vms/vmstty.c index 00ded425c..1c7130e11 100644 --- a/sys/vms/vmstty.c +++ b/sys/vms/vmstty.c @@ -582,6 +582,23 @@ VA_DECL(const char *, s) #endif exit(EXIT_FAILURE); } + +#ifdef SIGWINCH +/* called by resize_tty(wintty.c) after receiving a SIGWINCH signal; + terminal size has changed and we should update LI and CO (from termcap) */ +void +getwindowsz(void) +{ + /* + * gettty() has code to do this, but it can't be used directly because + * it fetches terminal state in order to reset that upon termination. + * We need to avoid clobbering other saved state with values used by + * game-in-progress. For now, do nothing. + */ + return; +} +#endif + #ifdef ENHANCED_SYMBOLS /* * set in tty_start_screen() and allows @@ -592,6 +609,8 @@ VA_DECL(const char *, s) void tty_utf8graphics_fixup(void) { + return; } #endif /* ENHANCED_SYMBOLS */ +/*vmstty.c */ diff --git a/win/tty/getline.c b/win/tty/getline.c index eecff8bfb..abefed260 100644 --- a/win/tty/getline.c +++ b/win/tty/getline.c @@ -39,7 +39,10 @@ tty_getlin(const char *query, register char *bufp) } static void -hooked_tty_getlin(const char *query, register char *bufp, getlin_hook_proc hook) +hooked_tty_getlin( + const char *query, + register char *bufp, + getlin_hook_proc hook) { register char *obufp = bufp; register int c; diff --git a/win/tty/termcap.c b/win/tty/termcap.c index a7f38c957..11be382fe 100644 --- a/win/tty/termcap.c +++ b/win/tty/termcap.c @@ -627,6 +627,8 @@ term_clear_screen(void) if (CL) { xputs(CL); home(); + /* set remembered data to all spaces */ + erase_tty_screen(); } } diff --git a/win/tty/wintty.c b/win/tty/wintty.c index 7f3214425..e8ed9d934 100644 --- a/win/tty/wintty.c +++ b/win/tty/wintty.c @@ -36,9 +36,10 @@ extern void msmsg(const char *, ...); #include "wintty.h" -#ifdef CLIPPING /* might want SIGWINCH */ -#if defined(BSD) || defined(ULTRIX) || defined(AIX_31) || defined(_BULL_SOURCE) +#if defined(CLIPPING) && !defined(NO_SIGNAL) #include +#ifdef SIGWINCH +#define RESIZABLE #endif #endif @@ -80,7 +81,7 @@ extern void msmsg(const char *, ...); */ #define HUPSKIP() \ do { \ - if (gp.program_state.done_hup) { \ + if (gp.program_state.done_hup) { \ morc = '\033'; \ return; \ } \ @@ -88,7 +89,7 @@ extern void msmsg(const char *, ...); /* morc=ESC - in case we bypass xwaitforspace() which sets that */ #define HUPSKIP_RESULT(RES) \ do { \ - if (gp.program_state.done_hup) \ + if (gp.program_state.done_hup) \ return (RES); \ } while (0) #else /* !HANGUPHANDLING */ @@ -177,6 +178,8 @@ struct DisplayDesc *ttyDisplay; /* the tty display descriptor */ extern void cmov(int, int); /* from termcap.c */ extern void nocmov(int, int); /* from termcap.c */ +static volatile int erasing_tty_screen; /* volatile: SIGWINCH */ + #if defined(UNIX) || defined(VMS) static char obuf[BUFSIZ]; /* BUFSIZ is defined in stdio.h */ #endif @@ -212,6 +215,7 @@ static const char to_continue[] = "to continue"; static void getret(void); #endif static void bail(const char *); /* __attribute__((noreturn)) */ +static void newclipping(coordxy, coordxy); static void new_status_window(void); static void erase_menu_or_text(winid, struct WinDesc *, boolean); static void free_window_info(struct WinDesc *, boolean); @@ -269,6 +273,7 @@ static long last_glyph_reset_when; #endif static boolean calling_from_update_inventory = FALSE; static int ttyinv_create_window(int, struct WinDesc *); +static void ttyinv_remove_data(boolean); static void ttyinv_add_menu(winid, struct WinDesc *, char ch, int attr, int clr, const char *str); static void ttyinv_render(winid window, struct WinDesc *cw); @@ -349,84 +354,141 @@ bail(const char *mesg) /*NOTREACHED*/ } -#if defined(SIGWINCH) && defined(CLIPPING) && !defined(NO_SIGNAL) +#ifdef RESIZABLE static void winch_handler(int); +static void resize_tty(void); + +static volatile int resize_mesg = 0; - /* - * This really ought to just set a flag like the hangup handler does, - * then check the flag at "safe" times, in case the signal arrives - * while something fragile is executing. Better to have a brief period - * where display updates don't fit the new size than for tty internals - * to become corrupted. - * - * 'winch_seen' has been "notyet" for a long time.... - */ /* signal handler is called with at least 1 arg */ /*ARGUSED*/ static void winch_handler(int sig_unused UNUSED) { - int oldLI = LI, oldCO = CO, i; - register struct WinDesc *cw; - #ifdef WINCHAIN { #define WINCH_MESSAGE "(SIGWINCH)" if (wc_tracelogf) (void) write(fileno(wc_tracelogf), WINCH_MESSAGE, - strlen(WINCH_MESSAGE)); + sizeof WINCH_MESSAGE - sizeof ""); #undef WINCH_MESSAGE } #endif -#ifndef VMS - getwindowsz(); + + gp.program_state.resize_pending++; /* resize_tty() will reset it */ + /* if nethack is waiting for input, which is the most likely scenario, + we will go ahead and respond to the resize immediately; otherwise, + tty_nhgetch() will do so the next time it's called */ + if (gp.program_state.getting_char) { + resize_tty(); +#if 0 /* [this doesn't work as intended and seems to be unnecessary] */ + if (resize_mesg) { + /* resize_tty() put "Press a key to continue: " on top line */ + (void) tty_nhgetch(); /* recursion... */ + } #endif - /* For long running events such as multi-page menus and - * display_file(), we note the signal's occurance and - * hope the code there decides to handle the situation - * and reset the flag. There will be race conditions - * when handling this - code handlers so it doesn't matter. - */ -#ifdef notyet - winch_seen = TRUE; + } + return; +} + +/* query the system for tty size (vis getwindowsz()), and adapt the game's + windows to match */ +static void +resize_tty(void) +{ + int oldLI = LI, oldCO = CO, mapx, mapy, oldtoplin, i; + boolean map_active; + struct WinDesc *cw; + + /* reset to 0 rather than just decrement */ + gp.program_state.resize_pending = 0; + resize_mesg = 0; + + getwindowsz(); /* update LI and CO */ + if (!ttyDisplay || (LI == oldLI && CO == oldCO)) + return; + + ttyDisplay->rows = LI; + ttyDisplay->cols = CO; + + cw = wins[BASE_WINDOW]; + cw->rows = ttyDisplay->rows; + cw->cols = ttyDisplay->cols; + + if (!iflags.window_inited) + return; + + /* try to figure out where we'll want to leave the cursor */ + cw = (WIN_MAP != WIN_ERR) ? wins[WIN_MAP] : NULL; + map_active = (cw && cw->active); + if (!map_active) + mapx = 1, mapy = 0; + else if (gg.getposx < 1) + mapx = u.ux, mapy = u.uy; + else + mapx = gg.getposx, mapy = gg.getposy; + + oldtoplin = ttyDisplay->toplin; + ttyDisplay->toplin = TOPLINE_EMPTY; /* (before term_clear_screen()) */ + /* whatever used to be on the screen has become suspect; + blank it all out, then redo the display */ + term_clear_screen(); + new_status_window(); + + /* if the map window is shown, redisplay it (also status, perminv) */ + if (map_active) { + docrt_flags(docrtRefresh); + bot(); /* context.botlx=1 gets set by docrt() */ + for (i = 0; i < MAXWIN; ++i) { + if (i == BASE_WINDOW + || i == WIN_MAP /* docrt() updates it */ + || i == WIN_STATUS /* docrt()+bot() updates it */ +#ifdef TTY_PERM_INVENT + || i == WIN_INVEN /* docrt() again */ #endif - if ((oldLI != LI || oldCO != CO) && ttyDisplay) { - ttyDisplay->rows = LI; - ttyDisplay->cols = CO; - - cw = wins[BASE_WINDOW]; - cw->rows = ttyDisplay->rows; - cw->cols = ttyDisplay->cols; - - if (iflags.window_inited) { - cw = wins[WIN_MESSAGE]; - cw->curx = cw->cury = 0; - - new_status_window(); - if (u.ux) { - i = ttyDisplay->toplin; - ttyDisplay->toplin = TOPLINE_EMPTY; - docrt(); - bot(); - ttyDisplay->toplin = i; - flush_screen(1); - if (i) { - addtopl(gt.toplines); - } else - for (i = WIN_INVEN; i < MAXWIN; i++) - if (wins[i] && wins[i]->active) { - /* cop-out */ - addtopl("Press Return to continue: "); - break; - } - (void) fflush(stdout); - if (i < 2) - flush_screen(1); + || i == WIN_MESSAGE) /* we fake it here */ + continue; + if (wins[i] && wins[i]->active) { + /* cop-out */ + oldtoplin = TOPLINE_EMPTY; /* don't restore it below */ + ttyDisplay->toplin = TOPLINE_NON_EMPTY; + addtopl("Press a key to continue: "); + resize_mesg++; + break; } } + } /* wins[WIN_MAP].active */ + + if (oldtoplin != TOPLINE_EMPTY) { + ttyDisplay->toplin = oldtoplin; + addtopl(gt.toplines); } + if (map_active) { + newclipping(mapx, mapy); + tty_curs(WIN_MAP, mapx, mapy); + tty_display_nhwindow(WIN_MAP, FALSE); /*fflush(stdout)*/ + } + return; +} +#endif /* RESIZABLE */ + +static void +newclipping(coordxy x, coordxy y) +{ +#ifdef CLIPPING + if (CO < COLNO || LI < 1 + ROWNO + iflags.wc2_statuslines) { + setclipped(); /* sets clipping=TRUE */ + if (x) + tty_cliparound(x, y); + } else { + clipping = FALSE; + clipx = clipy = 0; + } +#else + nhUse(x + y); +#endif + return; } -#endif /* SIGWINCH && CLIPPING && !NO_SIGNAL */ /* destroy and recreate status window; extracted from winch_handler() and augmented for use by tty_preference_update() */ @@ -434,11 +496,9 @@ static void new_status_window(void) { if (WIN_STATUS != WIN_ERR) { - /* if it's shrinking, clear it before destroying so that + /* in case it's shrinking, clear it before destroying so that dropped portion won't show anything that's now becoming stale */ - if (wins[WIN_STATUS]->maxrow > iflags.wc2_statuslines) - tty_clear_nhwindow(WIN_STATUS); - + tty_clear_nhwindow(WIN_STATUS); tty_destroy_nhwindow(WIN_STATUS), WIN_STATUS = WIN_ERR; } /* frees some status tracking data */ @@ -449,18 +509,6 @@ new_status_window(void) #ifdef STATUS_HILITES status_initialize(REASSESS_ONLY); #endif - -#ifdef CLIPPING - if (u.ux) { - if (CO < COLNO || LI < 1 + ROWNO + iflags.wc2_statuslines) { - setclipped(); - tty_cliparound(u.ux, u.uy); - } else { - clipping = FALSE; - clipx = clipy = 0; - } - } -#endif } /*ARGSUSED*/ @@ -511,7 +559,7 @@ tty_init_nhwindows(int *argcp UNUSED, char **argv UNUSED) ttyDisplay->lastwin = WIN_ERR; -#if defined(SIGWINCH) && defined(CLIPPING) && !defined(NO_SIGNAL) +#ifdef RESIZABLE (void) signal(SIGWINCH, (SIG_RET_TYPE) winch_handler); #endif @@ -555,6 +603,7 @@ tty_preference_update(const char *pref) { if (!strcmp(pref, "statuslines") && iflags.window_inited) { new_status_window(); + newclipping(u.ux, u.uy); } #if defined(WIN32CON) @@ -983,10 +1032,13 @@ tty_clear_nhwindow(winid window) switch (cw->type) { case NHW_MESSAGE: if (ttyDisplay->toplin != TOPLINE_EMPTY) { - home(); - cl_end(); - if (cw->cury) - docorner(1, cw->cury + 1, 0); + if (!erasing_tty_screen) { + home(); + cl_end(); + if (cw->cury) + docorner(1, cw->cury + 1, 0); + } + cw->curx = cw->cury = 0; ttyDisplay->toplin = TOPLINE_EMPTY; } break; @@ -994,9 +1046,10 @@ tty_clear_nhwindow(winid window) m = cw->maxrow; n = cw->cols; for (i = 0; i < m; ++i) { - tty_curs(window, 1, i); - cl_end(); - + if (!erasing_tty_screen) { + tty_curs(window, 1, i); + cl_end(); + } for (j = 0; j < n - 1; ++j) cw->data[i][j] = ' '; cw->data[i][n - 1] = '\0'; @@ -1009,17 +1062,33 @@ tty_clear_nhwindow(winid window) gc.context.botlx = 1; /*FALLTHRU*/ case NHW_BASE: - term_clear_screen(); - /* [this should reset state for MESSAGE, MAP, and STATUS] */ + /* if erasing_tty_screen is True, calling sequence is + term_clear_screen -> erase_tty_screen -> tty_clear_nhwindow + so we don't call term_clear_screen again */ + if (!erasing_tty_screen) { + term_clear_screen(); + } + /* + * Neither map nor base window tracks what is currently shown so + * there's no stale data that would need to be changed to spaces. + */ break; case NHW_MENU: case NHW_TEXT: if (cw->active) erase_menu_or_text(window, cw, TRUE); - free_window_info(cw, FALSE); + if (!erasing_tty_screen) { + free_window_info(cw, FALSE); + } break; +#ifdef TTY_PERM_INVENT + case NHW_PERMINVENT: + ttyinv_remove_data(FALSE); + break; +#endif } cw->curx = cw->cury = 0; + /* cw->blanked = TRUE; -- this isn't used */ } RESTORE_WARNING_FORMAT_NONLITERAL @@ -1906,40 +1975,39 @@ tty_destroy_nhwindow(winid window) if (cw->type == NHW_MAP) term_clear_screen(); #ifdef TTY_PERM_INVENT - if (cw->type == NHW_PERMINVENT) { - int r, c; - - if (cw->cells) { - for (r = 0; r < cw->maxrow; r++) { - if (cw->cells[r]) { - for (c = 0; c < cw->maxcol; c++) { - /* glyph is a flag indicating whether content union - contains a glyph_info structure or just a char */ - if (cw->cells[r][c].glyph) - free((genericptr_t) cw->cells[r][c].content.gi); - cw->cells[r][c] = zerottycell; - cw->cells[r][c].glyph = 0; - } - free((genericptr_t) cw->cells[r]); - cw->cells[r] = (struct tty_perminvent_cell *) 0; - } - } - free((genericptr_t) cw->cells); - cw->cells = (struct tty_perminvent_cell **) 0; - cw->rows = cw->cols = 0; - } - cw->maxrow = cw->maxcol = 0; - WIN_INVEN = WIN_ERR; - done_tty_perm_invent_init = FALSE; - } + if (cw->type == NHW_PERMINVENT) + ttyinv_remove_data(TRUE); #endif free_window_info(cw, TRUE); free((genericptr_t) cw); wins[window] = 0; /* available for re-use */ } +/* when screen is cleared, reset stored data to spaces */ void -tty_curs(winid window, +erase_tty_screen(void) +{ + struct WinDesc *cw; + int i; + + if (erasing_tty_screen++) + return; +#if 0 /* originally we called term_clear_screen() but now it calls us */ + term_clear_screen(); /* erase the screen */ +#endif + /* update window data to reflect that each active window is all blanks */ + for (i = 0; i < MAXWIN; ++i) { + cw = wins[i]; + if (cw && cw->active) + tty_clear_nhwindow(i); + } + tty_curs(BASE_WINDOW, 1, 0); + erasing_tty_screen = 0; +} + +void +tty_curs( + winid window, register int x, register int y) /* not xchar: perhaps xchar is unsigned * then curx-x would be unsigned too */ { @@ -2330,9 +2398,6 @@ tty_display_file( nh_terminate(EXIT_FAILURE); } (void) close(fd); -#ifdef notyet - winch_seen = 0; -#endif } #else /* DEF_PAGER */ { @@ -2406,11 +2471,12 @@ tty_start_menu(winid window, unsigned long mbehavior) return; } if (mbehavior == MENU_BEHAVE_PERMINV - && (iflags.perm_invent - || gp.perm_invent_toggling_direction == toggling_on)) { + && (iflags.perm_invent + || gp.perm_invent_toggling_direction == toggling_on)) { winid w = ttyinv_create_window(window, wins[window]); + if (w == WIN_ERR) { - /* something went wrong, so add clean up code here */ + ; /* something went wrong, so add clean up code here */ } else { cw->mbehavior = mbehavior; } @@ -2537,7 +2603,8 @@ tty_end_menu(winid window, /* menu to use */ } #ifdef TTY_PERM_INVENT if (cw->mbehavior == MENU_BEHAVE_PERMINV - && (iflags.perm_invent || gp.perm_invent_toggling_direction == toggling_on) + && (iflags.perm_invent + || gp.perm_invent_toggling_direction == toggling_on) && window == WIN_INVEN) { if (gp.program_state.in_moveloop) ttyinv_render(window, cw); @@ -2807,7 +2874,6 @@ ttyinv_create_window(int newid, struct WinDesc *newwin) newwin->datlen = (short *) 0; newwin->cells = (struct tty_perminvent_cell **) 0; - if (!assesstty(ttyinvmode, &newwin->offx, &newwin->offy, &newwin->rows, &newwin->cols, &newwin->maxcol, &minrow, &newwin->maxrow)) { @@ -2861,6 +2927,54 @@ ttyinv_create_window(int newid, struct WinDesc *newwin) return newid; } +/* discard perminvent window or erase it and set remembered data to spaces */ +static void +ttyinv_remove_data(boolean destroy) +{ + struct WinDesc *cw = (WIN_INVEN != WIN_ERR) ? wins[WIN_INVEN] : NULL; + + if (!cw) { + impossible("Removing ttyinv data for nonexistent perm invent window?"); + return; + } + + if (cw->cells) { + int r, c; + + for (r = 0; r < cw->maxrow; r++) { + if (cw->cells[r]) { + for (c = 0; c < cw->maxcol; c++) { + struct tty_perminvent_cell *invcell = &cw->cells[r][c]; + + /* glyph is a flag indicating whether content union + contains a glyph_info structure or just a char */ + if (invcell->glyph) + free((genericptr_t) invcell->content.gi); + *invcell = zerottycell; /* sets glyph flag to 0 */ + if (!destroy) { /* erasing */ + invcell->content.ttychar = ' '; + invcell->text = 1; + invcell->refresh = 1; /* full redraw wanted */ + } + } + if (destroy) + free((genericptr_t) cw->cells[r]), + cw->cells[r] = (struct tty_perminvent_cell *) 0; + } + } + if (destroy) { + free((genericptr_t) cw->cells), + cw->cells = (struct tty_perminvent_cell **) 0; + cw->rows = cw->cols = 0; + } + } + if (destroy) { + cw->maxrow = cw->maxcol = 0; + WIN_INVEN = WIN_ERR; + done_tty_perm_invent_init = FALSE; + } +} + static void ttyinv_add_menu(winid window UNUSED, struct WinDesc *cw, char ch, int attr UNUSED, int clr UNUSED, const char *str) @@ -2908,15 +3022,14 @@ ttyinv_add_menu(winid window UNUSED, struct WinDesc *cw, char ch, } return; } + static int selector_to_slot(char ch, const int invflags, boolean *ignore) { int slot = 0; boolean show_gold = (invflags & InvShowGold) != 0, + /* sparse = (invflags & InvSparse) != 0, */ inuse_only = (invflags & InvInUse) != 0; -#if 0 - sparse = (invflags & InvSparse) != 0, -#endif *ignore = FALSE; switch (ch) { @@ -3216,6 +3329,7 @@ tty_invent_box_glyph_init(struct WinDesc *cw) } done_tty_perm_invent_init = TRUE; } + #endif /* TTY_PERM_INVENT */ /* update persistent inventory window */ @@ -3260,7 +3374,9 @@ tty_wait_synch(void) } void -docorner(register int xmin, register int ymax, int ystart_between_menu_pages) +docorner( + register int xmin, register int ymax, + int ystart_between_menu_pages) { register int y; register struct WinDesc *cw = wins[WIN_MAP]; @@ -3274,7 +3390,7 @@ docorner(register int xmin, register int ymax, int ystart_between_menu_pages) HUPSKIP(); #if 0 /* this optimization is not valuable enough to justify - abusing core internals... */ + * abusing core internals... */ if (u.uswallow) { /* Can be done more efficiently */ swallowed(1); /* without this flush, if we happen to follow --More-- displayed in @@ -3285,7 +3401,7 @@ docorner(register int xmin, register int ymax, int ystart_between_menu_pages) } #endif /*0*/ -#if defined(SIGWINCH) && defined(CLIPPING) +#ifdef RESIZABLE if (ymax > LI) ymax = LI; /* can happen if window gets smaller */ #endif @@ -3633,12 +3749,10 @@ tty_nhgetch(void) { int i; #ifdef UNIX - /* kludge alert: Some Unix variants return funny values if getc() - * is called, interrupted, and then called again. There - * is non-reentrant code in the internal _filbuf() routine, called by - * getc(). + /* kludge alert: Some Unix variants return funny values if getc() is + * called, interrupted, and then called again. There is non-reentrant + * code in the internal _filbuf() routine, called by getc(). */ - static volatile int nesting = 0; char nestbuf; #endif @@ -3655,21 +3769,33 @@ tty_nhgetch(void) if (iflags.debug_fuzzer) { i = randomkey(); } else { +#ifdef RESIZABLE + if (gp.program_state.resize_pending) + resize_tty(); +#endif + gp.program_state.getting_char++; #ifdef UNIX - i = (++nesting == 1) + i = (gp.program_state.getting_char == 1) ? tgetch() - : (read(fileno(stdin), (genericptr_t) &nestbuf, 1) == 1) - ? (int) nestbuf : EOF; - --nesting; + : ((read(fileno(stdin), (genericptr_t) &nestbuf, 1) == 1) + ? (int) nestbuf : EOF); #else i = tgetch(); +#endif + gp.program_state.getting_char--; +#ifdef RESIZABLE + if (resize_mesg) { + resize_mesg = 0; + tty_clear_nhwindow(WIN_MESSAGE); + i = '\033'; + } #endif } if (!i) i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */ else if (i == EOF) i = '\033'; /* same for EOF */ - /* topline has been seen - we can clear need for more */ + /* topline has been seen - we can clear the need for --More-- */ if (ttyDisplay && ttyDisplay->toplin == TOPLINE_NEED_MORE) ttyDisplay->toplin = TOPLINE_NON_EMPTY; #ifdef TTY_TILES_ESCCODES @@ -4826,6 +4952,7 @@ play_usersound_via_idx(int idx, int volume) #undef print_vt_soundcode_idx #endif +#undef RESIZABLE #ifdef getret #undef getret #endif