SAFERHANGUP

This is an initial round of SAFERHANGUP hangup changes.  It introduces
SAFERHANGUP, provides the core framework, and enables it for UNIX.

Window-port changes are provided for win/tty, win/X11 and win/gnome.  Qt
changes should be forthcoming after having Warwick look at them.
window.doc is updated so windowport maintainers have an clue what needs to
be done to support SAFERHANGUP.
This commit is contained in:
cohrs
2003-09-19 03:15:49 +00:00
parent 1382c6c028
commit 40b5b12673
12 changed files with 178 additions and 42 deletions
+67 -1
View File
@@ -55,6 +55,10 @@
#include "patchlevel.h"
#endif
#ifndef NO_SIGNAL
#include <signal.h>
#endif
/* Should be defined in <X11/Intrinsic.h> but you never know */
#ifndef XtSpecificationRelease
#define XtSpecificationRelease 0
@@ -88,6 +92,9 @@ int click_x, click_y, click_button; /* Click position on a map window */
/* (filled by set_button_values()). */
int updated_inventory;
#ifndef NO_SIGNAL
static XtSignalId X11_sig_id;
#endif
/* Interface definition, for windows.c */
struct window_procs X11_procs = {
@@ -162,7 +169,10 @@ static void FDECL(X11_hangup, (Widget, XEvent*, String*, Cardinal*));
static int FDECL(input_event, (int));
static void FDECL(win_visible, (Widget,XtPointer,XEvent *,Boolean *));
static void NDECL(init_standard_windows);
#if !defined(NO_SIGNAL) && defined(SAFERHANGUP)
static void FDECL(X11_sig, (int));
static void FDECL(X11_sig_cb, (XtPointer, XtSignalId*));
#endif
/*
* Local variables.
@@ -604,6 +614,32 @@ X11_create_nhwindow(type)
if (!x_inited)
panic("create_nhwindow: windows not initialized");
#if !defined(NO_SIGNAL) && defined(SAFERHANGUP)
/* set up our own signal handlers on the first call. Can't do this in
* X11_init_nhwindows because unixmain sets its handler after calling
* all the init routines. */
if (X11_sig_id == 0) {
X11_sig_id = XtAppAddSignal(app_context, X11_sig_cb, (XtPointer)0);
#ifdef SA_RESTART
{
struct sigaction sact;
(void) memset((char*) &sact, 0, sizeof(struct sigaction));
sact.sa_handler = (SIG_RET_TYPE)X11_sig;
(void) sigaction(SIGHUP, &sact, (struct sigaction*)0);
#ifdef SIGXCPU
(void) sigaction(SIGXCPU, &sact, (struct sigaction*)0);
#endif
}
#else
(void) signal(SIGHUP, (SIG_RET_TYPE) X11_sig);
#ifdef SIGXCPU
(void) signal(SIGXCPU, (SIG_RET_TYPE) X11_sig);
#endif
#endif
}
#endif
/*
* We have already created the standard message, map, and status
* windows in the window init routine. The first window of that
@@ -1064,6 +1100,36 @@ void X11_exit_nhwindows(dummy)
X11_destroy_nhwindow(WIN_MESSAGE);
}
#if !defined(NO_SIGNAL) && defined(SAFERHANGUP)
void
X11_sig(sig) /* Unix signal handler */
int sig;
{
XtNoticeSignal(X11_sig_id);
hangup(sig);
}
void
X11_sig_cb(not_used, id)
XtPointer not_used;
XtSignalId* id;
{
XEvent event;
XClientMessageEvent *mesg;
/* Set up a fake message to the event handler. */
mesg = (XClientMessageEvent *) &event;
mesg->type = ClientMessage;
mesg->message_type = XA_STRING;
mesg->format = 8;
XSendEvent(XtDisplay(window_list[WIN_MAP].w),
XtWindow(window_list[WIN_MAP].w),
False,
NoEventMask,
(XEvent*) mesg);
}
#endif
/* delay_output ------------------------------------------------------------ */
+8
View File
@@ -1622,6 +1622,10 @@ x_event(exit_condition)
inptr = (inptr+1) % INBUF_SIZE;
/* pkey(retval); */
keep_going = FALSE;
} else if (program_state.done_hup) {
retval = '\033';
inptr = (inptr+1) % INBUF_SIZE;
keep_going = FALSE;
}
break;
case EXIT_ON_KEY_OR_BUTTON_PRESS:
@@ -1637,6 +1641,10 @@ x_event(exit_condition)
/* pkey(retval); */
}
keep_going = FALSE;
} else if (program_state.done_hup) {
retval = '\033';
inptr = (inptr+1) % INBUF_SIZE;
keep_going = FALSE;
}
break;
default:
+21 -20
View File
@@ -158,7 +158,7 @@ gnome_player_selection()
if (sel >= 0) sel = pickmap[sel];
else if (sel == ROLE_NONE) { /* Quit */
clearlocks();
gnome_exit_nhwindows(0);
gtk_exit(0);
}
free(choices);
free(pickmap);
@@ -212,7 +212,7 @@ gnome_player_selection()
if (sel >= 0) sel = pickmap[sel];
else if (sel == ROLE_NONE) { /* Quit */
clearlocks();
gnome_exit_nhwindows(0);
gtk_exit(0);
}
flags.initrace = sel;
free(choices);
@@ -267,7 +267,7 @@ gnome_player_selection()
if (sel >= 0) sel = pickmap[sel];
else if (sel == ROLE_NONE) { /* Quit */
clearlocks();
gnome_exit_nhwindows(0);
gtk_exit(0);
}
flags.initgend = sel;
free(choices);
@@ -320,7 +320,7 @@ gnome_player_selection()
if (sel >= 0) sel = pickmap[sel];
else if (sel == ROLE_NONE) { /* Quit */
clearlocks();
gnome_exit_nhwindows(0);
gtk_exit(0);
}
flags.initalign = sel;
free(choices);
@@ -350,7 +350,7 @@ void gnome_askname()
/* Quit if they want to quit... */
if (ret==-1)
{
gnome_exit_nhwindows(0);
gtk_exit(0);
}
}
@@ -369,8 +369,7 @@ void gnome_get_nh_event()
*/
void gnome_exit_nhwindows(const char *str)
{
gtk_exit (0);
terminate(EXIT_SUCCESS);
/* gtk cannot do this without exiting the program, do nothing */
}
/* Prepare the window to be suspended. */
@@ -398,19 +397,17 @@ void gnome_resume_nhwindows()
winid
gnome_create_nhwindow(int type)
{
winid i = 0;
winid i = 0;
/* Return the next available winid */
/* Return the next available winid
*/
for (i=0; i<MAXWINDOWS; i++)
if (gnome_windowlist[i].win == NULL)
break;
if (i == MAXWINDOWS)
g_error ("ERROR: No windows available...\n");
gnome_create_nhwindow_by_id( type, i);
return i;
for (i=0; i<MAXWINDOWS; i++)
if (gnome_windowlist[i].win == NULL)
break;
if (i == MAXWINDOWS)
g_error ("ERROR: No windows available...\n");
gnome_create_nhwindow_by_id( type, i);
return i;
}
void
@@ -910,8 +907,10 @@ int gnome_nhgetch()
g_askingQuestion = 1;
/* Process events until a key press event arrives. */
while ( g_numKeys == 0 )
while ( g_numKeys == 0 ) {
if (program_state.done_hup) return '\033';
gtk_main_iteration();
}
theFirst = g_list_first( g_keyBuffer);
g_keyBuffer = g_list_remove_link(g_keyBuffer, theFirst);
@@ -944,8 +943,10 @@ int gnome_nh_poskey(int *x, int *y, int *mod)
g_askingQuestion = 0;
/* Process events until a key or map-click arrives. */
while ( g_numKeys == 0 && g_numClicks == 0 )
while ( g_numKeys == 0 && g_numClicks == 0 ) {
if (program_state.done_hup) return '\033';
gtk_main_iteration();
}
if (g_numKeys > 0) {
int key;
+6 -6
View File
@@ -58,12 +58,7 @@ getlin_hook_proc hook;
(void) fflush(stdout);
Sprintf(toplines, "%s ", query);
Strcat(toplines, obufp);
if((c = Getchar()) == EOF) {
#ifndef NEWAUTOCOMP
*bufp = 0;
#endif /* not NEWAUTOCOMP */
break;
}
if((c = Getchar()) == EOF) c = '\033';
if(c == '\033') {
*obufp = c;
obufp[1] = 0;
@@ -183,6 +178,11 @@ register const char *s; /* chars allowed besides return */
while((c = tty_nhgetch()) != '\n') {
if(iflags.cbreak) {
if (c == EOF || c == '\033') {
ttyDisplay->dismiss_more = 1;
morc = '\033';
break;
}
if ((s && index(s,c)) || c == x) {
morc = (char) c;
break;
+4 -3
View File
@@ -677,7 +677,7 @@ tty_askname()
wins[BASE_WINDOW]->cury - 1);
ct = 0;
while((c = tty_nhgetch()) != '\n') {
if(c == EOF) error("End of input\n");
if(c == EOF) c = '\033';
if (c == '\033') { ct = 0; break; } /* continue outer loop */
#if defined(WIN32CON)
if (c == '\003') bail("^C abort.\n");
@@ -2520,6 +2520,7 @@ tty_nhgetch()
i = tgetch();
#endif
if (!i) i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */
else if (i == EOF) i = '\033'; /* same for EOF */
if (ttyDisplay && ttyDisplay->toplin == 1)
ttyDisplay->toplin = 2;
return i;
@@ -2546,8 +2547,8 @@ tty_nh_poskey(x, y, mod)
if (WIN_MESSAGE != WIN_ERR && wins[WIN_MESSAGE])
wins[WIN_MESSAGE]->flags &= ~WIN_STOP;
i = ntposkey(x, y, mod);
if (!i && mod && *mod == 0)
i = '\033'; /* map NUL to ESC since nethack doesn't expect NUL */
if (!i && mod && (*mod == 0 || *mod == EOF))
i = '\033'; /* map NUL or EOF to ESC, nethack doesn't expect either */
if (ttyDisplay && ttyDisplay->toplin == 1)
ttyDisplay->toplin = 2;
return i;