]> granicus.if.org Git - nethack/commitdiff
Add compile-time option MSGHANDLER
authorPasi Kallinen <paxed@alt.org>
Sun, 10 Jan 2016 11:01:46 +0000 (13:01 +0200)
committerPasi Kallinen <paxed@alt.org>
Sun, 10 Jan 2016 11:08:20 +0000 (13:08 +0200)
This was a feature request from a blind player; he wanted to
play a sound whenever a pline message was given.

doc/fixes36.1
include/config.h
src/pline.c
util/makedefs.c

index a14453683c04173ca156cbbf20d16ac08869df0c..c3b17ca0f0cc93c084ddb893c9d95ef604394df2 100644 (file)
@@ -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
index 72f87fb11761826f0496600ecd09aaed56c68729..121ce54079e671bfaa3bf690be1e140681592a78 100644 (file)
@@ -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 */
index 4ada9bff78e2bc2e033537e533a1ad7c468faf6d..141532cadf813fca36f5dcf80c224a6550bf80d2 100644 (file)
@@ -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*/
index 64f9b7fe5acfb393002e728947a1bb501e5bec43..a20660c7c40e9b131ae970e7d8004e76c0e443e0 100644 (file)
@@ -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