From: senda@kuis.kyoto-u.ac.jp (Shuji Senda)
Newsgroups: fj.sources
Subject: xdvi-16jgs(0) (Re: xdvi-14jgs)
Date: 24 Sep 92 08:55:03 GMT
Distribution: fj
Organization: Dept. of Info. Sci., Kyoto Univ
In-Reply-To: hiro@jaist-east.ac.jp's message of Wed, 23 Sep 1992 07:40:46 GMT
Nntp-Posting-Host: cr-x.kuis.kyoto-u.ac.jp


	$B@gED!w5~Bg$G$9!#8F$P$l$?$N$G=P$FMh$^$7$?!#(J

In article <HIRO.92Sep23164046@skywalker.jaist-east.ac.jp>, hiro@jaist-east.ac.jp (Masahiro Morita) writes:

Masahiro> $B$"$H!"(Jxdvi-16j $B$H$$$&$N$,$G$?$=$&$G$9$,!"$3$A$i$X$NBP1~$O$^(J
Masahiro> $B$@9T$J$C$F$$$^$;$s!#(J

Masahiro> $B!t(J $B@gED!w5~Bg>pJs$5$s!"$b$7$h$m$7$1$l$P$3$A$i$K$bEj9F$7$F$b(J
Masahiro> $B$i$($^$9$+!)(J

	$B$H$$$&$o$1$G!"(Jxdvi patch level 16 $BMQ$N(J ASCII-jTeX $BBP1~(J patch
	<NORO.92Sep21190929@otemoyan.iias.flab.fujitsu.co.jp>$B$KBP1~$7(J
	$B$?(J xdvi-16jgs $B$r$*$H$I$1$7$^$9!#(J

	$B$3$l$O!"(J<HIRO.92Sep23164046@skywalker.jaist-east.ac.jp> $B$r$b$H(J
	$B$K!"(J<1992Sep16.132206.17694@kuamp.kyoto-u.ac.jp> $B$rEv$F$k$3$H(J
	$B$G(J epsbox$BBP1~(J $B$r$7$?$b$N$G$9!#(J(epsbox $B$NF0:n$K$D$$$F$OL$3NG'(J)

	$B$5$i$K!"%+%i!<%G%#%9%W%l%$;HMQ;~$K$*$1$k(J -rv $B$X$NBP1~!"(J
	<MARUYAMA.92Sep22214616@sunnm.ism.ac.jp> $B$G;XE&$5$l$F$$$?%-!<(J
	$B%P%$%s%G%#%s%0$r%*%j%8%J%k$KLa$9!"$H$$$C$?JQ99$r9T$C$F$$$^$9!#(J

# -DVI_KEY $B$r;XDj$9$l$P!"(Jxdvi-pl16 $BMQ$N(J ASCII-jTeX $BBP1~(J patch $B$GJQ99$5(J
# $B$l$?(J vi$BIw(J $B%-!<%P%$%s%I$K$J$j$^$9!#(J

	xdvi pl16 $B$K(J ASCII-jTeX $BBP1~(J patch $B$rEv$F$?$b$N$KBP$7$F$5$i$K(J
	$B0J2<$N%Q%C%A$rEv$F$F2<$5$$!#(J

diff -cN xdvi-pl16/Imakefile xdvi-pl16-with-gs/Imakefile
*** xdvi-pl16/Imakefile	Tue Sep 22 16:02:14 1992
--- xdvi-pl16-with-gs/Imakefile	Tue Sep 22 16:14:15 1992
***************
*** 1,7 ****
! DEFAULT_FONT_PATH=.:/usr/share/lib/tex/pk/pk300:/usr/share/lib/tex/pk/jpk300
  DEFAULT_VF_PATH=
  DEFAULT_FONT_SIZES=240:300:328.6:360:432:518.4:622:746.4:895.8:1075
  DEFS=-DUSE_PK -DUSE_GF -DUSE_PXL -DMSBITFIRST -DBMSHORT -DBUTTONS -DGREY -DMAKEPK
  
  DEPLIBS=XawClientDepLibs
  LOCAL_LIBRARIES=XawClientLibs
--- 1,15 ----
! 
! #define	PS
! 
! DEFAULT_FONT_PATH=.:/usr/local/lib/tex/fonts:/usr/local/lib/tex/jfonts
  DEFAULT_VF_PATH=
  DEFAULT_FONT_SIZES=240:300:328.6:360:432:518.4:622:746.4:895.8:1075
+ 
+ #ifdef PS
+ DEFS=-DUSE_PK -DUSE_GF -DUSE_PXL -DMSBITFIRST -DBMSHORT -DBUTTONS -DGREY -DMAKEPK -DPS -DEPSBOX
+ #else
  DEFS=-DUSE_PK -DUSE_GF -DUSE_PXL -DMSBITFIRST -DBMSHORT -DBUTTONS -DGREY -DMAKEPK
+ #endif
  
  DEPLIBS=XawClientDepLibs
  LOCAL_LIBRARIES=XawClientLibs
***************
*** 8,15 ****
  MATHLIB=-lm
  SYS_LIBRARIES=$(MATHLIB)
  LINTLIBS=$(LINTXAW) $(LINTXMU) $(LINTXTOOL) $(LINTEXTENSIONLIB) $(LINTXLIB) -lm
! SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c tpic.c
! OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o tpic.o
  DEFINES=$(DEFS) -DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\" \
    -DDEFAULT_VF_PATH=\"$(DEFAULT_VF_PATH)\" \
    -DDEFAULT_FONT_SIZES=\"$(DEFAULT_FONT_SIZES)\" \
--- 16,35 ----
  MATHLIB=-lm
  SYS_LIBRARIES=$(MATHLIB)
  LINTLIBS=$(LINTXAW) $(LINTXMU) $(LINTXTOOL) $(LINTEXTENSIONLIB) $(LINTXLIB) -lm
! 
! #ifdef PS
! #define	PS_SRC	gs-view.c ps.c
! #define	PS_OBJ	gs-view.o ps.o
! #else
! #define	PS_SRC
! #define	PS_OBJ
! #endif
! 
! SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c \
!      PS_SRC tpic.c
! OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o \
!      PS_OBJ tpic.o
! 
  DEFINES=$(DEFS) -DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\" \
    -DDEFAULT_VF_PATH=\"$(DEFAULT_VF_PATH)\" \
    -DDEFAULT_FONT_SIZES=\"$(DEFAULT_FONT_SIZES)\" \
diff -cN xdvi-pl16/Makefile xdvi-pl16-with-gs/Makefile
*** xdvi-pl16/Makefile	Sun Feb 16 07:57:00 1992
--- xdvi-pl16-with-gs/Makefile	Tue Sep 22 16:11:39 1992
***************
*** 4,18 ****
  # $Header: Makefile,v 1.2 87/05/14 14:05:34 eichin Locked $
  # $Source: /u1/uus/vs2/xdvi/RCS/Makefile,v $
  #
! DEFAULT_FONT_PATH=/usr/local/tex/fonts
  DEFAULT_VF_PATH=/usr/local/tex/fonts/vf
  DEFAULT_FONT_SIZES=300:328.6:360:432:518.4:622:746.4
! DEFS=-DUSE_PK -DMSBITFIRST -DBMSHORT -DBUTTONS
  FONTDEFINES=-DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\" \
    -DDEFAULT_VF_PATH=\"$(DEFAULT_VF_PATH)\" \
    -DDEFAULT_FONT_SIZES=\"$(DEFAULT_FONT_SIZES)\" \
    -DDEFAULT_SUBDIR_PATH=\"$(DEFAULT_SUBDIR_PATH)\"
! TOP=/usr/X11
  INCDIR=$(TOP)/include
  LIBDIR=$(TOP)/lib
  XMULIB=-lXmu
--- 4,18 ----
  # $Header: Makefile,v 1.2 87/05/14 14:05:34 eichin Locked $
  # $Source: /u1/uus/vs2/xdvi/RCS/Makefile,v $
  #
! DEFAULT_FONT_PATH=/usr/local/lib/tex/fonts:/usr/local/lib/tex/jfonts/dm:/usr/local/lib/tex/jfonts/dg:/usr/local/lib/tex/local.fonts
  DEFAULT_VF_PATH=/usr/local/tex/fonts/vf
  DEFAULT_FONT_SIZES=300:328.6:360:432:518.4:622:746.4
! DEFS=-DUSE_PK -DMSBITFIRST -DBMSHORT -DBUTTONS -DPS
  FONTDEFINES=-DDEFAULT_FONT_PATH=\"$(DEFAULT_FONT_PATH)\" \
    -DDEFAULT_VF_PATH=\"$(DEFAULT_VF_PATH)\" \
    -DDEFAULT_FONT_SIZES=\"$(DEFAULT_FONT_SIZES)\" \
    -DDEFAULT_SUBDIR_PATH=\"$(DEFAULT_SUBDIR_PATH)\"
! TOP=/usr/local/X11R5
  INCDIR=$(TOP)/include
  LIBDIR=$(TOP)/lib
  XMULIB=-lXmu
***************
*** 22,32 ****
  MANDIR=$(DESTDIR)/man
  INCLUDES=-I$(INCDIR)
  CFLAGS=-O $(INCLUDES) $(DEFS)
! LIBS=-L$(LIBDIR) -lXaw $(XMULIB) -lXt $(EXTENSIONLIB) -lX11 -lm
  #LIBS=-L$(LIBDIR) -lX11 -lm
! SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c tpic.c
! OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o tpic.o
! CC=gcc
  LINT=lint
  # LINT=$(CC) -c -Wall -Wshadow -Wpointer-arith
  # also maybe -Wcast-qual -Wwrite-strings
--- 22,32 ----
  MANDIR=$(DESTDIR)/man
  INCLUDES=-I$(INCDIR)
  CFLAGS=-O $(INCLUDES) $(DEFS)
! LIBS=-L$(LIBDIR) -lXaw $(XMULIB) -lXt $(EXTENSIONLIB) -lX11 -lm -lXwchar
  #LIBS=-L$(LIBDIR) -lX11 -lm
! SRCS=xdvi.c dvi_init.c dvi_draw.c fontfmts.c vf.c util.c font_open.c ps.c gs-view.c tpic.c
! OBJS=xdvi.o dvi_init.o dvi_draw.o fontfmts.o vf.o util.o font_open.o ps.o gs-view.o tpic.o
! CC=cc
  LINT=lint
  # LINT=$(CC) -c -Wall -Wshadow -Wpointer-arith
  # also maybe -Wcast-qual -Wwrite-strings
***************
*** 42,50 ****
  xdvi.o: xdvi.h patchlevel.h xdvi.icon
  dvi_init.o:xdvi.h dvi.h
  dvi_draw.o:xdvi.h dvi.h
- tpic.o:	xdvi.h
  fontfmts.o: xdvi.h pk.c gf.c pxl.c
  util.o:	xdvi.h
  
  font_open.o:	font_open.c xdvi.h
  	$(CC) -c $(CFLAGS) $(FONTDEFINES) font_open.c
--- 42,51 ----
  xdvi.o: xdvi.h patchlevel.h xdvi.icon
  dvi_init.o:xdvi.h dvi.h
  dvi_draw.o:xdvi.h dvi.h
  fontfmts.o: xdvi.h pk.c gf.c pxl.c
  util.o:	xdvi.h
+ ps.o: gs-view.h xdvi.h
+ gs-view.o: gs-view.h xdvi.h
  
  font_open.o:	font_open.c xdvi.h
  	$(CC) -c $(CFLAGS) $(FONTDEFINES) font_open.c
diff -cN xdvi-pl16/gs-view.c xdvi-pl16-with-gs/gs-view.c
*** xdvi-pl16/gs-view.c
--- xdvi-pl16-with-gs/gs-view.c	Thu Sep 24 16:50:54 1992
***************
*** 0 ****
--- 1,194 ----
+ /*
+  *	gs-view.c
+  *
+  *		by hiro@jaist-east.ac.jp
+  *
+  *	$Date: 1992/09/16 04:42:23 $
+  *	$Revision: 1.4 $
+  */
+ 
+ #include <stdio.h>
+ #include <sys/stat.h>
+ #include <fcntl.h>
+ #include <sys/types.h>
+ #include <X11/X.h>
+ #include <X11/Intrinsic.h>
+ #include <X11/StringDefs.h>
+ #include <X11/Xatom.h>
+ #include <X11/Xmu/Atoms.h>
+ #include <signal.h>
+ 
+ #include "gs-view.h"
+ 
+ #define	GHOSTSCRIPT	"gs"
+ 
+ #define	DEV_NULL	"/dev/null"
+ 
+ static char*	RCS_ID = "$Header: /tmp_mnt/home/fs015/hiro/src/xdvi-14j-ps/RCS/gs-view.c,v 1.4 1992/09/16 04:42:23 hiro Exp $";
+ 
+ struct gs_prop {
+     Window	parent;
+     Atom	GS_DONE;
+     Atom	GS_PAGE;
+ };
+ 
+ static Boolean	check_gs_event(disp, event, props)
+  Display*	disp;
+  XEvent*	event;
+  struct gs_prop*	props;
+ {
+     if (event-> type == ClientMessage &&
+ 	event-> xclient.window == props-> parent &&
+ 	event-> xclient.send_event == TRUE) {
+ #ifdef DEBUG_XDVI_PS
+ 	printf("caught ClientMessage event\n");
+ #endif
+ 	if (event-> xclient.message_type == props-> GS_DONE ||
+ 	    event-> xclient.message_type == props-> GS_PAGE)
+ 	  return TRUE;
+     }
+     else
+       return FALSE;
+ }
+ 
+ int	psfig_to_bitmap(gs)
+  struct gs_info*	gs;
+ {
+     char	param[BUFSIZ];
+ 
+     sprintf(param, "0 0 %d %d %d %d %f %f 0 0 0 0 %d %d",
+ 	    (int)gs-> llx, (int)gs-> lly, (int)gs-> urx, (int)gs-> ury,
+ 	    gs-> width  / ((gs-> urx - gs-> llx) / 72.0),
+ 	    gs-> height / ((gs-> ury - gs-> lly) / 72.0),
+ 	    gs-> width, gs-> height);
+     XChangeProperty(gs-> disp, gs-> parent,
+ 		    XInternAtom(gs-> disp, "GHOSTVIEW", FALSE), XA_STRING,
+ 		    8, PropModeReplace, param, strlen(param));
+ 
+ #ifdef DEBUG
+     printf("property:%s\n", param);
+ #endif
+ 
+     if ((gs-> gs_pid = fork()) == 0) {
+ 	/* child */
+ 	static char	env[BUFSIZ];
+ 	char*	argv[6];
+ 	int	i;
+ 	int	pipe[2];
+ 
+ 	sprintf(env, "DISPLAY=%s", XDisplayString(gs-> disp));
+ 	putEnv(strDup(env));
+ 	sprintf(env, "GHOSTVIEW=%d %d", gs-> parent, gs-> pix);
+ 	putEnv(strDup(env));
+ 
+ #ifdef DEBUG
+ 	printf("getenv:%s\n", getenv("DISPLAY"));
+ 	printf("getenv:%s\n", getenv("GHOSTVIEW"));
+ #endif
+ 
+ 	i = 0;
+ 	argv[i++] = GHOSTSCRIPT;
+ 	argv[i++] = "-dQUIET";
+ 	argv[i++] = "-dNOPAUSE";
+ 	argv[i++] = gs-> psfile;
+ 	argv[i++] = NULL;
+ 
+ 	for (i = 3; i < 20; i ++)
+ 	  close(i);
+ 
+ 	dup2(open(DEV_NULL, O_RDONLY), 0); /* redirect stdin to /dev/null */
+ 
+ #ifdef DEBUG_XDVI_PS
+ 	printf("gs:exec-ed\n");
+ #endif
+ 	if (execvp(GHOSTSCRIPT, argv)) {
+ 	    perror("gs");
+ 	    exit(-1);
+ 	}
+     }
+     else {
+ 	/* parent */
+ 	XEvent	ev;
+ 	struct gs_prop	props;
+ 
+ 	props.parent = gs-> parent;
+ 	props.GS_DONE = XInternAtom(gs-> disp, "DONE", False);
+ 	props.GS_PAGE = XInternAtom(gs-> disp, "PAGE", False);
+ 
+ 	XIfEvent(gs-> disp, & ev, check_gs_event, & props);
+ #ifdef DEBUG
+ 	if (ev.xclient.message_type == props.GS_DONE ||
+ 	    ev.xclient.message_type == props.GS_PAGE) {
+ 	    printf("caught event:GS_DONE or GS_PAGE\n");
+ 	    printf("mess:%s\n", ev.xclient.data.b);
+ 	}
+ 	else
+ 	  printf("caught another event\n");
+ #endif
+ 	kill(gs-> gs_pid, SIGTERM);
+ 	wait(NULL);
+     }
+     return 0;
+ }
+ 
+ #ifdef DEBUG
+ void	main(argc, argv)
+  int	argc;
+  char**	argv;
+ {
+     struct gs_info	gs;
+     GC	gc;
+     int 	screen;
+ 
+     gs.width = 400;
+     gs.height = 400;
+ 
+     gs.disp = XOpenDisplay("");
+     screen = DefaultScreen();
+     gs.parent = XCreateSimpleWindow(gs.disp, DefaultRootWindow(gs.disp),
+ 				    0, 0, gs.width, gs.height, 1,
+ 				    BlackPixel(gs.disp, screen),
+ 				    BlackPixel(gs.disp, screen));
+     XMapWindow(gs.disp, gs.parent);
+ 
+     gc = XCreateGC(gs.disp, gs.parent, 0, 0);
+     XSetForeground(gs.disp, gc, WhitePixel(gs.disp, screen));
+     XSetBackground(gs.disp, gc, BlackPixel(gs.disp, screen));
+ 
+     XFlush(gs.disp);
+ 
+     gs.psfile = argv[1];
+     get_bounding_box(gs.psfile, & gs.llx, & gs.lly, & gs.urx, & gs.ury);
+ 
+     printf("bounding box: llx:%d lly:%d urx:%d ury:%d\n",
+ 	   (int)gs.llx, (int)gs.lly, (int)gs.urx, (int)gs.ury);
+ 
+     gs.pix = XCreatePixmap(gs.disp, gs.parent, gs.width, gs.height, 1);
+ 
+     psfig_to_bitmap(& gs);
+ 
+     XCopyArea(gs.disp, gs.pix, gs.parent, gc,
+ 	      0, 0, 400, 400, 0, 0);
+     XFlush(gs.disp);
+ 
+     getchar();
+ 
+     exit(0);
+ }
+ #endif
+ 
+ /*
+  * $Log: gs-view.c,v $
+  * Revision 1.4  1992/09/16  04:42:23  hiro
+  * bug fix: bounding box.
+  *
+  * Revision 1.3  1992/09/10  12:28:55  hiro
+  * redirect stdin to /dev/null.
+  *
+  * Revision 1.2  1992/09/01  10:36:56  hiro
+  * change putenv() and strdup().
+  *
+  * Revision 1.1  1992/08/29  09:22:45  hiro
+  * Initial revision
+  *
+  */
diff -cN xdvi-pl16/gs-view.h xdvi-pl16-with-gs/gs-view.h
*** xdvi-pl16/gs-view.h
--- xdvi-pl16-with-gs/gs-view.h	Tue Sep 22 02:18:18 1992
***************
*** 0 ****
--- 1,49 ----
+ /*
+  *	gs-view.h
+  *
+  *		by hiro@jaist-east.ac.jp
+  *
+  *	$Date: 1992/09/01 08:12:26 $
+  *	$Revision: 1.2 $
+  */
+ 
+ #ifndef X_H
+ #define Pixmap	unsigned long
+ #endif
+ 
+ struct bitmap_info {
+     Pixmap	bitmap;
+     unsigned int	width, height;
+ };
+ 
+ #ifdef X_H
+ struct	gs_info {
+     Display*	disp;
+     Window	parent;
+     char*	psfile;
+     Pixmap	pix;
+     unsigned int	width, height;
+     float	llx, lly;
+     float	urx, ury;
+     FILE*	gs_out;
+     int 	gs_pid;
+ };
+ #endif
+ 
+ struct psfig_info {
+     char*	filename;
+     float	llx, lly;
+     float	urx, ury;
+     float	hscale, vscale;
+     struct bitmap_info	fig[4];
+ };
+ 
+ /*
+  * $Log: gs-view.h,v $
+  * Revision 1.2  1992/09/01  08:12:26  hiro
+  * change 'pid_t' to 'int'.
+  *
+  * Revision 1.1  1992/08/29  09:21:34  hiro
+  * Initial revision
+  *
+  */
diff -cN xdvi-pl16/ps.c xdvi-pl16-with-gs/ps.c
*** xdvi-pl16/ps.c
--- xdvi-pl16-with-gs/ps.c	Thu Sep 24 16:49:27 1992
***************
*** 0 ****
--- 1,212 ----
+ /*
+  *	ps.c
+  *
+  *		by hiro@jaist-east.ac.jp
+  *
+  *	$Revision: 1.5 $
+  *	$Date: 1992/09/16 04:43:56 $
+  */
+ 
+ #include <stdio.h>
+ #include <string.h>
+ 
+ #include "xdvi.h"
+ 
+ #include "gs-view.h"
+ 
+ char*	dirname(f1, f2)
+  char*	f1;
+  char*	f2;
+ {
+     char*	p1;
+     char*	p2;
+     char*	p3;
+     static char	buf[BUFSIZ];
+ 
+     for (p2 = buf, p1 = f1, p3 = f1; *f1; f1 ++, p2 ++) {
+ 	if (*f1 == '/')
+ 	  p1 = f1 + 1;
+ 	*p2 = *f1;
+     }
+     strcpy(buf + (p1 - p3), f2);
+ 
+     return buf;
+ }
+ 
+ int	get_bounding_box(psfile, llx, lly, urx, ury)
+  char*	psfile;
+  float*	llx;
+  float*	lly;
+  float*	urx;
+  float*	ury;
+ {
+     FILE*	fptr;
+     char	buf[BUFSIZ];
+ 
+     if ((fptr = fopen(psfile, "r")) == NULL)
+ 	if ((fptr = xfopen(psfile)) == NULL) {
+ 	    perror(psfile);
+ 	    return -1;
+ 	}
+ 
+     do {
+ 	if (fgets(buf, BUFSIZ, fptr) == NULL) {
+ 	    fprintf(stderr, "%s:unexpected EOF.\n", psfile);
+ 	    return -1;
+ 	}
+ 	if (strncmp(buf, "%%BoundingBox:", 14) == 0) {
+ 	    sscanf(buf + 14, "%f %f %f %f", llx, lly, urx, ury);
+ 	    break;
+ 	}
+     }	while(1);
+ 
+     fclose(fptr);
+ 
+     return 0;
+ }
+ 
+ int	strrncmp(s1, s2, n)
+  char*	s1;
+  char*	s2;
+  int	n;
+ {
+     char*	sl1;
+     char*	sl2;
+ 
+     sl1 = s1 + strlen(s1) - 1;
+     sl2 = s2 + strlen(s2) - 1;
+     for ( ; n != 0 && *sl1 == *sl2; n --, sl1 --, sl2 --)
+       ;
+     return n;
+ }
+ 
+ int	psSpecial(cp)
+  char*	cp;
+ {
+     struct psfig_info	psfile;
+     char*	ptr;
+     float 	hsize = 0.0, vsize = 0.0;
+     float	hscale = 0.0, vscale = 0.0;
+     double	atof();
+ 
+     psfile.filename = NULL;
+ #ifdef EPSBOX
+     if (strncmp(cp, "postscriptbox",strlen("postscriptbox")) == 0) {
+ 	    ptr = strtok(cp, "{}");
+ 	    if (ptr = strtok(NULL, "{}")) {
+ 		    hsize = atof(ptr);
+ 	    } else {
+ 		    fprintf(stderr, "\\special:ERROR.\n");
+ 	    }
+ 	    if (ptr = strtok(NULL, "{}")) {
+ 		    vsize = atof(ptr);
+ 	    } else {
+ 		    fprintf(stderr, "\\special:ERROR.\n");
+ 	    }
+ 	    psfile.filename = dirname(dvi_name, strtok(NULL, "{}"));
+ 	    if (get_bounding_box(psfile.filename,
+ 				 & psfile.llx, & psfile.lly,
+ 				 & psfile.urx, & psfile.ury)) {
+ 		    return 1;
+ 	    }
+ 	    if (psfile.filename == NULL) {
+ 		fprintf(stderr, "\\special:ERROR.\n");
+ 		return 1;
+ 	    }
+ 	    if (hsize != 0.0)
+ 	      hscale = hsize / (psfile.urx - psfile.llx);
+ 	    if (vsize != 0.0)
+ 	      vscale = vsize / (psfile.ury - psfile.lly);
+ 	    if (hscale == 0.0)
+ 	      hscale = vscale;
+ 	    if (vscale == 0.0)
+ 	      vscale = hscale;
+ 	    if (hscale == 0.0 && vscale == 0.0) {
+ 		psfile.hscale = 1.0;
+ 		psfile.vscale = 1.0;
+ 	    }
+ 	    else {
+ 		psfile.hscale = hscale;
+ 		psfile.vscale = vscale;
+ 	    }
+ 	    draw_ps(& psfile, PXL_H, (int)(PXL_V - vsize));
+     } else {
+ #endif
+     ptr = strtok(cp, " =");
+     while (ptr != NULL) {
+ 	if (strrncmp(ptr, "file", 4) == 0) {
+ 	    psfile.filename = dirname(dvi_name, strtok(NULL, " "));
+ 	    if (get_bounding_box(psfile.filename,
+ 				 & psfile.llx, & psfile.lly,
+ 				 & psfile.urx, & psfile.ury))
+ 	      return 1;
+ 	}
+ 	else if (strcmp(ptr, "hsize") == 0)
+ 	  hsize = atof(strtok(NULL, " "));
+ 	else if (strcmp(ptr, "vsize") == 0)
+ 	  vsize = atof(strtok(NULL, " "));
+ 	else if (strcmp(ptr, "hscale") == 0) {
+ 	    hscale = atof(strtok(NULL, " "));
+ 	    if (vscale == 0.0)
+ 	      vscale = hscale;
+ 	}
+ 	else if (strcmp(ptr, "vscale") == 0) {
+ 	    vscale = atof(strtok(NULL, " "));
+ 	    if (hscale == 0.0)
+ 	      hscale = vscale;
+ 	}
+ 	ptr = strtok(NULL, " =");
+     }
+     if (psfile.filename == NULL) {
+ 	fprintf(stderr, "\\special:ERROR.\n");
+ 	return 1;
+     }
+     if (hsize != 0.0)
+       hscale = hsize / (psfile.urx - psfile.llx);
+     if (vsize != 0.0)
+       vscale = vsize / (psfile.ury - psfile.lly);
+     if (hscale == 0.0)
+       hscale = vscale;
+     if (vscale == 0.0)
+       vscale = hscale;
+     if (hscale == 0.0 && vscale == 0.0) {
+ 	psfile.hscale = 1.0;
+ 	psfile.vscale = 1.0;
+     }
+     else {
+ 	psfile.hscale = hscale;
+ 	psfile.vscale = vscale;
+     }
+ 
+     draw_ps(& psfile, PXL_H, PXL_V);
+ #ifdef EPSBOX
+     }
+ #endif
+     return 0;
+ }
+ 
+ #ifdef DEBUG
+ main()
+ {
+     applicationDoSpecial("psfile=fig1.ps hscale=0.5 vsize=100");
+ }
+ #endif
+ 
+ /*
+  * $Log: ps.c,v $
+  * Revision 1.5  1992/09/16  04:43:56  hiro
+  * bug fix: bounding box.
+  *
+  * Revision 1.4  1992/09/01  10:35:37  hiro
+  * support TPIC.
+  *
+  * Revision 1.3  1992/08/31  08:40:38  hiro
+  * change 'get_bounding_box()'.
+  *
+  * Revision 1.2  1992/08/31  07:59:04  hiro
+  * change search path for PS file.
+  *
+  * Revision 1.1  1992/08/29  09:23:04  hiro
+  * Initial revision
+  *
+  */
diff -cN xdvi-pl16/tpic.c xdvi-pl16-with-gs/tpic.c
*** xdvi-pl16/tpic.c	Tue Sep 22 00:06:47 1992
--- xdvi-pl16-with-gs/tpic.c	Tue Sep 22 02:19:52 1992
***************
*** 428,433 ****
--- 428,436 ----
  	else if (strcmp(command, "bk") == 0) blacken_last();
  	/* throw away the path -- jansteen */
  	else if (strcmp(command, "ip") == 0) path_len = 0;
+ #ifdef PS
+ 	else if (psSpecial(orig_cp) == 0);
+ #endif
  	else if (!hush_spec_now)
  	    Fprintf(stderr, "%s:  special \"%s\" not implemented\n", prog,
  		orig_cp);
diff -cN xdvi-pl16/util.c xdvi-pl16-with-gs/util.c
*** xdvi-pl16/util.c	Tue Sep 22 16:02:16 1992
--- xdvi-pl16-with-gs/util.c	Tue Sep 22 02:18:29 1992
***************
*** 211,213 ****
--- 211,258 ----
  	while (--size) x = (x << 8) | one(fp);
  	return x;
  }
+ 
+ #ifdef PS
+ 
+ /*
+  *
+  */
+ 
+ extern char**	environ;
+ 
+ char*	strDup(str)
+  char*	str;
+ {
+     char*	ptr = xmalloc(strlen(str), "strdup");
+ 
+     return strcpy(ptr, str);
+ }
+ 
+ #ifdef BCOPY
+ #define	memcpy(a, b, n)	bcopy(b, a, n)
+ #endif
+ 
+ void	putEnv(env)
+  char*	env;
+ {
+     int 	i, n;
+ 
+     for (i = 0; env[i] != '='; i ++)
+       ;
+     i ++;
+     for (n = 0; environ[n]; n ++) {
+ 	if (strncmp(environ[n], env, i) == 0)
+ 	  break;
+     }
+     if (environ[n] == NULL) {
+ 	char**	ptr = (void*)xmalloc(sizeof(char*) * (n + 2), "putenv");
+ 
+ 	memcpy(ptr, environ, sizeof(char*) * n);
+ 	environ = ptr;
+ 	environ[n] = env;
+ 	environ[n+1] = NULL;
+     }
+     else
+       environ[n] = env;
+ }
+ #endif
diff -cN xdvi-pl16/xdvi.c xdvi-pl16-with-gs/xdvi.c
*** xdvi-pl16/xdvi.c	Tue Sep 22 16:02:17 1992
--- xdvi-pl16-with-gs/xdvi.c	Thu Sep 24 17:10:47 1992
***************
*** 235,240 ****
--- 235,243 ----
  	Boolean	expert;
  #endif
  	int	mg_size[5];
+ #ifdef PS
+ 	Boolean	use_ps_special;
+ #endif
  #ifdef	GREY
  	Boolean	use_grey;
  #endif
***************
*** 725,730 ****
--- 728,914 ----
  {
  }
  
+ #ifdef PS
+ 
+ #include <sys/stat.h>
+ #include "gs-view.h"
+ 
+ #define	PSFIG_CACHE_SIZE	16
+ 
+ char* strDup();
+ 
+ struct psfig_cache_struct {
+     Pixmap	pix;
+ 
+     char*	psfile;
+     unsigned int	width, height;
+     time_t	ps_time;
+ 
+     struct psfig_cache_struct*	next;
+ }	psfig_cache[] = 
+ {{ 0, NULL, 0, 0, 0, NULL }, { 0, NULL, 0, 0, 0, NULL }, 
+  { 0, NULL, 0, 0, 0, NULL }, { 0, NULL, 0, 0, 0, NULL }, 
+  { 0, NULL, 0, 0, 0, NULL }, { 0, NULL, 0, 0, 0, NULL }, 
+  { 0, NULL, 0, 0, 0, NULL }, { 0, NULL, 0, 0, 0, NULL }, 
+  { 0, NULL, 0, 0, 0, NULL }, { 0, NULL, 0, 0, 0, NULL }, 
+  { 0, NULL, 0, 0, 0, NULL }, { 0, NULL, 0, 0, 0, NULL }, 
+  { 0, NULL, 0, 0, 0, NULL }, { 0, NULL, 0, 0, 0, NULL }, 
+  { 0, NULL, 0, 0, 0, NULL }, { 0, NULL, 0, 0, 0, NULL }};
+ 
+ static Boolean	use_ps_special;
+ 
+ Pixmap	get_cached_psfig(psfile, width, height, flag)
+  char*	psfile;
+  unsigned int	width, height;
+  Boolean	flag;
+ {
+     int 	i;
+     int 	hash = 0;
+     struct psfig_cache_struct*	cache;
+     struct stat	buf;
+ 
+     for (i = 0; psfile[i]; i ++)
+       hash += psfile[i];
+     hash += width + height;
+     hash %= PSFIG_CACHE_SIZE;
+ 
+     stat(psfile, & buf);
+ 
+     for (cache = & psfig_cache[hash]; cache; cache = cache-> next)
+       if (cache-> width  == width  &&
+ 	  cache-> height == height &&
+ 	  strcmp(cache-> psfile, psfile) == 0) {
+ 	  if (cache-> ps_time == buf.st_mtime)
+ 	    return cache-> pix;
+ 	  else {
+ 	      free(cache-> psfile);
+ 	      XFreePixmap(DISP, cache-> pix);
+ 	      cache-> pix = (Pixmap)0;
+ 	      return (Pixmap)0;
+ 	  }
+       }
+     return 0;
+ }
+ 
+ void	put_cache_psfig(pix, psfile, width, height)
+  Pixmap	pix;
+  char*	psfile;
+  unsigned int	width, height;
+ {
+     int 	i;
+     int 	hash = 0;
+     struct psfig_cache_struct*	cache;
+     struct stat	buf;
+ 
+     for (i = 0; psfile[i]; i ++)
+       hash += psfile[i];
+     hash += width + height;
+     hash %= PSFIG_CACHE_SIZE;
+ 
+     stat(psfile, & buf);
+ 
+     if (psfig_cache[hash].pix == 0) {
+ 	psfig_cache[hash].pix    = pix;
+ 	psfig_cache[hash].psfile = strDup(psfile);
+ 	psfig_cache[hash].width  = width;
+ 	psfig_cache[hash].height = height;
+ 	psfig_cache[hash].next   = NULL;
+ 	psfig_cache[hash].ps_time= buf.st_mtime;
+     }
+     else {
+ 	for (cache = & psfig_cache[hash]; cache-> next; cache = cache-> next)
+ 	  if (cache-> width  == width  &&
+ 	      cache-> height == height &&
+ 	      strcmp(cache-> psfile, psfile) == 0) {
+ 	      if (cache-> pix == (Pixmap)0)
+ 		cache-> pix = pix;
+ 	      cache-> ps_time = buf.st_mtime;
+ 	      return ;
+ 	  }
+ 	cache-> next = (void*)xmalloc(sizeof(struct psfig_cache_struct),
+ 				      "caching PSfig");
+ 	cache-> next-> pix    = pix;
+ 	cache-> next-> psfile = psfile;
+ 	cache-> next-> width  = width;
+ 	cache-> next-> height = height;
+ 	cache-> next-> next   = NULL;
+ 	cache-> next-> ps_time= buf.st_mtime;
+     }
+ }
+ 
+ void	draw_ps(psfile, x, y)
+  struct psfig_info*	psfile;
+  int	x, y;
+ {
+     struct gs_info	gs;
+     int 	cx = x,
+                 cy = y;
+     static GC	pix_gc = 0;
+     static GC	win_gc = 0;
+ 
+     gs.psfile = psfile-> filename;
+ 
+     gs.width  = (psfile-> urx - psfile-> llx) * psfile-> hscale / 72.0
+       * specialConv * 1000.0 / shrink_factor;
+     gs.height = (psfile-> ury - psfile-> lly) * psfile-> vscale / 72.0
+       * specialConv * 1000.0 / shrink_factor;
+ 
+     if (use_ps_special) {
+ 	gs.pix = get_cached_psfig(gs.psfile, gs.width, gs.height);
+ 	if (gs.pix == 0) {
+ 	    gs.disp = DISP;
+ 	    gs.parent = WINDOW(currwin);
+ 	    gs.pix = XCreatePixmap(DISP, WINDOW(currwin),
+ 				   gs.width, gs.height,
+ 				   DefaultDepthOfScreen(SCRN));
+ 	    gs.llx = psfile-> llx;
+ 	    gs.lly = psfile-> lly;
+ 	    gs.urx = psfile-> urx;
+ 	    gs.ury = psfile-> ury;
+ 
+ 	    psfig_to_bitmap(& gs);
+ 	    if (RESOURCE(reverse) && DefaultDepthOfScreen(SCRN) > 1) {
+ 		if (win_gc == 0) {
+ 		    win_gc = XCreateGC(DISP, gs.pix, 0, NULL);
+ 		    XSetForeground(DISP, win_gc, WhitePixelOfScreen(SCRN) ^ BlackPixelOfScreen(SCRN));
+ 		    XSetFunction(DISP, win_gc, GXxor);
+ 		}
+ 		XFillRectangle(DISP, gs.pix,
+ 			       win_gc, 0, 0, gs.width, gs.height);
+ 	    }
+ 
+ 	    put_cache_psfig(gs.pix, gs.psfile, gs.width, gs.height);
+ 	}
+ 
+ 	if (pix_gc == 0) {
+ 	    pix_gc = XCreateGC(DISP, WINDOW(currwin), 0, 0);
+ 	    XCopyGC(DISP, foreGC,
+ 		    GCFunction | GCForeground | GCBackground, pix_gc);
+ 	    
+ 	    if (DefaultDepthOfScreen(SCRN) > 1) {
+ 		XSetFunction(DISP, pix_gc, GXcopy);
+ 	    } else if (WhitePixelOfScreen(SCRN) == 1) {
+ 		if (RESOURCE(reverse)) {
+ 		    XSetFunction(DISP, pix_gc, GXorInverted);
+ 		} else {
+ 		    XSetFunction(DISP, pix_gc, GXand);
+ 		}
+ 	    }
+ 	}
+ 
+ 	XCopyArea(DISP, gs.pix, WINDOW(currwin), pix_gc,
+ 		  0, 0, gs.width, gs.height,
+ 		  cx - currwin.base_x, cy - currwin.base_y);
+     }
+     else {
+ 	XDrawRectangle(DISP, WINDOW(currwin), ruleGC,
+ 		       cx - currwin.base_x, cy - currwin.base_y,
+ 		       gs.width - 1, gs.height - 1);
+     }
+ }
+ 
+ #endif PS
+ 
  /*
   *	Put a rectangle on the screen.  hl determines the GC.
   */
***************
*** 1493,1499 ****
--- 1677,1687 ----
  	    case 'P':		/* declare current page */
  		pageno_correct = arg0 * number0 - current_page;
  		return;
+ #ifdef	VI_KEY
  	    case 'K':		/* toggle keep-position flag */
+ #else
+ 	    case 'k':		/* toggle keep-position flag */
+ #endif
  		RESOURCE(keep_flag) = (arg0 ? number0 : !RESOURCE(keep_flag));
  		return;
  	    case '\f':
***************
*** 1503,1524 ****
--- 1691,1728 ----
  		home(True);
  		return;
  #ifdef	TOOLKIT
+ #ifdef	VI_KEY
  	    case 'h':
+ #else
+ 	    case 'l':
+ #endif
  		if (!x_bar) goto bad;
  		XtCallCallbacks(x_bar, XtNscrollProc,
  		    (XtPointer) (-2 * (int) clip_w / 3));
  		return;
+ #ifdef	VI_KEY
  	    case 'l':
+ #else
+ 	    case 'r':
+ #endif
  		if (!x_bar) goto bad;
  		XtCallCallbacks(x_bar, XtNscrollProc,
  		    (XtPointer) (2 * (int) clip_w / 3));
  		return;
+ #ifdef	VI_KEY
  	    case 'k':
+ #else
+ 	    case 'u':
+ #endif
  		if (!y_bar) goto bad;
  		XtCallCallbacks(y_bar, XtNscrollProc,
  		    (XtPointer) (-2 * (int) clip_h / 3));
  		return;
+ #ifdef	VI_KEY
  	    case 'j':
+ #else
+ 	    case 'd':
+ #endif
  		if (!y_bar) goto bad;
  		XtCallCallbacks(y_bar, XtNscrollProc,
  		    (XtPointer) (2 * (int) clip_h / 3));
***************
*** 1639,1644 ****
--- 1843,1854 ----
  		reset_fonts();
  		break;
  #endif
+ #ifdef PS
+ 	    case '\007':	/* CTRL-G */
+ 		use_ps_special = ! use_ps_special;
+ 		--dvi_time;
+ 		break;
+ #endif
  	    case 'R':
  		/* reread DVI file */
  		--dvi_time;	/* then it will notice a change */
***************
*** 2167,2172 ****
--- 2377,2386 ----
  {"-mgs3",	".magnifierSize3",XrmoptionSepArg,	(caddr_t) NULL},
  {"-mgs4",	".magnifierSize4",XrmoptionSepArg,	(caddr_t) NULL},
  {"-mgs5",	".magnifierSize5",XrmoptionSepArg,	(caddr_t) NULL},
+ #ifdef	PS
+ {"-ps",		".psSpecial",	XrmoptionNoArg,		(caddr_t) "on"},
+ {"+ps",		".psSpecial",	XrmoptionNoArg,		(caddr_t) "off"},
+ #endif
  #ifdef	GREY
  {"-nogrey",	".grey",	XrmoptionNoArg,		(caddr_t) "off"},
  {"+nogrey",	".grey",	XrmoptionNoArg,		(caddr_t) "on"},
***************
*** 2256,2261 ****
--- 2470,2479 ----
    offset(mg_size[3]), XtRString, "900"},
  {"magnifierSize5", "MagnifierSize", XtRInt, sizeof(int),
    offset(mg_size[4]), XtRString, "1200"},
+ #ifdef	PS
+ {"psSpecial", "PsSpecial", XtRBoolean, sizeof(Boolean),
+   offset(use_ps_special), XtRString, "false"},
+ #endif
  #ifdef	GREY
  {"grey", "Grey", XtRBoolean, sizeof (Boolean),
   offset(use_grey), XtRString, "true"},
***************
*** 2395,2400 ****
--- 2613,2622 ----
  {"-mgs4",	"magnifierSize4",SepArg, NumberArg, 1,	(caddr_t) &mg_size[3]},
  {"-mgs5",	"magnifierSize5",SepArg, NumberArg, 1,	(caddr_t) &mg_size[4]},
  #endif
+ #ifdef	PS
+ {"-ps",		NULL,		TrueArg, BooleanArg, 2, (caddr_t) &use_ps_special},
+ {"+ps",		"psSpecial",	FalseArg, BooleanArg, 1,(caddr_t) &use_ps_special},
+ #endif
  #ifdef	GREY
  {"-nogrey",	NULL,		FalseArg, BooleanArg, 2,(caddr_t) &use_grey},
  {"+nogrey",	"grey",		TrueArg, BooleanArg, 1,	(caddr_t) &use_grey},
***************
*** 2704,2709 ****
--- 2926,2934 ----
  	list_fonts = resource.list_fonts;
  	hush_spec = resource.hush_spec;
  	hush_chars = resource.hush_chars;
+ #ifdef	PS
+ 	use_ps_special = resource.use_ps_special;
+ #endif
  #ifdef	GREY
  	use_grey = resource.use_grey;
  #endif

