[comp.sources.x] v11i060: xdvi, Patch11, Part02/02

vojta@math.berkeley.edu (Paul Vojta) (02/13/91)

Submitted-by: vojta@math.berkeley.edu (Paul Vojta)
Posting-number: Volume 11, Issue 60
Archive-name: xdvi/patch11.02
Patch-To: xdvi: Volume 3, Issues 37-39
Patch-To: xdvi: Volume 4, Issue 44 (xdvi, Patch4)
Patch-To: xdvi: Volume 4, Issue 96 (xdvi, dvi previewer, Patch5)
Patch-To: xdvi: Volume 5, Issue 35 (xdvi, dvi previewer, patch 6, part 1/2)
Patch-To: xdvi: Volume 5, Issue 36 (xdvi, dvi previewer, patch 6, part 2/2)
Patch-To: xdvi: Volume 6, Issue  5 (xdvi, Patch7)
Patch-To: xdvi: Volume 6, Issue 49 (xdvi, dvi previewer, patch 8)
Patch-To: xdvi: Volume 7, Issue 52 (xdvi, dvi previewer, patch 9, part 1/2)
Patch-To: xdvi: Volume 7, Issue 53 (xdvi, dvi previewer, patch 9, part 2/2)
Patch-To: xdvi: Volume 10, Issue 9 (xdvi, patch10, part01/02)
Patch-To: xdvi: Volume 10, Issue 10 (xdvi, patch10, part02/02)

-- cut here --
diff -cr old/pxl_open.c new/pxl_open.c
*** old/pxl_open.c	Sun Oct 21 14:47:37 1990
--- new/pxl_open.c	Sat Feb  2 16:28:32 1991
***************
*** 1,5 ****
  /*
!  *	pxl_open.c(font, font_ret, mag, mag_ret, factor, name)
   *	Find and open gf, pk, or pxl files in the given path, having the given
   *	name and magnification.  It tries gf files first, followed by pk and pxl
   *	files.  The path variable should be of the form path1:path2:...:pathn,
--- 1,5 ----
  /*
!  *	pxl_open.c(font, font_ret, mag, mag_ret, name)
   *	Find and open gf, pk, or pxl files in the given path, having the given
   *	name and magnification.  It tries gf files first, followed by pk and pxl
   *	files.  The path variable should be of the form path1:path2:...:pathn,
***************
*** 11,23 ****
   *	and if it fails then the procedure will try changing the point size
   *	as well.  If all of the above fails, then alt_font will be tried.
   *
   *	If the file is found, then a file pointer is returned, and the following
   *	values are set:
   *		*font_ret  a pointer to a string containing the font name (if
   *			different from the font requested).
   *		*mag_ret  the actual magnification found.
-  *		*factor	the ratio of the point sizes of the requested font
-  *			and the font actually found (or 1.0 if altfont is used).
   *		*name	a pointer to a string containing the file name
   *
   *	If the file is not found, then the return value is NULL.
--- 11,30 ----
   *	and if it fails then the procedure will try changing the point size
   *	as well.  If all of the above fails, then alt_font will be tried.
   *
+  *	If the variable SEARCH_SUBDIRECTORIES is set, then the environment
+  *	variable TEXFONTS_SUBDIR and the #define variable DEFAULT_SUBDIR_PATH
+  *	will be enabled, as well as ``*'' and ``**'' specifiers.  The
+  *	SUBDIR_PATH things will be appended to the end of the usual path, with
+  *	a `*' at the end of each component.  The `*' means that subdirectories
+  *	will be searched up to one level; `**' means that subdirectories
+  *	will be recursively searched to any level.  Neither specifier may be
+  *	preceded by a `%' specifier (after the most recent colon).
+  *
   *	If the file is found, then a file pointer is returned, and the following
   *	values are set:
   *		*font_ret  a pointer to a string containing the font name (if
   *			different from the font requested).
   *		*mag_ret  the actual magnification found.
   *		*name	a pointer to a string containing the file name
   *
   *	If the file is not found, then the return value is NULL.
***************
*** 49,65 ****
  
  static	char	*font_path;
  static	char	*default_font_path	= DEFAULT_FONT_PATH;
  static	int	*sizes, *sizend;
  static	char	default_size_list[]	= DEFAULT_FONT_SIZES;
  
  #ifdef	sun
  char	*sprintf();
  #endif
  
! char	*malloc(), *getenv();
  double	atof();
  
  static	void
  get_sizes(size_list, spp)
  	char	*size_list;
  	int	**spp;
--- 56,306 ----
  
  static	char	*font_path;
  static	char	*default_font_path	= DEFAULT_FONT_PATH;
+ #ifdef	SEARCH_SUBDIRECTORIES
+ static	char	default_subdir_path[]	= DEFAULT_SUBDIR_PATH;
+ #endif
  static	int	*sizes, *sizend;
  static	char	default_size_list[]	= DEFAULT_FONT_SIZES;
  
+ #define	FILENAMESIZE 512
+ 
  #ifdef	sun
  char	*sprintf();
  #endif
  
! char	*xmalloc(), *getenv();
  double	atof();
+ void	exit();
  
+ #ifdef	SEARCH_SUBDIRECTORIES
+ /* We will need some system include files to deal with directories.  */
+ /* <sys/types.h> was included by xdvi.h.  */
+ #include <sys/stat.h>
+ 
+ static	int	is_dir ();
+ 
+ #if	defined(SYSV) || defined(_POSIX_SOURCE)
+ #include <dirent.h>
+ typedef struct dirent *directory_entry_type;
+ #else
+ #include <sys/dir.h>
+ typedef struct direct *directory_entry_type;
+ #endif
+ 
+ /* Declare the routine to get the current working directory.  */
+ 
+ #ifdef	HAVE_GETWD
+ extern char *getwd ();
+ #define	getcwd(b, len)	((b) ? getwd (b) : getwd (xmalloc (len, "getwd")))
+ #else
+ #ifdef	ANSI
+ extern char *getcwd (char *, int);
+ #else
+ extern char *getcwd ();
+ #endif	/* not ANSI */
+ #endif	/* not HAVE_GETWD */
+ 
+ char	*cwd;
+ 
+ /* The following is a data structure containing the precomputed names of
+    subdirectories to be recursively searched. */
+ 
+ static	struct subdir_entry {
+ 	char	*name;		/* partial string */
+ 	char	*index;		/* reference point in {,default_}font_path */
+ 	struct subdir_entry *next;	/* link in list */
+ }
+ 	*subdir_head	= NULL,
+ 	*next_subdir;
+ 
+ #ifndef	S_ISDIR
+ #define	S_ISDIR(m)	((m & S_IFMT) == S_IFDIR)
+ #endif
+ 
+ /* Return true if FN is a directory or a symlink to a directory,
+    false if not. */
+ 
+ static	int
+ is_dir (fn)
+   char *fn;
+ {
+   struct stat stats;
+ 
+   return stat (fn, &stats) == 0 && S_ISDIR (stats.st_mode);
+ }
+ 
+ /*
+  *	Compute extra length of subdirectory entries, including a star for each.
+  */
+ 
+ static	int
+ extra_len(str1, str2)
+     char *str1, *str2;
+ {
+ 	int	bias	= 0;
+ 	char	*p	= str1;
+ 	char	*q;
+ 
+ 	do {
+ 	    q = index(p, PATH_SEP);
+ 	    if (q == NULL) q = p + strlen(p);
+ 	    if (q == p) {
+ 		if (str2 != NULL) {
+ 		    bias += extra_len(str2, (char *) NULL);
+ 		    str2 = NULL;
+ 		}
+ 	    }
+ 	    else ++bias;	/* don't forget the star */
+ 	    p = q + 1;
+ 	}
+ 	while (p[-1] != '\0');
+ 	return bias + p - str1;
+ }
+ 
+ /*
+  *	Add the specifiers (and double stars) for the given strings (user
+  *	string, plus default string) to the destination string.
+  */
+ 
  static	void
+ add_subdir_paths(dst, dst_first, src, src_default)
+     char *dst, *dst_first, *src, *src_default;
+ {
+ 	char	*q;
+ 
+ 	do {
+ 	    q = index(src, PATH_SEP);
+ 	    if (q == NULL) q = src + strlen(src);
+ 	    if (q == src) {
+ 		if (src_default != NULL) {
+ 		    add_subdir_paths(dst, dst_first, src_default, (char *)NULL);
+ 		    dst += strlen(dst);
+ 		    src_default = NULL;
+ 		}
+ 	    }
+ 	    else {
+ 		if (dst != dst_first) *dst++ = PATH_SEP;
+ 		bcopy(src, dst, q - src);
+ 		dst += q - src;
+ 		*dst++ = '*';
+ 	    }
+ 	    src = q + 1;
+ 	}
+ 	while (src[-1] != '\0');
+ 	*dst = '\0';
+ }
+ 
+ /*
+  *	Make a subdirectory entry.
+  */
+ 
+ static	struct subdir_entry *
+ make_subdir_entry(index, name)
+     char *index, *name;
+ {
+ 	struct subdir_entry *new_entry;
+ 	static	struct subdir_entry	**subdir_tail = &subdir_head;
+ 
+ 	*subdir_tail = new_entry = (struct subdir_entry *)
+ 	    xmalloc(sizeof(struct subdir_entry), "subdirectory list entry");
+ 	subdir_tail = &(new_entry->next);
+ 	new_entry->name = strcpy(xmalloc(strlen(name) + 1,
+ 	    "subdirectory entry string"), name);
+ 	new_entry->index = index;
+ 	new_entry->next = NULL;
+ 	return new_entry;
+ }
+ 
+ /*
+  *	Create the subdirectory linked list for the given initial string
+  */
+ 
+ static	void
+ add_subdirs(str, len, recurs)
+     char *str;
+     int len;
+     Boolean recurs;
+ {
+ 	int	len1 = len;
+ 	char	temp[FILENAMESIZE];
+ 	struct subdir_entry *next_subdir;
+ 	DIR	*dir;
+ 	directory_entry_type	e;
+ 
+ 	bcopy(str, temp, len);
+ 	if (len > 0 && temp[len - 1] != '/') temp[len1++] = '/';
+ 	temp[len1] = '\0';
+ 	next_subdir = make_subdir_entry(str, temp + len);
+ 	do {
+ 	    /* By changing directories, we save a bunch of string
+ 	       concatenations (and make the pathnames the kernel looks up
+ 	       shorter).  */
+ 	    Strcpy(temp + len, next_subdir->name);
+ 	    if (chdir (temp) != 0) continue;
+ 
+ 	    dir = opendir (".");
+ 	    if (dir == NULL) continue;
+ 
+ 	    len1 = strlen(temp);
+ 	    if (len1 == 0 || temp[len1 - 1] != '/') temp[len1++] = '/';
+ 	    while ((e = readdir (dir)) != NULL)
+ 	      {
+ 		if (is_dir (e->d_name) && strcmp (e->d_name, ".") != 0
+ 		    && strcmp (e->d_name, "..") != 0)
+ 		  {
+ 		    Strcpy(temp + len1, e->d_name);
+ 		    (void) make_subdir_entry(str, temp + len);
+ 		  }
+ 	      }
+ 	    (void) closedir (dir);
+ 
+ 
+ 	    /* Change back to the current directory, in case the path
+ 	       contains relative directory names.  */
+ 	    if (chdir (cwd) != 0) {
+ 		perror (cwd);
+ 		exit (errno);
+ 	    }
+ 	}
+ 	while (recurs && (next_subdir = next_subdir->next) != NULL);
+ }
+ 
+ /*
+  *	Recursively figure out the subdirectory tree and precompute the
+  *	list of subdirectories to search.
+  */
+ 
+ static	void
+ compute_subdir_paths(fp, fp_default)
+     char *fp, *fp_default;
+ {
+ 	char	*star_loc = NULL;
+ 	char	*endp;
+ 
+ 	do {
+ 	    if (star_loc == NULL) {
+ 		star_loc = index(fp, '*');
+ 		if (star_loc == NULL) star_loc = fp + strlen(fp);
+ 	    }
+ 	    endp = index(fp, PATH_SEP);
+ 	    if (endp == NULL) endp = fp + strlen(fp);
+ 	    if (endp == fp) {
+ 		if (fp_default != NULL) {
+ 		    compute_subdir_paths(fp_default, (char *) NULL);
+ 		    fp_default = NULL;
+ 		}
+ 	    }
+ 	    else if (star_loc < endp) {
+ 		add_subdirs(fp, star_loc - fp, star_loc[1] == '*');
+ 		star_loc = NULL;
+ 	    }
+ 	    fp = endp + 1;
+ 	}
+ 	while (fp[-1] != '\0');
+ }
+ #endif	/* SEARCH_SUBDIRECTORIES */
+ 
+ static	void
  get_sizes(size_list, spp)
  	char	*size_list;
  	int	**spp;
***************
*** 79,90 ****
  	int	*sp, *sp1, *sp2;
  	unsigned int n;
  	char	*p;
  
! 	if ((font_path = getenv("XDVIFONTS")) == NULL) {
  	    font_path = default_font_path;
  	    default_font_path = NULL;
  	}
  
  	size_list = getenv("XDVISIZES");
  	n = 1;	/* count number of sizes */
  	if (size_list == NULL || *size_list == PATH_SEP)
--- 320,360 ----
  	int	*sp, *sp1, *sp2;
  	unsigned int n;
  	char	*p;
+ #ifdef	SEARCH_SUBDIRECTORIES
+ 	char	*q;
+ #endif
  
! 	if ((font_path = getenv("XDVIFONTS")) == NULL
! 		&& (font_path = getenv("TEXFONTS")) == NULL) {
  	    font_path = default_font_path;
  	    default_font_path = NULL;
  	}
  
+ #ifdef	SEARCH_SUBDIRECTORIES
+ 	p = getenv ("TEXFONTS_SUBDIR");
+ 	if (p == NULL) p = "";
+ 	q = xmalloc((unsigned) strlen(font_path)
+ 	    + extra_len(p, default_subdir_path) + 1,
+ 	    "initializing font searching");
+ 	Strcpy(q, font_path);
+ 	add_subdir_paths(q + strlen(q), q, p, default_subdir_path);
+ 	font_path = q;
+ 
+ 	/* Unfortunately, we can't look in the environment for the current
+ 	   directory, because if we are running under a program (let's say
+ 	   Emacs), the PWD variable might have been set by Emacs' parent
+ 	   to the current directory at the time Emacs was invoked.  This
+ 	   is not necessarily the same directory the user expects to be
+ 	   in.  So, we must always call getcwd(3) or getwd(3), even though
+ 	   they are slow and prone to hang in networked installations.  */
+ 	cwd = getcwd ((char *) NULL, FILENAMESIZE + 2);
+ 	if (cwd == NULL) {
+ 	    perror ("getcwd");
+ 	    exit (errno);
+ 	}
+ 	compute_subdir_paths(font_path, default_font_path);
+ #endif
+ 
  	size_list = getenv("XDVISIZES");
  	n = 1;	/* count number of sizes */
  	if (size_list == NULL || *size_list == PATH_SEP)
***************
*** 92,98 ****
  		++n;
  	if (size_list != NULL)
  	    for (p = size_list; (p = index(p, PATH_SEP)) != NULL; ++p) ++n;
! 	sizes = (int *) malloc(n * sizeof(int));
  	sizend = sizes + n;
  	sp = sizes;	/* get the actual sizes */
  	if (size_list == NULL || *size_list == PATH_SEP)
--- 362,368 ----
  		++n;
  	if (size_list != NULL)
  	    for (p = size_list; (p = index(p, PATH_SEP)) != NULL; ++p) ++n;
! 	sizes = (int *) xmalloc(n * sizeof(int), "size list");
  	sizend = sizes + n;
  	sp = sizes;	/* get the actual sizes */
  	if (size_list == NULL || *size_list == PATH_SEP)
***************
*** 122,128 ****
  	int	count;
  {
  	char	*p = path,
! 		nm[128],
  		*n = nm,
  		c;
  	Boolean	f_used = False;
--- 392,398 ----
  	int	count;
  {
  	char	*p = path,
! 		nm[FILENAMESIZE],
  		*n = nm,
  		c;
  	Boolean	f_used = False;
***************
*** 129,134 ****
--- 399,418 ----
  	Boolean	p_used = False;
  	FILE	*f;
  
+ #ifdef	SEARCH_SUBDIRECTORIES
+ 	if (next_subdir != NULL && next_subdir->index == p) {
+ 	    int len = index(p, '*') - p;
+ 
+ 	    bcopy(p, n, len);
+ 	    p += len;
+ 	    n += len;
+ 	    Strcpy(n, next_subdir->name);
+ 	    n += strlen(n);
+ 	    ++p;
+ 	    if (*p == '*') ++p;
+ 	    if (*p != '/') *n++ = '/';
+ 	}
+ #endif
  	for (;;) {
  	    c = *p++;
  	    if (c==PATH_SEP || c=='\0') {
***************
*** 168,174 ****
  	    f = fopen(nm, OPEN_MODE);
  	}
  	if (f != NULL) {
! 	    *name = malloc((unsigned) (n - nm + 1));
  	    Strcpy(*name, nm);
  	}
  	return f;
--- 452,458 ----
  	    f = fopen(nm, OPEN_MODE);
  	}
  	if (f != NULL) {
! 	    *name = xmalloc((unsigned) (n - nm + 1), "font file name");
  	    Strcpy(*name, nm);
  	}
  	return f;
***************
*** 185,191 ****
  	char	**name;
  	char	*font_path, *default_font_path;
  {
! 	char	*p;
  	FILE	*f;
  	int	pkmag	= (pxlmag + 2) / 5;
  
--- 469,475 ----
  	char	**name;
  	char	*font_path, *default_font_path;
  {
! 	char	*p	= font_path;
  	FILE	*f;
  	int	pkmag	= (pxlmag + 2) / 5;
  
***************
*** 192,201 ****
  	/*
  	 * loop over paths
  	 */
! 	for (p = font_path;; ++p) {
  	    int count = 0;
  
! 	    if (*p == ':' || *p == '\0') {
  		if (default_font_path != NULL &&
  			(f = try_size(font, pxlmag, name, default_font_path,
  			(char *) NULL)) != NULL)
--- 476,488 ----
  	/*
  	 * loop over paths
  	 */
! #ifdef	SEARCH_SUBDIRECTORIES
! 	next_subdir = subdir_head;
! #endif
! 	for (;;) {
  	    int count = 0;
  
! 	    if (*p == PATH_SEP || *p == '\0') {
  		if (default_font_path != NULL &&
  			(f = try_size(font, pxlmag, name, default_font_path,
  			(char *) NULL)) != NULL)
***************
*** 215,222 ****
--- 502,516 ----
  		(f = formatted_open(p, font, "pxl", pxlmag, name, count++))
  			!= NULL)
  		    return f;
+ #ifdef	SEARCH_SUBDIRECTORIES
+ 	    if (next_subdir != NULL && next_subdir->index == p) {
+ 		next_subdir = next_subdir->next;
+ 		if (next_subdir != NULL && next_subdir->index == p) continue;
+ 	    }
+ #endif
  	    p = index(p, PATH_SEP);
  	    if (p == NULL) break;
+ 	    ++p;
  	}
  	return NULL;
  }
***************
*** 234,251 ****
  {
  	FILE	*f;
  	int	*p1, *p2, pxlmag;
  
  	/*
  	 * Loop over sizes.  Try actual size first, then closest sizes.
  	 */
  	pxlmag = mag + 0.5;
! 	if ((f = try_size(font, *mag_ret = pxlmag, name, font_path,
  		default_font_path)) != NULL)
  	    return f;
  	if (pxlmag < mag) ++pxlmag; else --pxlmag;
! 	if ((f = try_size(font, *mag_ret = pxlmag, name, font_path,
  		default_font_path)) != NULL)
  	    return f;
  	for (p2 = sizes; p2 < sizend; ++p2) if (*p2 >= mag) break;
  	p1 = p2;
  	for (;;) {
--- 528,562 ----
  {
  	FILE	*f;
  	int	*p1, *p2, pxlmag;
+ 	char	*path_to_use = font_path;
  
  	/*
  	 * Loop over sizes.  Try actual size first, then closest sizes.
+ 	   If the pathname is absolutely or explicitly relative, don't
+ 	   use the usual paths to search for it; just look for it in the
+ 	   directory specified.
  	 */
  	pxlmag = mag + 0.5;
! 
! #ifndef	VMS
! 	if (*font == '/') path_to_use = "/";
! 	else if (*font == '.' && (*(font + 1) == '/'
! 		|| (*(font + 1) == '.' && *(font + 2) == '/')))
! 	    path_to_use = ".";
! #endif
! 
! 	if ((f = try_size(font, *mag_ret = pxlmag, name, path_to_use,
  		default_font_path)) != NULL)
  	    return f;
+ 
+ 	/* Try at one away from the size we just tried, to account
+ 	   for rounding error.  */
  	if (pxlmag < mag) ++pxlmag; else --pxlmag;
! 	if ((f = try_size(font, *mag_ret = pxlmag, name, path_to_use,
  		default_font_path)) != NULL)
  	    return f;
+ 
+ 	/* Now try at all the sizes. */
  	for (p2 = sizes; p2 < sizend; ++p2) if (*p2 >= mag) break;
  	p1 = p2;
  	for (;;) {
***************
*** 256,262 ****
  	    else if (p2 >= sizend || mag * mag <= p1[-1] * *p2)
  		    pxlmag = *--p1;
  		else pxlmag = *p2++;
! 	    if ((f = try_size(font, *mag_ret = pxlmag, name, font_path,
  		    default_font_path)) != NULL)
  		return f;
  	}
--- 567,573 ----
  	    else if (p2 >= sizend || mag * mag <= p1[-1] * *p2)
  		    pxlmag = *--p1;
  		else pxlmag = *p2++;
! 	    if ((f = try_size(font, *mag_ret = pxlmag, name, path_to_use,
  		    default_font_path)) != NULL)
  		return f;
  	}
***************
*** 263,273 ****
  }
  
  FILE *
! pxl_open(font, font_ret, mag, mag_ret, factor, name)
  	char	*font, **font_ret;
  	float	mag;
  	int	*mag_ret;
- 	float	*factor;
  	char	**name;
  {
  	FILE	*f;
--- 574,583 ----
  }
  
  FILE *
! pxl_open(font, font_ret, mag, mag_ret, name)
  	char	*font, **font_ret;
  	float	mag;
  	int	*mag_ret;
  	char	**name;
  {
  	FILE	*f;
***************
*** 274,280 ****
  	int	actual_pt, low_pt, high_pt, trial_pt;
  	char	fn[50], *fnend;
  
- 	*factor = 1.0;
  	f = pre_pxl_open(font, mag, mag_ret, name);
  	if (f != NULL) {
  	    *font_ret = NULL;
--- 584,589 ----
***************
*** 297,304 ****
  		Sprintf(fnend, "%d", trial_pt);
  		f = pre_pxl_open(fn, mag * actual_pt / trial_pt, mag_ret, name);
  		if (f != NULL) {
! 		    *font_ret = strcpy(malloc((unsigned) strlen(fn) + 1), fn);
! 		    *factor = (float) actual_pt / trial_pt;
  		    return f;
  		}
  	    }
--- 606,613 ----
  		Sprintf(fnend, "%d", trial_pt);
  		f = pre_pxl_open(fn, mag * actual_pt / trial_pt, mag_ret, name);
  		if (f != NULL) {
! 		    *font_ret = strcpy(xmalloc((unsigned) strlen(fn) + 1,
! 			"name of font used"), fn);
  		    return f;
  		}
  	    }
***************
*** 307,313 ****
  	    *font_ret = alt_font;
  	    f = pre_pxl_open(alt_font, mag, mag_ret, name);
  	    if (f != NULL)
! 		*font_ret = strcpy(malloc((unsigned) strlen(alt_font) + 1),
  		    alt_font);
  	}
  	return f;
--- 616,623 ----
  	    *font_ret = alt_font;
  	    f = pre_pxl_open(alt_font, mag, mag_ret, name);
  	    if (f != NULL)
! 		*font_ret = strcpy(xmalloc((unsigned) strlen(alt_font) + 1,
! 		    "name of font used"),
  		    alt_font);
  	}
  	return f;
diff -cr old/tpic.c new/tpic.c
*** old/tpic.c	Sun Oct 21 14:47:54 1990
--- new/tpic.c	Fri Dec  7 16:54:30 1990
***************
*** 410,415 ****
      else if (strcmp(command, "sh") == 0) shade_last();
      else if (strcmp(command, "wh") == 0) whiten_last();
      else if (strcmp(command, "bk") == 0) blacken_last();
!     else if (spec_warn_now)
  	Fprintf(stderr, "%s:  special \"%s\" not implemented\n", prog, orig_cp);
  }
--- 410,415 ----
      else if (strcmp(command, "sh") == 0) shade_last();
      else if (strcmp(command, "wh") == 0) whiten_last();
      else if (strcmp(command, "bk") == 0) blacken_last();
!     else if (!hush_spec_now)
  	Fprintf(stderr, "%s:  special \"%s\" not implemented\n", prog, orig_cp);
  }
diff -cr old/xdvi.c new/xdvi.c
*** old/xdvi.c	Sun Oct 21 14:49:08 1990
--- new/xdvi.c	Mon Feb  4 13:05:55 1991
***************
*** 116,121 ****
--- 116,145 ----
  #define	DPY	DISP,
  static	Screen	*SCRN;
  static	Cursor	redraw_cursor, ready_cursor;
+ 
+ #ifdef	VMS
+ /*
+  * Magnifying glass cursor
+  *
+  * Developed by Tom Sawyer, April 1990
+  * Contibuted by Hunter Goatley, January 1991
+  *
+  */
+ 
+ #define mag_glass_width 16
+ #define mag_glass_height 16
+ #define mag_glass_x_hot 6
+ #define mag_glass_y_hot 6
+ static char mag_glass_bits[] = {
+ 	0xf8, 0x03, 0x0c, 0x06, 0xe2, 0x09, 0x13, 0x1a, 0x01, 0x14, 0x01, 0x14,
+ 	0x01, 0x10, 0x01, 0x10, 0x01, 0x10, 0x03, 0x10, 0x02, 0x18, 0x0c, 0x34,
+ 	0xf8, 0x6f, 0x00, 0xd8, 0x00, 0xb0, 0x00, 0xe0
+ };
+ #include <decw$cursor.h>	/* Include the DECWindows cursor symbols */
+ static	int	DECWCursorFont;	/* Space for the DECWindows cursor font  */
+ static	Pixmap	MagnifyPixmap;	/* Pixmap to hold our special mag-glass  */
+ #endif	/* VMS */
+ 
  #define	SetCursor(x)	XDefineCursor(DISP, WINDOW(mane), x)
  #define	ClearPage(wr)	XClearWindow(DISP, WINDOW(wr));
  #define	ClearArea(win, x, y, w, h)	XClearArea(DISP, win, x, y, w, h, False)
***************
*** 160,166 ****
  int	offset_x, offset_y;
  int	unshrunk_paper_w, unshrunk_paper_h;
  int	unshrunk_page_w, unshrunk_page_h;
! Boolean	spec_warn	= True;
  static	char	*paper		= DEFAULT_PAPER;
  static	char	*sidemargin, *topmargin;
  static	char	*xoffset, *yoffset;
--- 184,191 ----
  int	offset_x, offset_y;
  int	unshrunk_paper_w, unshrunk_paper_h;
  int	unshrunk_page_w, unshrunk_page_h;
! Boolean	hush_spec	= False;
! Boolean	hush_chars	= False;
  static	char	*paper		= DEFAULT_PAPER;
  static	char	*sidemargin, *topmargin;
  static	char	*xoffset, *yoffset;
***************
*** 309,320 ****
  		{"Shrink2",	"sh2",		2 << 8 | 's',	200},
  		{"Shrink3",	"sh3",		3 << 8 | 's',	250},
  		{"Shrink4",	"sh4",		4 << 8 | 's',	300},
! 		{"Next",	"next",		'n',		400},
! 		{"Page+5",	"next5",	5 << 8 | 'n',	450},
! 		{"Page+10",	"next10",	10 << 8 | 'n',	500},
! 		{"Prev",	"prev",		'p',		600},
! 		{"Page-5",	"prev5",	5 << 8 | 'p',	650},
! 		{"Page-10",	"prev10",	10 << 8 | 'p',	700},
  };
  
  static	void	handle_command();
--- 334,345 ----
  		{"Shrink2",	"sh2",		2 << 8 | 's',	200},
  		{"Shrink3",	"sh3",		3 << 8 | 's',	250},
  		{"Shrink4",	"sh4",		4 << 8 | 's',	300},
! 		{"Page-10",	"prev10",	10 << 8 | 'p',	400},
! 		{"Page-5",	"prev5",	5 << 8 | 'p',	450},
! 		{"Prev",	"prev",		'p',		500},
! 		{"Next",	"next",		'n',		600},
! 		{"Page+5",	"next5",	5 << 8 | 'n',	650},
! 		{"Page+10",	"next10",	10 << 8 | 'n',	700},
  };
  
  static	void	handle_command();
***************
*** 415,421 ****
  char	*sprintf();
  #endif
  
- char	*malloc();
  double	atof();
  void	exit();
  
--- 440,445 ----
***************
*** 1192,1197 ****
--- 1216,1224 ----
  	    case 'q':
  	    case '\003':	/* control-C */
  	    case '\004':	/* control-D */
+ #ifdef	VMS
+ 	    case '\032':	/* control-Z */
+ #endif
  		exit(0);
  	    case 'n':
  	    case 'f':
***************
*** 1362,1368 ****
  	if (0 <= next_page && next_page < total_pages) {
  	    if (current_page != next_page) {
  		current_page = next_page;
! 		spec_warn_now = spec_warn;
  		if (!keep_flag) home(False);
  	    }
  	    canit = True;
--- 1389,1395 ----
  	if (0 <= next_page && next_page < total_pages) {
  	    if (current_page != next_page) {
  		current_page = next_page;
! 		hush_spec_now = hush_spec;
  		if (!keep_flag) home(False);
  	    }
  	    canit = True;
***************
*** 1629,1635 ****
  	}
  	else {
  	    draw_page();
! 	    spec_warn_now = False;
  	}
  }
  
--- 1656,1662 ----
  	}
  	else {
  	    draw_page();
! 	    hush_spec_now = True;
  	}
  }
  
***************
*** 1746,1756 ****
  #ifndef	VMS
  #ifdef	BUTTONS
  	Fputs("\
! Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-sw]\n\
  	[-expert] [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
! 	[-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>] [-rv]\
! \n\
! 	[-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>]\n\
  	[-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
  [-cr <color>]\n\
  	[-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
--- 1773,1783 ----
  #ifndef	VMS
  #ifdef	BUTTONS
  	Fputs("\
! Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
  	[-expert] [-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
! 	[-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
! 	[-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
! 	[-hushspecials] [-hushchars] [-hush]\n\
  	[-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
  [-cr <color>]\n\
  	[-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
***************
*** 1758,1768 ****
  	stderr);
  #else	/* !BUTTONS */
  	Fputs("\
! Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-sw]\n\
  	[-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
! 	[-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>] [-rv]\
! \n\
! 	[-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>]\n\
  	[-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
  [-cr <color>]\n\
  	[-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
--- 1785,1795 ----
  	stderr);
  #else	/* !BUTTONS */
  	Fputs("\
! Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-rv]\n\
  	[-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
! 	[-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
! 	[-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
! 	[-hushspecials] [-hushchars] [-hush]\n\
  	[-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
  [-cr <color>]\n\
  	[-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
***************
*** 1771,1795 ****
  #endif	/* BUTTONS */
  #else	/* VMS */
  	Fputs("\
! Usage: xdvi [+[<page>]] [-s <shrink>] [-density <%>] [-p <pixels>] [-l] [-sw]\n\
  	[-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
! 	[-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>] [-rv]\
  \n", stderr);
  	Fputs("\
! 	[-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>]\n\
  	[-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
  [-cr <color>]\n\
  	[-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
! 	[-iconic] [-display <host:display>] [-copy] [-thorough] dvi_file\n",
  	stderr);
  #endif	/* VMS */
  #else	/* X10 */
  	Fputs("\
! Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l] [-sw]\n\
  	[-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
! 	[-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>] [-rv]\
! \n\
! 	[-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>]\n\
  	[-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
  [-cr <color>]\n\
  	[-bw <width>] [-geometry <geometry> | =<geometry>]\n\
--- 1798,1823 ----
  #endif	/* BUTTONS */
  #else	/* VMS */
  	Fputs("\
! Usage: xdvi [+[<page>]] [-s <shrink>] [-density <%>] [-p <pixels>] [-l] [-rv]\n\
  	[-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
! 	[-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\
  \n", stderr);
  	Fputs("\
! 	[-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
! 	[-hushspecials] [-hushchars] [-hush]\n\
  	[-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
  [-cr <color>]\n\
  	[-bw <width>] [-geometry <geometry>] [-icongeometry <geometry>]\n\
! 	[-iconic] [-display <host::display>] [-copy] [-thorough] dvi_file\n",
  	stderr);
  #endif	/* VMS */
  #else	/* X10 */
  	Fputs("\
! Usage: xdvi [+[<page>]] [-s <shrink>] [-S <density>] [-p <pixels>] [-l]\n\
  	[-paper <papertype>] [-mgs[n] <size>] [-altfont <font>]\n\
! 	[-margins <dimen>] [-sidemargin <dimen>] [-topmargin <dimen>]\n\
! 	[-offsets <dimen>] [-xoffset <dimen>] [-yoffset <dimen>] [-keep]\n\
! 	[-hushspecials] [-hushchars] [-hush]\n\
  	[-fg <color>] [-bg <color>] [-hl <color>] [-bd <color>] \
  [-cr <color>]\n\
  	[-bw <width>] [-geometry <geometry> | =<geometry>]\n\
***************
*** 1838,1845 ****
  {"-altfont",	".altFont",	XrmoptionSepArg,	(caddr_t) NULL},
  {"-l",		".listFonts",	XrmoptionNoArg,		(caddr_t) "on"},
  {"+l",		".listFonts",	XrmoptionNoArg,		(caddr_t) "off"},
! {"-sw",		".specialWarn",	XrmoptionNoArg,		(caddr_t) "on"},
! {"+sw",		".specialWarn",	XrmoptionNoArg,		(caddr_t) "off"},
  {"-fg",		".foreground",	XrmoptionSepArg,	(caddr_t) NULL},
  {"-foreground",	".foreground",	XrmoptionSepArg,	(caddr_t) NULL},
  {"-bg",		".background",	XrmoptionSepArg,	(caddr_t) NULL},
--- 1866,1877 ----
  {"-altfont",	".altFont",	XrmoptionSepArg,	(caddr_t) NULL},
  {"-l",		".listFonts",	XrmoptionNoArg,		(caddr_t) "on"},
  {"+l",		".listFonts",	XrmoptionNoArg,		(caddr_t) "off"},
! {"-hushspecials", ".hushSpecials", XrmoptionNoArg,	(caddr_t) "on"},
! {"+hushspecials", ".hushSpecials", XrmoptionNoArg,	(caddr_t) "off"},
! {"-hushchars",	".hushLostChars", XrmoptionNoArg,	(caddr_t) "on"},
! {"+hushchars",	".hushLostChars", XrmoptionNoArg,	(caddr_t) "off"},
! {"-hush",	".Hush",	XrmoptionNoArg,		(caddr_t) "on"},
! {"+hush",	".Hush",	XrmoptionNoArg,		(caddr_t) "off"},
  {"-fg",		".foreground",	XrmoptionSepArg,	(caddr_t) NULL},
  {"-foreground",	".foreground",	XrmoptionSepArg,	(caddr_t) NULL},
  {"-bg",		".background",	XrmoptionSepArg,	(caddr_t) NULL},
***************
*** 1847,1852 ****
--- 1879,1886 ----
  {"-hl",		".highlight",	XrmoptionSepArg,	(caddr_t) NULL},
  {"-cr",		".cursorColor",	XrmoptionSepArg,	(caddr_t) NULL},
  {"-icongeometry",".iconGeometry",XrmoptionSepArg,	(caddr_t) NULL},
+ {"-keep",	".keepPosition",XrmoptionNoArg,		(caddr_t) "on"},
+ {"+keep",	".keepPosition",XrmoptionNoArg,		(caddr_t) "off"},
  {"-copy",	".copy",	XrmoptionNoArg,		(caddr_t) "on"},
  {"+copy",	".copy",	XrmoptionNoArg,		(caddr_t) "off"},
  {"-thorough",	".thorough",	XrmoptionNoArg,		(caddr_t) "on"},
***************
*** 1888,1895 ****
    (Cardinal) &list_fonts, XtRBoolean, (caddr_t) &list_fonts},
  {"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean),
    (Cardinal) &reverse, XtRBoolean, (caddr_t) &reverse},
! {"specialWarn", "SpecialWarn", XtRBoolean, sizeof(Boolean),
!   (Cardinal) &spec_warn, XtRBoolean, (caddr_t) &spec_warn},
  {"foreground", "Foreground", XtRPixel, sizeof(Pixel),
    (Cardinal)&fore_Pixel, XtRPixel, (caddr_t) &fore_Pixel},
  {"foreground", "Foreground", XtRString, sizeof(char *),
--- 1922,1931 ----
    (Cardinal) &list_fonts, XtRBoolean, (caddr_t) &list_fonts},
  {"reverseVideo", "ReverseVideo", XtRBoolean, sizeof(Boolean),
    (Cardinal) &reverse, XtRBoolean, (caddr_t) &reverse},
! {"hushSpecials", "Hush", XtRBoolean, sizeof(Boolean),
!   (Cardinal) &hush_spec, XtRBoolean, (caddr_t) &hush_spec},
! {"hushLostChars", "Hush", XtRBoolean, sizeof(Boolean),
!   (Cardinal) &hush_chars, XtRBoolean, (caddr_t) &hush_chars},
  {"foreground", "Foreground", XtRPixel, sizeof(Pixel),
    (Cardinal)&fore_Pixel, XtRPixel, (caddr_t) &fore_Pixel},
  {"foreground", "Foreground", XtRString, sizeof(char *),
***************
*** 1912,1917 ****
--- 1948,1955 ----
    (Cardinal)&curs_color, XtRString, NULL},
  {"iconGeometry", "IconGeometry", XtRString, sizeof(char *),
    (Cardinal)&icon_geometry, XtRString, NULL},
+ {"keepPosition", "KeepPosition", XtRBoolean, sizeof(Boolean),
+   (Cardinal)&keep_flag, XtRBoolean, (caddr_t) &keep_flag},
  {"copy", "Copy", XtRBoolean, sizeof(Boolean),
    (Cardinal)&copy, XtRBoolean, (caddr_t) &copy},
  {"thorough", "Thorough", XtRBoolean, sizeof(Boolean),
***************
*** 1953,1958 ****
--- 1991,1997 ----
  static	char	*geometry;
  static	char	*margins;
  static	char	*offsets;
+ static	Boolean	hush;
  
  #ifndef X10
  static	Boolean	iconic	= False;
***************
*** 2012,2019 ****
  {"+l",		"listFonts",	FalseArg, BooleanArg, 1,(caddr_t) &list_fonts},
  {"-rv",		NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &reverse},
  {"+rv",		"reverseVideo",	FalseArg, BooleanArg, 1,(caddr_t) &reverse},
! {"-sw",		NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &spec_warn},
! {"+sw",		"specialWarn",	FalseArg, BooleanArg, 1,(caddr_t) &spec_warn},
  {"-bw",		NULL,		SepArg,	NumberArg, 2,	(caddr_t) &bwidth},
  {"-borderwidth", "borderWidth",	SepArg,	NumberArg, 1,	(caddr_t) &bwidth},
  {"-fg",		NULL,		SepArg,	StringArg, 2,	(caddr_t) &fore_color},
--- 2051,2062 ----
  {"+l",		"listFonts",	FalseArg, BooleanArg, 1,(caddr_t) &list_fonts},
  {"-rv",		NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &reverse},
  {"+rv",		"reverseVideo",	FalseArg, BooleanArg, 1,(caddr_t) &reverse},
! {"-hush",	NULL,		TrueArg, BooleanArg, 6,	(caddr_t) &hush},
! {"+hush",	"Hush",		FalseArg, BooleanArg, 5,(caddr_t) &hush},
! {"-hushspecials", NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &hush_spec},
! {"+hushspecials", "hushSpecials", FalseArg, BooleanArg, 1,(caddr_t) &hush_spec},
! {"-hushchars",	NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &hush_chars},
! {"+hushchars",	"hushLostChars", FalseArg, BooleanArg, 1,(caddr_t) &hush_chars},
  {"-bw",		NULL,		SepArg,	NumberArg, 2,	(caddr_t) &bwidth},
  {"-borderwidth", "borderWidth",	SepArg,	NumberArg, 1,	(caddr_t) &bwidth},
  {"-fg",		NULL,		SepArg,	StringArg, 2,	(caddr_t) &fore_color},
***************
*** 2032,2037 ****
--- 2075,2082 ----
  {"-icongeometry","iconGeometry",StickyArg, StringArg, 1,(caddr_t) &icon_geometry},
  {"-iconic",	NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &iconic},
  {"+iconic",	"iconic",	FalseArg, BooleanArg, 1,(caddr_t) &iconic},
+ {"-keep",	NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &keep_flag},
+ {"+keep",	"keepPosition",	FalseArg, BooleanArg, 1,(caddr_t) &keep_flag},
  {"-copy",	NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &copy},
  {"+copy",	"copy",		FalseArg, BooleanArg, 1,(caddr_t) &copy},
  {"-thorough",	NULL,		TrueArg, BooleanArg, 2,	(caddr_t) &thorough},
***************
*** 2061,2069 ****
  	char	**argvend = argv + argc;
  	char	*optstring;
  	caddr_t	addr;
! 	struct option *opt, *candidate;
! 	int	len1, len2, matchlen, i;
  
  	for (arg = argv + 1; arg < argvend; ++arg) {
  	    len1 = strlen(*arg);
  	    candidate = NULL;
--- 2106,2117 ----
  	char	**argvend = argv + argc;
  	char	*optstring;
  	caddr_t	addr;
! 	struct option *opt, *lastopt, *candidate;
! 	int	len1, len2, matchlen;
  
+ 	/*
+ 	 * Step 1.  Process command line options.
+ 	 */
  	for (arg = argv + 1; arg < argvend; ++arg) {
  	    len1 = strlen(*arg);
  	    candidate = NULL;
***************
*** 2120,2128 ****
  		case StringArg:	*((char **) addr) = optstring; break;
  		case NumberArg:	*((int *) addr) = atoi(optstring); break;
  	    }
! 	    for (i = candidate->classcount; i > 0; --i)
! 		(candidate++)->resource = NULL;
  	}
  
  #ifndef X10
  	if ((DISP = XOpenDisplay(display)) == NULL)
--- 2168,2202 ----
  		case StringArg:	*((char **) addr) = optstring; break;
  		case NumberArg:	*((int *) addr) = atoi(optstring); break;
  	    }
! 		/* flag it for subsequent processing */
! 	    candidate->resource = (char *) candidate;
  	}
+ 	/*
+ 	 * Step 2.  Propagate classes for command line arguments.  Backwards.
+ 	 */
+ 	for (opt = options + XtNumber(options) - 1; opt >= options; --opt)
+ 	    if (opt->resource == (char *) opt) {
+ 		addr = opt->address;
+ 		lastopt = opt + opt->classcount;
+ 		for (candidate = opt; candidate < lastopt; ++candidate) {
+ 		    if (candidate->resource != NULL) {
+ 			switch (opt->argtype) {
+ 			    case BooleanArg:
+ 				*((Boolean *) candidate->address) =
+ 				    *((Boolean *) addr);
+ 				break;
+ 			    case StringArg:
+ 				*((char **) candidate->address) =
+ 				    *((char **) addr);
+ 				break;
+ 			    case NumberArg:
+ 				*((int *) candidate->address) = *((int *) addr);
+ 				break;
+ 			}
+ 			candidate->resource = NULL;
+ 		    }
+ 		}
+ 	    }
  
  #ifndef X10
  	if ((DISP = XOpenDisplay(display)) == NULL)
***************
*** 2132,2137 ****
--- 2206,2214 ----
  	if (XOpenDisplay(display) == NULL)
  	    oops("Can't open display");
  #endif
+ 	/*
+ 	 * Step 3.  Handle resources (including classes).
+ 	 */
  	for (opt = options; opt < options + XtNumber(options); ++opt)
  	    if (opt->resource &&
  #ifndef X10
***************
*** 2140,2161 ****
  #else
  		    (optstring = XGetDefault(DPY prog, opt->resource)))
  #endif
! 		switch (opt->argtype) {
! 		    case StringArg:
! 			*((char **) opt->address) = optstring;
! 			break;
! 		    case NumberArg:
! 			*((int *) opt->address) = atoi(optstring);
! 			break;
! 		    case BooleanArg:
! 			*((Boolean *) opt->address) =
! 			    (strcmp(optstring, "on") == 0);
  		}
- 
- 	if (!sidemargin) sidemargin = margins;
- 	if (!topmargin) topmargin = margins;
- 	if (!xoffset) xoffset = offsets;
- 	if (!yoffset) yoffset = offsets;
  }
  
  #endif	/* TOOLKIT */
--- 2217,2237 ----
  #else
  		    (optstring = XGetDefault(DPY prog, opt->resource)))
  #endif
! 		{
! 		    lastopt = opt + opt->classcount;
! 		    for (candidate = opt; candidate < lastopt; ++candidate)
! 			if (candidate->resource != NULL) switch (opt->argtype) {
! 			    case StringArg:
! 				*((char **) candidate->address) = optstring;
! 				break;
! 			    case NumberArg:
! 				*((int *) candidate->address) = atoi(optstring);
! 				break;
! 			    case BooleanArg:
! 				*((Boolean *) candidate->address) =
! 				    (strcmp(optstring, "on") == 0);
! 			}
  		}
  }
  
  #endif	/* TOOLKIT */
***************
*** 2382,2389 ****
--- 2458,2478 ----
  		highGC = MakeGC(GXcopy, hl_Pixel, back_Pixel);
  	}
  
+ #ifndef	VMS
  	ready_cursor = XCreateFontCursor(DISP, XC_cross);
  	redraw_cursor = XCreateFontCursor(DISP, XC_watch);
+ #else
+ 	DECWCursorFont = XLoadFont(DISP, "DECW$CURSOR");
+ 	XSetFont(DISP, foreGC, DECWCursorFont);
+ 	redraw_cursor = XCreateGlyphCursor(DISP, DECWCursorFont, DECWCursorFont,
+ 		decw$c_wait_cursor, decw$c_wait_cursor + 1,
+ 		&fore_color, &back_color);
+ 	MagnifyPixmap = XCreateBitmapFromData (DISP, RootWindowOfScreen(SCRN),
+ 		mag_glass_bits, mag_glass_width, mag_glass_height);
+ 	ready_cursor = XCreatePixmapCursor(DISP, MagnifyPixmap, MagnifyPixmap,
+ 		&back_color, &fore_color, mag_glass_x_hot, mag_glass_y_hot);
+ #endif	/* VMS */
+ 
  	if (!curs_color)
  	    cr_Pixel = high_color ? hl_Pixel : fore_Pixel;
  	{
***************
*** 2637,2643 ****
  #endif	/* X10 */
  
  	do_pages();
! #ifdef	lint
! 	return 0;
! #endif
  }
--- 2726,2730 ----
  #endif	/* X10 */
  
  	do_pages();
! 	/* NOTREACHED */
  }
diff -cr old/xdvi.h new/xdvi.h
*** old/xdvi.h	Sun Oct 21 14:49:17 1990
--- new/xdvi.h	Tue Jan 15 15:17:41 1991
***************
*** 135,141 ****
  extern	int	maxstack;
  extern	int	n_fonts_left;		/* for LRU management of fonts */
  extern	time_t	dvi_time;		/* last mod. time for dvi file */
- extern	char	*font_path;
  extern	int	page_w, page_h;
  
  /*
--- 135,140 ----
***************
*** 145,153 ****
  extern	long	*page_offset;
  
  /*
!  * Mechanism for reducing repeated warning about specials.
   */
! extern	Boolean	spec_warn, spec_warn_now;
  
  
  /*
--- 144,153 ----
  extern	long	*page_offset;
  
  /*
!  * Mechanism for reducing repeated warning about specials, lost characters, etc.
   */
! extern	Boolean	hush_spec, hush_spec_now;
! extern	Boolean	hush_chars;
  
  
  /*
***************
*** 202,208 ****
  	struct font *next;		/* link to next font info block */
  	int TeXnumber;			/* font number (in DVI file) */
  	int scale;			/* scaled size in SPELL units */
- 	float factor;			/* multiply char. widths by this */
  	char *fontname;			/* PXL file name */
  	short size;			/* dots per 5 inches */
  	FILE *file;			/* open PXL file or NULL */
--- 202,207 ----
diff -cr old/xdvi_man.sed new/xdvi_man.sed
*** old/xdvi_man.sed	Sun Oct 21 14:49:31 1990
--- new/xdvi_man.sed	Sat Feb  2 16:20:39 1991
***************
*** 9,19 ****
  .B xdvi
  .nh
  [+[\fIpage\fP]] [\-s \fIshrink\fP] [\-S \fIdensity\fP] [\-p \fIpixels\fP] [\-l]
! [\-sw] [\-paper \fIpapertype\fP] [\-mgs[\fIn\fP] \fIsize\fP]
! [\-altfont \fIfont\fP]
  [\-margins \fIdimen\fP] [\-sidemargin \fIdimen\fP] [\-topmargin \fIdimen\fP]
  [\-offsets \fIdimen\fP] [\-xoffset \fIdimen\fP] [\-yoffset \fIdimen\fP]
! [\-rv] [\-fg \fIcolor\fP] [\-bg \fIcolor\fP]
  [\-hl \fIcolor\fP] [\-bd \fIcolor\fP] [\-cr \fIcolor\fP] [\-bw \fIwidth\fP]
  #ifx11
  [\-geometry \fIgeometry\fP] [\-icongeometry \fIgeometry\fP] [\-iconic]
--- 9,19 ----
  .B xdvi
  .nh
  [+[\fIpage\fP]] [\-s \fIshrink\fP] [\-S \fIdensity\fP] [\-p \fIpixels\fP] [\-l]
! [\-paper \fIpapertype\fP] [\-mgs[\fIn\fP] \fIsize\fP]
! [\-hushspecials] [-hushchars] [-hush] [\-altfont \fIfont\fP]
  [\-margins \fIdimen\fP] [\-sidemargin \fIdimen\fP] [\-topmargin \fIdimen\fP]
  [\-offsets \fIdimen\fP] [\-xoffset \fIdimen\fP] [\-yoffset \fIdimen\fP]
! [\-keep] [\-rv] [\-fg \fIcolor\fP] [\-bg \fIcolor\fP]
  [\-hl \fIcolor\fP] [\-bd \fIcolor\fP] [\-cr \fIcolor\fP] [\-bw \fIwidth\fP]
  #ifx11
  [\-geometry \fIgeometry\fP] [\-icongeometry \fIgeometry\fP] [\-iconic]
***************
*** 94,105 ****
  (%%dot%%listFonts)
  Causes the names of the fonts used to be listed.
  .TP
! .B \-sw
! (%%dot%%specialWarn)
! Causes \fIxdvi\fR to warn the user when it encounters a \\special string
! which it cannot process.  This option is on by default; to turn it off,
! use \fB+sw\fR.
  .TP
  .B \-rv
  (%%dot%%reverseVideo)
  Causes the page to be displayed with white characters on a
--- 94,113 ----
  (%%dot%%listFonts)
  Causes the names of the fonts used to be listed.
  .TP
! .B \-hushspecials
! (%%dot%%hushSpecials)
! Causes \fIxdvi\fR to suppress warnings about \\special strings
! which it cannot process.
  .TP
+ .B \-hushchars
+ (%%dot%%hushLostChars)
+ Causes \fIxdvi\fR to suppress warnings about references to characters which
+ are not defined in the font.
+ .TP
+ .B \-hush
+ (%%dot%%Hush)
+ Causes \fIxdvi\fR to suppress all suppressable warnings.
+ .TP
  .B \-rv
  (%%dot%%reverseVideo)
  Causes the page to be displayed with white characters on a
***************
*** 159,169 ****
  Always use the \fIcopy\fR operation when writing characters to the display.
  This option may be necessary for correct operation on a color display, but
  overstrike characters will be incorrect.
  #ifbuttons
  .TP
  .B \-expert
  (.expert)
! Prevent the buttons from appearing.
  #endif
  .TP
  .BI \-margins " dimen"
--- 167,182 ----
  Always use the \fIcopy\fR operation when writing characters to the display.
  This option may be necessary for correct operation on a color display, but
  overstrike characters will be incorrect.
+ .TP
+ .B \-keep
+ (.keepPosition)
+ Sets a flag to indicate that \fIxdvi\fR should not move to the home position
+ when moving to a new page.  See also the `k' keystroke.
  #ifbuttons
  .TP
  .B \-expert
  (.expert)
! Prevent the buttons from appearing.  See also the `x' keystroke.
  #endif
  .TP
  .BI \-margins " dimen"
***************
*** 345,359 ****
  of the same file while running \fIxdvi\fR only once.
  .TP
  .B k
! Normally when \fIxdvi\fR switches pages it moves to the home position as well.
  The `k' keystroke toggles a `keep-position' flag which, when set, will keep
  the same position when moving between pages.  Also `0k' and `1k' clear and
! set this flag, respectively.
  #ifbuttons
  .TP
  .B x
  Toggles expert mode (in which the buttons do not appear).  Also `0x' and `1x'
! clear and reset this mode, respectively.
  #endif
  .SH MOUSE ACTIONS
  If the shrink factor is set to any number other than one, then clicking
--- 358,372 ----
  of the same file while running \fIxdvi\fR only once.
  .TP
  .B k
! Normally when \fIxdvi\fR switches pages, it moves to the home position as well.
  The `k' keystroke toggles a `keep-position' flag which, when set, will keep
  the same position when moving between pages.  Also `0k' and `1k' clear and
! set this flag, respectively.  See also the \fB\-keep\fR option.
  #ifbuttons
  .TP
  .B x
  Toggles expert mode (in which the buttons do not appear).  Also `0x' and `1x'
! clear and reset this mode, respectively.  See also the \fB\-expert\fR option.
  #endif
  .SH MOUSE ACTIONS
  If the shrink factor is set to any number other than one, then clicking
***************
*** 388,393 ****
--- 401,423 ----
  If the font cannot be found at all, then \fIxdvi\fR will try to vary the point
  size of the font (within a certain range), and if this fails, then it will
  use the font specified as the alternate font (cf. \fB-altfont\fR).
+ .PP
+ For compatibility with TeX, you may also use ``TEXFONTS'' in place of
+ ``XDVIFONTS'', although in that case the variable should not include any
+ ``%'' specifiers.
+ #ifsubdir
+ .PP
+ You can also enable recursive searching in the font path by using the ``*''
+ and ``**'' specifiers.  At this point in the path, \fIxdvi\fR will recursively
+ search subdirectories of the given directory in order to find font files.
+ A single asterisk limits the search to one level; a double asterisk will search
+ through an arbitrary number of levels.  Also, the variable TEXFONTS_SUBDIR
+ can be used to give a colon-separated list of directories to recursively search.
+ This is equivalent to including the specifiers with a ``*'' after each; the
+ usual conventions regarding extra colons applies here, too, relative to a
+ default subdirectory path.  Asterisks may not be preceded by a ``%'' specifier
+ in any path component.
+ #endif
  .PP
  The ``XDVISIZES'' variable must be set to indicate which sizes of fonts are
  available.  It should consists of a list of numbers separated by colons.  If
--
Dan Heller
------------------------------------------------
O'Reilly && Associates 		      Zyrcom Inc
Senior Writer			       President
argv@ora.com			argv@zipcode.com