From: Pasi Kallinen Date: Sun, 10 Jan 2016 11:01:46 +0000 (+0200) Subject: Add compile-time option MSGHANDLER X-Git-Tag: NetHack-3.6.1_RC01~1046 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=65d780dc3d1a176d834c0b0ced197d5eaaa21428;p=nethack Add compile-time option MSGHANDLER This was a feature request from a blind player; he wanted to play a sound whenever a pline message was given. --- diff --git a/doc/fixes36.1 b/doc/fixes36.1 index a14453683..c3b17ca0f 100644 --- a/doc/fixes36.1 +++ b/doc/fixes36.1 @@ -161,6 +161,7 @@ Platform- and/or Interface-Specific New Features ------------------------------------------------ tty: menu_overlay -option to clear screen and align menus to left tty: compile-time option to output escape codes for tile data hints +unix: compile-time option MSGHANDLER to pass messages to external program NetHack Community Patches (or Variation) Included diff --git a/include/config.h b/include/config.h index 72f87fb11..121ce5407 100644 --- a/include/config.h +++ b/include/config.h @@ -466,6 +466,12 @@ typedef unsigned char uchar; * Note that gnome-terminal at least doesn't work with this. */ /* #define TTY_TILES_ESCCODES */ +/* NetHack will execute an external program whenever a new message-window + * message is shown. The program to execute is given in environment variable + * NETHACK_MSGHANDLER. It will get the message as the only parameter. + * Only available with POSIX_TYPES or GNU C */ +/* #define MSGHANDLER */ + /* #define STATUS_VIA_WINDOWPORT */ /* re-work of the status line updating process */ /* #define STATUS_HILITES */ /* support hilites of status fields */ diff --git a/src/pline.c b/src/pline.c index 4ada9bff7..141532cad 100644 --- a/src/pline.c +++ b/src/pline.c @@ -10,6 +10,9 @@ static boolean no_repeat = FALSE; static char prevmsg[BUFSZ]; static char *FDECL(You_buf, (int)); +#if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__)) +static void FDECL(execplinehandler, (const char *)); +#endif /*VARARGS1*/ /* Note that these declarations rely on knowledge of the internals @@ -94,6 +97,11 @@ VA_DECL(const char *, line) flush_screen(1); /* %% */ putstr(WIN_MESSAGE, 0, line); + +#if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__)) + execplinehandler(line); +#endif + /* this gets cleared after every pline message */ iflags.last_msg = PLNMSG_UNKNOWN; strncpy(prevmsg, line, BUFSZ), prevmsg[BUFSZ - 1] = '\0'; @@ -585,4 +593,42 @@ struct obj *otmp2; } } +#if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__)) +static boolean use_pline_handler = TRUE; +static void +execplinehandler(line) +const char *line; +{ + int f; + const char *args[3]; + char *env; + + if (!use_pline_handler) + return; + + if (!(env = nh_getenv("NETHACK_MSGHANDLER"))) { + use_pline_handler = FALSE; + return; + } + + f = fork(); + if (f == 0) { /* child */ + args[0] = env; + args[1] = line; + args[2] = NULL; + (void) setgid(getgid()); + (void) setuid(getuid()); + (void) execv(args[0], (char *const *) args); + perror((char *) 0); + (void) fprintf(stderr, "Exec to message handler %s failed.\n", + env); + terminate(EXIT_FAILURE); + } else if (f == -1) { + perror((char *) 0); + use_pline_handler = FALSE; + pline("Fork to message handler failed."); + } +} +#endif /* defined(POSIX_TYPES) || defined(__GNUC__) */ + /*pline.c*/ diff --git a/util/makedefs.c b/util/makedefs.c index 64f9b7fe5..a20660c7c 100644 --- a/util/makedefs.c +++ b/util/makedefs.c @@ -1350,6 +1350,9 @@ static const char *build_opts[] = { #ifdef HOLD_LOCKFILE_OPEN "exclusive lock on level 0 file", #endif +#if defined(MSGHANDLER) && (defined(POSIX_TYPES) || defined(__GNUC__)) + "external program as a message handler", +#endif #ifdef LOGFILE "log file", #endif