]> granicus.if.org Git - nethack/commitdiff
hangup hangup (trunk only)
authornethack.rankin <nethack.rankin>
Thu, 18 Jan 2007 04:16:03 +0000 (04:16 +0000)
committernethack.rankin <nethack.rankin>
Thu, 18 Jan 2007 04:16:03 +0000 (04:16 +0000)
     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
include/winprocs.h
src/cmd.c
src/display.c
src/pline.c
src/windows.c

index 8e5ccc499b0972658c170b2c6640dd5383803903..1fac63df43ae53c6f7a6db0639cd7b011f6cd323 100644 (file)
@@ -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 ### */
 
index 900f37d705b5d3071c6d3e206893f9f44f758d5a..11ad3ba284663112a5955176862a897e91415407 100644 (file)
@@ -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
index a694f0b692238dbd40ab94383c407c5c87cb597c..9d6f43f990002b11fb63be597218489754ed37e3 100644 (file)
--- 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.
index a8918aecff4a4bf2f3bfc23cb9a7e2ced2796ddf..95ddb5a2162ce551a32a28d076525fd33693991d 100644 (file)
@@ -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]];
index 3fb5f4d3970fdafff67242f6eb092ff0399d21f2..eee589505a08691803b8287722a7fde1963d8813 100644 (file)
@@ -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
index 381621b6478a99237e79b222c870ad2a210ac0ad..fca68e07d92d08e348f328ed66aee8839438e030 100644 (file)
@@ -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*/