***
*** A patch for teTeX-0.3.5-src
*** enables NeXTTeX style IPC between virtex and dvi previewer (TeXview.app)
***
*** Establishes new command line options for virtex:
***   -v or --ipc : send finished pages immediately to previewer
***   -V or --ipc-start : as above, but start up previewer if not running
***
*** Coded by Tom Rokicki, submitted for inclusion in teTeX by 
*** Gregor Hoffleit <flight@mathi.uni-heidelberg.de>
***

diff -urN /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/kpathsea/cnf.c ./kpse-2.6/kpathsea/cnf.c
--- /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/kpathsea/cnf.c	Sat Nov 26 17:45:30 1994
+++ ./kpse-2.6/kpathsea/cnf.c	Fri Aug  2 21:22:13 1996
@@ -117,11 +117,11 @@
         line++;
     }
   
-  /* Everything up to the next whitespace or eol is the value. */
+  /* The value is whatever remains.  Remove trailing whitespace.  */
   start = line;
-  while (*line && !ISSPACE (*line))
-    line++;
-  len = line - start;
+  len = strlen (start);
+  while (ISSPACE (start[len - 1]) && len > 0)
+    len--;
   
   value = xmalloc (len + 1);
   strncpy (value, start, len);


diff -urN /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/web2c/lib/ipc.c ./kpse-2.6/web2c/lib/ipc.c
--- /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/web2c/lib/ipc.c	Thu Jan  1 01:00:00 1970
+++ ./kpse-2.6/web2c/lib/ipc.c	Fri Aug  2 21:22:23 1996
@@ -0,0 +1,105 @@
+/* ipc for TeX->TeXview communications. */
+#include <sys/types.h>
+#include <sys/socket.h>
+#include <sys/time.h>
+#include <fcntl.h>
+
+#define IPC_PIPE_NAME "/.TeXview_Pipe"
+
+struct msg {
+   short namelength ; /* length of auxilliary data */
+   int eof ;   /* new eof for dvi file */
+   char more_data[0] ; /* where the rest of the stuff goes */ 
+} ;
+
+/* common routines */
+/* extern char *getenv(), *malloc() ; */
+static char *ipc_name ;
+static struct sockaddr *ipc_addr ;
+static int ipc_addr_len ;
+static int ipc_make_name() {
+   char *s ;
+   if (ipc_addr_len == 0) {
+      if ((s = getenv("HOME")) &&
+          (ipc_addr = (struct sockaddr *)malloc(strlen(s) + 40))) {
+         ipc_addr->sa_family = 0 ;
+         ipc_name = ipc_addr->sa_data ;
+         strcpy(ipc_name, s) ;
+         strcat(ipc_name, IPC_PIPE_NAME) ;
+         ipc_addr_len = strlen(ipc_name) + 3 ;
+      }
+   }
+   return ipc_addr_len ;
+}
+
+static int sock = -1 ;
+
+int ipc_is_open() {
+   return sock >= 0 ;
+}
+
+#ifdef TeX
+/* routines for output (for TeX) */
+
+void ipc_open_out() {
+#ifdef DEBUGIPC
+ printf("Trying to open TeX output . . .\n") ;
+#endif
+   if (sock >= 0)
+      return ;
+   if (ipc_make_name() < 0) {
+      sock = -1 ;
+      return ;
+   }
+   if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) >= 0) {
+      if ((connect(sock, ipc_addr, ipc_addr_len) != 0) ||
+          (fcntl(sock, F_SETFL, FNDELAY) == -1)) {
+         close(sock) ;
+         sock = -1 ;
+         return ;
+      }
+#ifdef DEBUGIPC
+ printf("Successfully opened.\n") ;
+#endif
+   }
+}
+
+void ipc_close_out() {
+#ifdef DEBUGIPC
+ printf("Closing TeX output . . .\n") ;
+#endif
+   if (ipc_is_open()) {
+      close(sock) ;
+      sock = -1 ;
+   }
+}
+
+void ipc_snd(n, eof, data)
+int n, eof ;
+char *data ;
+{
+   struct foo {
+      struct msg msg ;
+      char more_data[1024] ;
+   } ourmsg ;
+
+#ifdef DEBUGIPC
+ printf("Trying to send a message . . .\n") ;
+#endif
+   if (! ipc_is_open())
+      return ;
+   ourmsg.msg.namelength = n ;
+   ourmsg.msg.eof = eof ;
+   if (n)
+      strcpy(ourmsg.more_data, data) ;
+   n += sizeof(struct msg) ;
+#ifdef DEBUGIPC
+ printf("Trying a write . . .\n") ;
+#endif
+   if (write(sock, &ourmsg, n) != n)
+      ipc_close_out() ;
+#ifdef DEBUGIPC
+ printf("Returning from send message . . .\n") ;
+#endif
+}
+#endif

diff -urN /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/web2c/lib/texmf.c ./kpse-2.6/web2c/lib/texmf.c
--- /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/web2c/lib/texmf.c	Sun Jul 28 23:44:18 1996
+++ ./kpse-2.6/web2c/lib/texmf.c	Fri Aug  2 21:22:24 1996
@@ -46,6 +46,8 @@
 #include <kpathsea/c-ctype.h>
 #include <kpathsea/c-pathch.h>
 #include <kpathsea/tex-file.h>
+#include <kpathsea/cnf.h>
+#include <kpathsea/variable.h>
 
 /* For `struct tm'.  */
 #include <time.h>
@@ -106,6 +108,9 @@
           dump_default_length = strlen (program_name) + dump_ext_length;
         }
     }
+#ifdef TeX
+    grabargs();
+#endif /* TeX */
 #endif /* not INI */
 
 #ifdef MF
@@ -818,3 +823,119 @@
 #endif /* TRAP */
 }
 #endif /* MF */
+
+/* Finally, the IPC stuff added by tgr */
+#ifdef TeX
+#include "ipc.c" /* where all of the real work is done. */
+
+static char my_realnameoffile[PATH_MAX];
+
+int grabargs() {
+   int i ;
+
+   while (gargc > 1 && gargv[1][0] == '-') {
+      gargc-- ;
+      gargv++ ;
+      if (!strcmp("--ipc",gargv[0])) {
+      	 ipcon = 1;
+      } else if (!strcmp("--ipc-start",gargv[0])) {
+         ipcon = 2;
+      } else switch (gargv[0][1]) {
+case 'v':
+         ipcon = 1 ;
+         break ;
+case 'V':
+         ipcon = 2 ;
+         break ;
+default:
+         printf("I didn't understand option %s\n", gargv[0]) ;
+         break ;
+      }
+   }
+   if (ipcon == 2) {
+/* we try to start TeXview from here if it's not out there already */
+         ipc_open_out() ;
+         if (! ipc_is_open()) {
+            string ipc_server_cmd=getenv("IPCSERVERCMD");
+            if (!ipc_server_cmd)
+               ipc_server_cmd=kpse_cnf_get("IPCSERVERCMD");
+            if (ipc_server_cmd)
+               ipc_server_cmd=kpse_var_expand(ipc_server_cmd);
+            if (system(ipc_server_cmd)==0) {
+               for (i=0; i<20; i++) {
+                  sleep(2) ;
+                  ipc_open_out() ;
+                  if (ipc_is_open())
+                     break ;
+               }
+            }
+         }
+   }
+}
+
+/* This routine notifies the server that there is a new eof.
+   If necessary, it also sends out the new file name.         */
+
+void ipcpage(n)
+int n ;
+{
+   static int begun = 0 ;
+   char *p = "" ;
+   int i ;
+
+   if (! begun) {
+      ipc_open_out() ;
+      p = my_realnameoffile ;
+      getwd(p) ;
+      p += strlen(p) ;
+      *p++ = '/' ;
+      for (i=strstart[jobname]; i<strstart[jobname+1]; i++)
+         *p++ = strpool[i] ;
+      strcpy(p, ".dvi") ;
+      p = my_realnameoffile ;
+      begun = 1 ;
+   }
+   ipc_snd(strlen(p), n, p) ;
+}
+
+
+/* docommand executes a command */
+void docommand(a, b)
+int a, b ;
+{
+   strpool[b] = 0 ;
+   system(strpool + a) ;
+}
+
+#include "config.h"
+
+
+
+#ifndef INI
+
+/* FLIGHT: a uexit that kills the IPC connection.
+           overrides uexit.c;
+	   just for (not-INI)TeX */	   
+
+void
+uexit (unix_code)
+  int unix_code;
+{
+  int final_code;
+
+  if (ipc_is_open() && dviptr + dvioffset)
+     ipcpage(dviptr + dvioffset) ;
+  ipc_close_out() ;
+  
+  if (unix_code == 0)
+    final_code = EXIT_SUCCESS;
+  else if (unix_code == 1)
+    final_code = !EXIT_SUCCESS;
+  else
+    final_code = unix_code;
+  
+  exit (final_code);
+}
+#endif /* INI-TeX */
+
+#endif /* TeX */

diff -urN /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/web2c/lib/texmf.defines ./kpse-2.6/web2c/lib/texmf.defines
--- /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/web2c/lib/texmf.defines	Sun Jul 28 23:44:18 1996
+++ ./kpse-2.6/web2c/lib/texmf.defines	Fri Aug  2 21:22:24 1996
@@ -71,3 +71,6 @@
 
 @define var eqtb;
 @define var mem;
+
+@define procedure ipcpage ();
+@define procedure docommand ();

diff -urN /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/web2c/tex/tex.ch ./kpse-2.6/web2c/tex/tex.ch
--- /tmp/O_teTeX-src-0.3_5/teTeX-src-0.3.5/kpse-2.6/web2c/tex/tex.ch	Thu Jul  6 02:17:49 1995
+++ ./kpse-2.6/web2c/tex/tex.ch	Fri Aug  2 21:22:25 1996
@@ -1239,8 +1239,46 @@
 In C, we use a macro to call |fwrite| or |write| directly, writing all
 the bytes to be written in one shot.  Much better even than writing four
 bytes at a time.
+@^system dependencies@>
+@^inner loop@>
+@^defecation@>
+@z
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% We output each portion of the page as we get to it, if we are using
+% ipc, so that the previewer can see it. <><>
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+
+@x
+dvi_out(eop); incr(total_pages); cur_s:=-1;
+@y
+dvi_out(eop); incr(total_pages); cur_s:=-1;
+if ipc_on > 0 then begin
+   if dvi_limit = half_buf then begin
+      write_dvi(half_buf, dvi_buf_size-1);
+      dvi_gone := dvi_gone + half_buf ;
+   end ;
+   if dvi_ptr > 0 then begin
+      write_dvi(0, dvi_ptr-1) ;
+      dvi_offset := dvi_offset + dvi_ptr ;
+      dvi_gone := dvi_gone + dvi_ptr ;
+   end ;
+   dvi_ptr := 0 ;
+   dvi_limit := dvi_buf_size ;
+   ipc_page(dvi_gone) ;
+end;
+@z
+
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+% We need to fix this modulo 4 calculation here.
+%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
+@x
+  k:=4+((dvi_buf_size-dvi_ptr) mod 4); {the number of 223's}
+@y
+  k:=7-((3+dvi_offset+dvi_ptr) mod 4); {the number of 223's}
 @z
 
+
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
 % [38.859] Fix a casting/expression evaluation problem.
 %%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%%
@@ -1998,6 +2036,7 @@
 @<Glob...@>=
 @!edit_name_start: pool_pointer;
 @!edit_name_length,@!edit_line,@!tfm_temp: integer;
+@!ipc_on: integer; {is ipc on, and if so, at what level?}
 
 @ The |edit_name_start| will be set to point into |str_pool| somewhere after
 its beginning if \TeX\ is supposed to switch to an editor on exit.



