From 72abae042b1744b533f471cd59bfba7364fac839 Mon Sep 17 00:00:00 2001 From: "nethack.rankin" Date: Thu, 18 Jan 2007 04:16:03 +0000 Subject: [PATCH] hangup hangup (trunk only) The last of my intended hangup overhaul. Once hangup is detected, replace currently loaded windowing routines with stubs that never do any terminal I/O. Real interface routines call their siblings directly rather than via the windowprocs pointers, so this shouldn't pull the rug out from under them, but it also can't prevent whatever they have in progress at the time of hangup from attempting further I/O once the handler returns. [We might want to change nhwindows_hangup() into winprocs.hangup_nhwindows() so that each interface has more control over its own fate.] This assumes that user input of ESC and menu selection result of -1 everywhere in the core will eventually cause active function calls to unwind their way back to moveloop() rather than to continually re-prompt. (This assumption is not a new one, just a bit more explicit now.) --- include/extern.h | 3 + include/winprocs.h | 8 +- src/cmd.c | 1 + src/display.c | 8 +- src/pline.c | 5 +- src/windows.c | 365 ++++++++++++++++++++++++++++++++++++++++++++- 6 files changed, 385 insertions(+), 5 deletions(-) diff --git a/include/extern.h b/include/extern.h index 8e5ccc499..1fac63df4 100644 --- a/include/extern.h +++ b/include/extern.h @@ -2517,6 +2517,9 @@ E char FDECL(genl_message_menu, (CHAR_P,int,const char *)); E void FDECL(genl_preference_update, (const char *)); E char *FDECL(genl_getmsghistory, (BOOLEAN_P)); E void FDECL(genl_putmsghistory, (const char *)); +#ifdef HANGUPHANDLING +E void NDECL(nhwindows_hangup); +#endif /* ### wizard.c ### */ diff --git a/include/winprocs.h b/include/winprocs.h index 900f37d70..11ad3ba28 100644 --- a/include/winprocs.h +++ b/include/winprocs.h @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)winprocs.h 3.5 2003/01/08 */ +/* SCCS Id: @(#)winprocs.h 3.5 2007/01/17 */ /* Copyright (c) David Cohrs, 1992 */ /* NetHack may be freely redistributed. See license for details. */ @@ -81,7 +81,11 @@ struct window_procs { #endif }; -extern NEARDATA struct window_procs windowprocs; +extern +#ifdef HANGUPHANDLING +volatile +#endif +NEARDATA struct window_procs windowprocs; /* * If you wish to only support one window system and not use procedure diff --git a/src/cmd.c b/src/cmd.c index a694f0b69..9d6f43f99 100644 --- a/src/cmd.c +++ b/src/cmd.c @@ -2803,6 +2803,7 @@ void hangup(sig_unused) /* called as signal() handler, so sent at least one arg */ int sig_unused; { + nhwindows_hangup(); # ifdef SAFERHANGUP /* When using SAFERHANGUP, the done_hup flag it tested in rhack and a couple of other places; actual hangup handling occurs then. diff --git a/src/display.c b/src/display.c index a8918aecf..95ddb5a21 100644 --- a/src/display.c +++ b/src/display.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)display.c 3.5 2005/06/21 */ +/* SCCS Id: @(#)display.c 3.5 2007/01/17 */ /* Copyright (c) Dean Luick, with acknowledgements to Kevin Darcy */ /* and Dave Cohrs, 1990. */ /* NetHack may be freely redistributed. See license for details. */ @@ -648,6 +648,9 @@ newsym(x,y) register xchar worm_tail; if (in_mklev) return; +#ifdef HANGUPHANDLING + if (program_state.done_hup) return; +#endif /* only permit updating the hero when swallowed */ if (u.uswallow) { @@ -1383,6 +1386,9 @@ flush_screen(cursor_on_u) if (delay_flushing) return; if (flushing) return; /* if already flushing then return */ flushing = 1; +#ifdef HANGUPHANDLING + if (program_state.done_hup) return; +#endif for (y = 0; y < ROWNO; y++) { register gbuf_entry *gptr = &gbuf[y][x = gbuf_start[y]]; diff --git a/src/pline.c b/src/pline.c index 3fb5f4d39..eee589505 100644 --- a/src/pline.c +++ b/src/pline.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)pline.c 3.5 2006/08/30 */ +/* SCCS Id: @(#)pline.c 3.5 2007/01/17 */ /* Copyright (c) Stichting Mathematisch Centrum, Amsterdam, 1985. */ /* NetHack may be freely redistributed. See license for details. */ @@ -45,6 +45,9 @@ pline VA_DECL(const char *, line) /* Do NOT use VA_START and VA_END in here... see above */ if (!line || !*line) return; +#ifdef HANGUPHANDLING + if (program_state.done_hup) return; +#endif #ifdef WIZARD if (program_state.wizkit_wishing) return; #endif diff --git a/src/windows.c b/src/windows.c index 381621b64..fca68e07d 100644 --- a/src/windows.c +++ b/src/windows.c @@ -1,4 +1,4 @@ -/* SCCS Id: @(#)windows.c 3.5 1996/05/19 */ +/* SCCS Id: @(#)windows.c 3.5 2007/01/17 */ /* Copyright (c) D. Cohrs, 1993. */ /* NetHack may be freely redistributed. See license for details. */ @@ -43,6 +43,9 @@ extern struct window_procs mswin_procs; STATIC_DCL void FDECL(def_raw_print, (const char *s)); +#ifdef HANGUPHANDLING +volatile +#endif NEARDATA struct window_procs windowprocs; static @@ -142,6 +145,7 @@ const char *pref; for the preference capabilities that they support. Just return in this genl one. */ + return; } char * @@ -184,6 +188,365 @@ const char *msg; so it should keep all pointers/indexes intact at the end of each call. */ + return; } +#ifdef HANGUPHANDLING + /* + * Dummy windowing scheme used to replace current one with no-ops + * in order to avoid all terminal I/O after hangup/disconnect. + */ + +static int NDECL(hup_nhgetch); +static char FDECL(hup_yn_function, (const char *,const char *,CHAR_P)); +static int FDECL(hup_nh_poskey, (int *,int *,int *)); +static void FDECL(hup_getlin, (const char *,char *)); +static void FDECL(hup_init_nhwindows, (int *,char **)); +static void FDECL(hup_exit_nhwindows, (const char *)); +static winid FDECL(hup_create_nhwindow, (int)); +static int FDECL(hup_select_menu, (winid,int,MENU_ITEM_P **)); +static void FDECL(hup_add_menu, (winid,int,const anything *,CHAR_P,CHAR_P, + int,const char *,BOOLEAN_P)); +static void FDECL(hup_end_menu, (winid,const char *)); +static void FDECL(hup_putstr, (winid,int,const char *)); +static void FDECL(hup_print_glyph, (winid,XCHAR_P,XCHAR_P,int)); +static void FDECL(hup_outrip, (winid,int)); +static void FDECL(hup_curs, (winid,int,int)); +static void FDECL(hup_display_nhwindow, (winid,BOOLEAN_P)); +static void FDECL(hup_display_file, (const char *,BOOLEAN_P)); +# ifdef CLIPPING +static void FDECL(hup_cliparound, (int,int)); +# endif +# ifdef CHANGE_COLOR +static void FDECL(hup_change_color, (int,long,int)); +# ifdef MAC +static short FDECL(hup_set_font_name, (winid,char *)); +# endif +static char *NDECL(hup_get_color_string); +# endif /* CHANGE_COLOR */ +# ifdef STATUS_VIA_WINDOWPORT +static void FDECL(hup_status_update, (int,genericptr_t,int,int)); +# endif + +static int NDECL(hup_int_ndecl); +static void NDECL(hup_void_ndecl); +static void FDECL(hup_void_fdecl_int, (int)); +static void FDECL(hup_void_fdecl_winid, (winid)); +static void FDECL(hup_void_fdecl_constchar_p, (const char *)); + +static struct window_procs hup_procs = { + "hup", + 0L, + 0L, + hup_init_nhwindows, + hup_void_ndecl, /* player_selection */ + hup_void_ndecl, /* askname */ + hup_void_ndecl, /* get_nh_event */ + hup_exit_nhwindows, + hup_void_fdecl_constchar_p, /* suspend_nhwindows */ + hup_void_ndecl, /* resume_nhwindows */ + hup_create_nhwindow, + hup_void_fdecl_winid, /* clear_nhwindow */ + hup_display_nhwindow, + hup_void_fdecl_winid, /* destroy_nhwindow */ + hup_curs, + hup_putstr, + hup_putstr, /* putmixed */ + hup_display_file, + hup_void_fdecl_winid, /* start_menu */ + hup_add_menu, + hup_end_menu, + hup_select_menu, + genl_message_menu, + hup_void_ndecl, /* update_inventory */ + hup_void_ndecl, /* mark_synch */ + hup_void_ndecl, /* wait_synch */ +# ifdef CLIPPING + hup_cliparound, +# endif +# ifdef POSITIONBAR + (void FDECL((*),(char *)))hup_void_fdecl_constchar_p, /* update_positionbar */ +# endif + hup_print_glyph, + hup_void_fdecl_constchar_p, /* raw_print */ + hup_void_fdecl_constchar_p, /* raw_print_bold */ + hup_nhgetch, + hup_nh_poskey, + hup_void_ndecl, /* nhbell */ + hup_int_ndecl, /* doprev_message */ + hup_yn_function, + hup_getlin, + hup_int_ndecl, /* get_ext_cmd */ + hup_void_fdecl_int, /* number_pad */ + hup_void_ndecl, /* delay_output */ +# ifdef CHANGE_COLOR + hup_change_color, +# ifdef MAC + hup_void_fdecl_int, /* change_background */ + hup_set_font_name, +# endif + hup_get_color_string, +# endif /* CHANGE_COLOR */ + hup_void_ndecl, /* start_screen */ + hup_void_ndecl, /* end_screen */ + hup_outrip, + genl_preference_update, + genl_getmsghistory, + genl_putmsghistory, +# ifdef STATUS_VIA_WINDOWPORT + hup_void_ndecl, /* status_init */ + hup_void_ndecl, /* status_finish */ + genl_status_enablefield, + hup_status_update, +# ifdef STATUS_HILITES + genl_status_threshold, +# endif +# endif /* STATUS_VIA_WINDOWPORT */ +}; + +void +nhwindows_hangup() +{ + if (iflags.window_inited) exit_nhwindows((char *)0); + windowprocs = hup_procs; + /* hup_init_nhwindows((int *)0, (char **)0); */ +} + +static int +hup_nhgetch( VOID_ARGS ) +{ + return '\033'; /* ESC */ +} + +/*ARGSUSED*/ +static char +hup_yn_function(prompt, resp, deflt) +const char *prompt, *resp; +char deflt; +{ + if (!deflt) deflt = '\033'; + return deflt; +} + +/*ARGSUSED*/ +static int +hup_nh_poskey(x, y, mod) +int *x, *y, *mod; +{ + return '\033'; +} + +/*ARGSUSED*/ +static void +hup_getlin(prompt, outbuf) +const char *prompt; +char *outbuf; +{ + Strcpy(outbuf, "\033"); +} + +/*ARGUSED*/ +static void +hup_init_nhwindows(argc_p, argv) +int *argc_p; +char **argv; +{ + iflags.window_inited = 1; +} + +/*ARGUSED*/ +static void +hup_exit_nhwindows(dummy) +const char *dummy; +{ + iflags.window_inited = 0; +} + +/*ARGSUSED*/ +static winid +hup_create_nhwindow(type) +int type; +{ + return WIN_ERR; +} + +/*ARGSUSED*/ +static int +hup_select_menu(window, how, menu_list) +winid window; +int how; +struct mi **menu_list; +{ + return -1; +} + +/*ARGSUSED*/ +static void +hup_add_menu(window, glyph, identifier, sel, grpsel, attr, txt, preselected) +winid window; +int glyph, attr; +const anything *identifier; +char sel, grpsel; +const char *txt; +boolean preselected; +{ + return; +} + +/*ARGSUSED*/ +static void +hup_end_menu(window, prompt) +winid window; +const char *prompt; +{ + return; +} + +/*ARGSUSED*/ +static void +hup_putstr(window, attr, text) +winid window; +int attr; +const char *text; +{ + return; +} + +/*ARGSUSED*/ +static void +hup_print_glyph(window, x, y, glyph) +winid window; +xchar x, y; +int glyph; +{ + return; +} + +/*ARGSUSED*/ +static void +hup_outrip(tmpwin, how) +winid tmpwin; +int how; +{ + return; +} + +/*ARGSUSED*/ +static void +hup_curs(window, x, y) +winid window; +int x, y; +{ + return; +} + +/*ARGSUSED*/ +static void +hup_display_nhwindow(window, blocking) +winid window; +boolean blocking; +{ + return; +} + +/*ARGSUSED*/ +static void +hup_display_file(fname, complain) +const char *fname; +boolean complain; +{ + return; +} + +# ifdef CLIPPING +/*ARGSUSED*/ +static void +hup_cliparound(x, y) +int x, y; +{ + return; +} +# endif + +# ifdef CHANGE_COLOR +/*ARGSUSED*/ +static void +hup_change_color(color, rgb, reverse) +int color, reverse; +long rgb; +{ + return; +} + +# ifdef MAC +/*ARGSUSED*/ +static short +hup_set_font_name(window, fontname) +winid window; +char *fontname; +{ + return 0; +} +# endif /* MAC */ + +static char * +hup_get_color_string(VOID_ARGS) +{ + return (char *)0; +} +# endif /* CHANGE_COLOR */ + +# ifdef STATUS_VIA_WINDOWPORT +/*ARGSUSED*/ +static void +hup_status_update(idx, ptr, chg, percent) +int idx, chg, percent; +genericptr_t ptr; +{ + return; +} +# endif /* STATUS_VIA_WINDOWPORT */ + + /* + * Non-specific stubs. + */ + +static int +hup_int_ndecl(VOID_ARGS) +{ + return -1; +} + +static void +hup_void_ndecl(VOID_ARGS) +{ + return; +} + +/*ARGUSED*/ +static void +hup_void_fdecl_int(arg) +int arg; +{ + return; +} + +/*ARGUSED*/ +static void +hup_void_fdecl_winid(window) +winid window; +{ + return; +} + +/*ARGUSED*/ +static void +hup_void_fdecl_constchar_p(string) +const char *string; +{ + return; +} + +#endif /* HANGUPHANDLING */ + /*windows.c*/