Monitor source part 9 of 9

jct jct at jct.UUCP
Tue Jul 11 14:34:29 AEST 1989


#! /bin/sh
# This is a shell archive.  Remove anything before this line, then unpack
# it by saving it into a file and typing "sh file".  To overwrite existing
# files, type "sh file -c".  You can also feed this as standard input via
# unshar, or by typing "sh <file", e.g..  If this archive is complete, you
# will see the following message at the end:
#		"End of archive 9 (of 9)."
# Contents:  lib/help.c
# Wrapped by jct@ on Mon Jul 10 22:48:37 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'lib/help.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/help.c'\"
else
echo shar: Extracting \"'lib/help.c'\" \(40463 characters\)
sed "s/^X//" >'lib/help.c' <<'END_OF_FILE'
X/* Module help */
X
X/*
X   Provides context sensitive help functions for screen operations
X   Uses Uniplex II+ format files with optional KM index at front of file
X   file indexing is invisable to Uniplex II+, use hindex to make index.
X   The index will speed operations but it is not required.
X
X   Allows "subsections" for nested help menus. Subsection entries come
X   after a help section end, "))", and are indicated by a leading ".XXS".
X   That is followed by a required title an optional file and a required
X   section. The first non-blank line that does not begin with a ".XXS"
X   terminates that help menu. ".XXT" may be used to give a sub-help menu
X   a title other that "Help Menu".
X
X   Help windows smaller than full_screen may be specified by ".XXW" after
X   the section name  and the title line. ".XXW" is followed by 4
X   integers-> y_max, x_max, y_org, x_org.
X
X   For example :
X	#HELP
X        Help Title
X	.XXW 10 30 7 40
X		Help text
X	))
X	.XXT " Sub-Help Test Menu "
X	.XXS "Sub help a" HELPA
X	.XXS HelpB file_two helpb
X
X   This indicates a help section named HELP, that has one line of help text.
X   The help window is 10 lines x 30 columns starting at line 7 and column 40.
X   After that text is displayed, 2 entry menu is shown that consists of the
X   titles "Sub help a" and "HelpB". "Sub help a" section is in the same file
X   as the current section and is named "HELPA". "HelpB" section is in another
X   file, "file_two", and is section "helpb" of that other file. The title of
X   the menu is " Sub-Help Test Menu ".
X
X   Subsections that begin with .XXR are for redirecting help information
X   to another section and optional file.
X
X   Example :
X	#HELP
X	))
X	.XXR /usr/mine/help extra
X
X   This redirects to the extra help section in file /usr/min/help.
X*/
X
X/*
X   Created February 21, 1987 by JCT
X*/
X
X/*
X   For non-screen oriented programs define NONSCREEN
X*/
X
X/*
X *	Copyright (c) John C. Tompkins 1989
X *	All rights reserved.
X *
X *	Permission is granted to use this for any personal, noncommercial use.
X *	You may not distribute source or executable code for profit, nor
X *	may you distribute it with a commercial product without the prior
X *      written consent of the author.  Please send modifications to the 
X *      author for inclusion in updates to the program.
X */
X
X#include <stdio.h>
X#include <ctype.h>
X#include <string.h>
X
X#include <km/defs.h>
X#include <km/ascii.h>
X#include <km/string1.h>
X
X#ifdef DOS				/* must come after <km/defs.h> */
X#include <stdlib.h>
X#define HELPHELP "\\help\\help.hlp"
X#else
X#define HELPHELP "/usr/lib/help/help.hlp"
X#endif
X
X#ifdef NONSCREEN
X#include <km/tcap.h>
X#ifdef DOS
X#include <conio.h>
X#else
X#include <km/tctl.h>
X#endif
X#else
X#include <km/scrio.h>
X#include <km/scrops.h>
X#endif
X
X#define DEF_SECTION	"STANDARD"
X#define STACK_SIZE	10
X#define HEAD_SIZE       50
X#define BUF_SIZE	150
X#define SS_MAX		17		/* A thru P */
X#define SS_SIZE		500		/* allows 30 chars per entry avg */
X
X#define END_SECTION	0x0001
X#define HELP_EMPTY	0x0002
X#define STOP		0x0004
X#define IN_INDEX	0x0010
X#define GOT_INDEX	0x0020
X#define FOUND_SECTION	0x0040
X#define HAVE_KEY	0x0080
X#define PAGE_FULL	0x0400
X#define HELP_NUMERIC	0x0800
X#define NO_REFRESH      0x1000
X
X#ifdef NONSCREEN
typedef struct
X  {
X    short key;
X    char  *text;
X    char  *pointer;
X    char  *help_section;
X  } SCR_ENTRY;
X#endif
X
X#define END1_PROMPT   " END OF HELP, (Q)uit, (S)top, (T)op, <SPACE> to backup or <RETURN> to continue "
X#define END1S_PROMPT  " END (Q) (S) (T) <SPC> <RET> "
X#define END1M_PROMPT  " END (Q)uit, (S)top, (T)op, <SPACE> or <RETURN> "
X#define END2_PROMPT   " END OF HELP, (Q)uit, (S)top or <RETURN> to continue "
X#define END2S_PROMPT  " END (Q) (S) <RET> "
X#define END2M_PROMPT  " END (Q)uit, (S)top or <RETURN> "
X#define MORE1_PROMPT  " (Q)uit, (S)top or <RETURN> to continue "
X#define MORE1S_PROMPT " (Q) (S) <RET> "
X#define MORE1M_PROMPT " (Q)uit, (S)top or <RETURN> "
X#define MORE2_PROMPT  " (Q)uit, (S)top, (T)op, <SPACE> to backup or <RETURN> to continue "
X#define MORE2S_PROMPT " (Q) (S) (T) <SPC> <RET> "
X#define MORE2M_PROMPT " (Q)uit, (S)top, (T)op, <SPACE> or <RETURN> "
X
X#ifndef NONSCREEN
int help_fg, help_bg;
X#endif
X
X#ifdef NONSCREEN
X#define BOX_SIZE  11
X
static int  i, scr_lines, line_count, highlight, no_help = FALSE;
X#ifdef DOS
static int  graphic = TRUE, LINES = 25, COLS = 80;
static char box_tbl[BOX_SIZE] = { 196, 179, 197, 218, 194, 191, 180, 217, 193, 192, 195 };
static char *_SO = "\033[7m", *_SE = "\033[m";
static char *_GS = "", *_GE = "";
static char *_GB = box_tbl;
X#else
static int  graphic, LINES, COLS;
static int  tcap_done = FALSE;
static char *_SO, *_SE, *_GB, *_GS, *_GE;
static char box_tbl[BOX_SIZE];
static char fake_tbl[] = {'-', '|', '+', '+', '+', '+', '+', '+', '+', '+', '+'};
X#endif
X#endif
X
static int       quit, backup, *pflags;
static int       ss_count, ss_index, stack_index, level = 0;
static int       page_length, page;
static char      ss_array[SS_SIZE], *ss_ptr, *title, *more = NULL;
static char      buf1[BUF_SIZE], buf2[BUF_SIZE];
static char	 head[HEAD_SIZE];
static long      stack[STACK_SIZE];
static FILE	 *pfile;
static SCR_ENTRY subsection[SS_MAX];
X
X#ifndef NONSCREEN
static int       help_y_max, help_x_max, help_y_org, help_x_org;
static int	 len1, len2, len_eff, adjust, win_fg, win_bg, fs_count = 0;
static char      *more_eff = NULL;
static WINDOW    *fs_help = 0;
X#endif
X
extern long atol();
X#ifndef DOS
extern char *malloc();
X#endif
X
static char *ss_store(p1, p2)
X  REGISTER char *p1;
X  REGISTER char *p2;
X{
X
X/*
X   Copies from p1 up to p2 into the current free area in the ss_array
X   marked by ss_ptr. Checks for overflow on ss_array.
X*/
X
X  char *temp;
X
X  temp = ss_ptr;
X  if (ss_count >= (SS_SIZE - 1))
X    return(NULL);
X  while ((p1 < p2) && (ss_count < (SS_SIZE - 1)))
X    {
X      *ss_ptr++ = *p1++;
X      ss_count++;
X    }
X  *ss_ptr++ = '\0';
X  return(temp);
X}
X
static char *eatspace(p)
X  REGISTER char *p;
X{
X
X/*
X   Skips over leading whitespace.
X*/
X
X  while (isspace(*p))
X    p++;
X  return(p);
X}
X
static char *get_name(in_p, end_pp)
X  char *in_p;
X  char **end_pp;
X{
X
X/*
X   Starts at in_p, skipping leading whitespace. If next non-space is ", then
X   sets flag and skips the " also. Copies until whitespace or, if flag set,
X   until " character is found or end of line. If ended on ", the " is
X   changed to whitespace.
X*/
X
X  int  have_quote;
X  char *p1, *p2;
X
X  in_p = eatspace(in_p);
X  if ((have_quote = (*in_p == '"')) != FALSE)
X    in_p++;
X  p1 = in_p;
X  while (*in_p)
X    {
X      if (have_quote)
X	{
X	  if ((*in_p == '"') || (*in_p == '\n'))
X	    break;
X	}
X      else
X	{
X	  if (isspace(*in_p))
X	    break;
X	}
X      in_p++;
X    }
X  if (*in_p == '"')
X    *in_p = ' ';
X  p2 = in_p;
X  if (end_pp)
X    *end_pp = p2;
X  if (p1 != p2)
X    return(ss_store(p1, p2));
X  else
X    return(NULL);
X}
X
static char *findend(p)
X  REGISTER char *p;
X{
X
X/*
X   Finds whitespace or end of line.
X*/
X
X  while (*p && !isspace(*p))
X    p++;
X  return(p);
X}
X
static char *delimit(p)
X  REGISTER char *p;
X{
X
X/*
X   Substitutes null character, \0, for first whitespace found
X*/
X
X  while (*p)
X    {
X      if (isspace(*p))
X	{
X	  *p++ = '\0';
X	  break;
X	}
X      else
X        p++;
X    }
X  return(p);
X}
X
static int line_empty()
X{
X
X/*
X   Looks through a "line", actually a string, if any non whitespace
X   character the line is not empty. If all whitespace, its empty.
X*/
X
X  REGISTER char *p;
X
X  p = buf1;
X  while (*p)
X    {
X      if (*p == '\n')
X	return(TRUE);
X      if (!isspace(*p))
X	return(FALSE);
X      p++;
X    }
X  return(TRUE);
X}
X
X#ifdef NONSCREEN
static void GB_analyze()
X{
X  char *temp;
X  int  i;
X
X  if (!_GB || !_GS || !_GE)
X    {
X      _GS = NULL;
X      _GE = NULL;
X      return;
X    }
X  temp = _GB;
X  for (i = 0; i < BOX_SIZE; i++)
X    box_tbl[i] = '\0';
X  while (*temp)
X    {
X      i = 0;
X      while (*temp && (i < BOX_SIZE))
X	{
X	  box_tbl[i] = *temp;
X	  temp++;
X	  i++;
X	}
X    }
X  if (i != BOX_SIZE)
X    {
X      _GS = NULL;
X      _GE = NULL;
X      return;
X    }
X  return;
X}
X
static int center(p)
X  REGISTER char *p;
X{
X
X/*
X   Returns the number of spaces needed to center the passed string on screen
X   In screen mode, this function provided in scrops.c
X*/
X
X  return(((COLS - strlen(p)) / 2) - 1);
X}
X
static int addgraphic(ch)
X  int ch;
X{
X
X/*
X   Displays the coded "graphic" character. Uses normal ASCII in nonscreen mode.
X   In screen mode, this function provided by scrops.c and makes use of a 
X   terminals line drawing set, if available.
X*/
X
X  if (graphic)
X    {
X      if ((ch >= 'A') && (ch <= 'K'))
X        fputc(box_tbl[ch - 'A'], stdout);
X      else
X        fputc(' ', stdout);
X    }
X#ifndef DOS
X  else
X    {
X      if ((ch >= 'A') && (ch <= 'K'))
X        fputc(fake_tbl[ch - 'A'], stdout);
X      else
X        fputc(' ', stdout);
X    }
X#endif
X  return(TRUE);
X}
X
static int graphbegin()
X{
X  if (!graphic && _GS)
X    {
X      fflush(stdout);
X      put_cap(_GS);
X      graphic = TRUE;
X      return(TRUE);
X    }
X  return(FALSE);
X}
X
static int graphend()
X{
X  if (graphic && _GE)
X    {
X      fflush(stdout);
X      put_cap(_GE);
X      graphic = FALSE;
X      return(TRUE);
X    }
X  return(FALSE);
X}
X
static int standout()
X{
X  if (!highlight && _SO)
X    {
X      fflush(stdout);
X      put_cap(_SO);
X      highlight = TRUE;
X      return(TRUE);
X    }
X  return(FALSE);
X}
X
static int standend()
X{
X  if (highlight && _SE)
X    {
X      fflush(stdout);
X      put_cap(_SE);
X      highlight = FALSE;
X      return(TRUE);
X    }
X  return(FALSE);
X}
X
static void put_prompt(str)
X  char *str;
X{
X  standout();
X  fputs(str, stdout);
X  standend();
X}
X#endif
X
static char *get_head()
X{
X
X/*
X   The first line after the section introduction is the help section name
X   that is displayed at the top center of the screen. This function returns
X   a pointer to that name or to a default name if the first line is blank.
X   Strips leading and trailing whitespace, but pads the name with 1 leading
X   and trailing blank. The name is the full line, " not special.
X*/
X
X  int           count = 0;
X  REGISTER char *p1;
X  REGISTER char *p2;
X
X  p1 = eatspace(buf1);
X  p2 = head;
X  if (!*p1 || (*p1 == '\n'))
X    return(NULL);
X  *p2++ = ' ';
X  while (*p1 && (*p1 != '\n') && (++count < 48))
X    *p2++ = *p1++;
X  p2--;
X  while (isspace(*p2))
X    p2--;
X  p2++;
X  *p2++ = ' ';
X  *p2 = '\0';
X  return(head);
X}
X
static int is_ruler()
X{
X
X/*
X   If more than 40 dots on the line, we assume its a ruler
X*/
X
X  REGISTER char *p1;
X  REGISTER int  count = 0;
X
X  p1 = buf1;
X  while (*p1)
X    {
X      if (*p1++ == '.')
X        count++;
X    } 
X  return(count > 40);
X}
X
X#ifndef NONSCREEN
static void get_wsize()
X{
X  REGISTER char *p1;
X
X  p1 = buf1 + 4;
X  help_y_max = atoi(p1);
X  p1 = eatspace(p1);
X  p1 = findend(p1);
X  help_x_max = atoi(p1);
X  p1 = eatspace(p1);
X  p1 = findend(p1);
X  help_y_org = atoi(p1);
X  p1 = eatspace(p1);
X  p1 = findend(p1);
X  help_x_org = atoi(p1);
X}
X
static void get_wcolor()
X{
X  REGISTER char *p1;
X  REGISTER char *p2;
X
X  p1 = eatspace(buf1 + 4);
X  p2 = delimit(p1);
X  win_fg = get_color(p1);
X  p1 = eatspace(p2);
X  p2 = delimit(p1);
X  win_bg = get_color(p1);
X}
X#endif
X
static int get_intro(help_file, flags)
X  FILE *help_file;
X  int  *flags;
X{
X
X/*
X   Reads the beginning of a help section to determine a possible window
X   size (.XXW) and section "title".
X*/
X
X  title = NULL;
X  more = NULL;
X#ifndef NONSCREEN
X  more_eff = NULL;
X#endif
X  *flags &= ~PAGE_FULL;
X  while (TRUE)
X    {
X      if (fgets(buf1, sizeof(buf1), help_file))
X        {
X	  if (is_ruler())
X	    ;
X          else if (substr(buf1, "))", TRUE))
X	    {
X	      *flags |= END_SECTION;
X	      *flags |= PAGE_FULL;
X	      return(FALSE);
X	    }
X          else
X	    {
X	      if (title)
X		{
X          	  if (substr(buf1, ".XXW", TRUE))
X#ifdef NONSCREEN
X		    ;
X#else
X	    	    get_wsize();
X#endif
X		  else if (substr(buf1, ".XXC", TRUE))
X#ifdef NONSCREEN
X		    ;
X#else
X	    	    get_wcolor();
X#endif
X		  else
X		    {
X		      more = buf1;
X		      break;
X		    }
X		}
X	      else
X	        title = get_head();
X	    }
X        }
X      else
X        {
X          *flags |= END_SECTION;
X          *flags |= PAGE_FULL;
X          return(FALSE);
X        }
X    }
X  return(TRUE);
X}
X
static int find_section(help_file, section, offset_end, flags)
X  FILE *help_file;
X  char *section;
X  long *offset_end;
X  int  *flags;
X{
X
X/*
X   Searches the start of the help file for an index and if found, searches
X   the index for the desired section for direct fseek()-ing to. If the index
X   exists but the section is not found, aborts. If the index does not exist,
X   searches the file sequentally until section found or end of file, much
X   slower.
X*/
X
X  REGISTER char *p1;
X  REGISTER char *p2;
X
X#ifndef NONSCREEN
X  help_y_max = LINES;
X  help_x_max = COLS;
X  help_y_org = 0;
X  help_x_org = 0;
X  win_fg = help_fg;
X  win_bg = help_bg;
X#endif
X  while (!(*flags & FOUND_SECTION) && (fgets(buf1, sizeof(buf1), help_file)))
X    {
X      if (*flags & IN_INDEX)
X	{
X	  if (substr(buf1, ".XXI", TRUE))
X	    {
X	      *flags |= GOT_INDEX;
X	      p1 = eatspace(buf1 + 4);
X	      p2 = delimit(p1);
X	      if (substr(p1, section, TRUE))
X	        {
X		  stack[0] = atol(p2);
X		  p2 = eatspace(p2);
X		  p2 = findend(p2);
X		  *offset_end = atol(p2);
X		  fseek(help_file, stack[0], 0);
X		  *flags |= FOUND_SECTION;
X		}
X	    }
X	  else if (!line_empty())
X	    {
X	      if (*flags & GOT_INDEX)
X		return(FALSE);
X	      *flags &= ~IN_INDEX;
X	    }
X	}
X      if (*buf1 == '#')
X	{
X	  delimit(buf1);
X	  if (substr((buf1 + 1), section, TRUE))
X	    {
X	      stack[0] = ftell(help_file);
X	      *flags |= FOUND_SECTION;
X	    }
X	}
X    }
X  get_intro(help_file, flags);
X  return(*flags & FOUND_SECTION);
X}
X
X#ifdef NONSCREEN
static int is_dot(flags)
X  int *flags;
X#else
static int is_dot(scr, flags)
X  SCR *scr;
X  int *flags;
X#endif
X{
X  int  temp;
X
X  if (*buf1 == '.')
X    {
X      if (substr((buf1 + 1), "PA", TRUE))
X        *flags |= PAGE_FULL;
X      else if (substr((buf1 + 1), "PL", TRUE))
X        {
X#ifdef NONSCREEN
X          if ((temp = atoi(buf1 + 3)) <= (LINES - 4))
X#else
X          if ((temp = atoi(buf1 + 3)) <= (scr->win->y_max - 4))
X#endif
X	    page_length = temp;
X          else
X#ifdef NONSCREEN
X            page_length = LINES - 4;
X#else
X            page_length = scr->win->y_max - 4;
X#endif
X        }
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
X
X#ifdef NONSCREEN
static int is_effect(help_file)
X  FILE *help_file;
X#else
static int is_effect(scr, help_file)
X  SCR  *scr;
X  FILE *help_file;
X#endif
X{
X#ifdef NONSCREEN
X  char *p1, *p2;
X#endif
X  char *p3;
X  int  count;
X
X  count = UNDETERMINED;
X  p3 = (strend(buf1) - 3);
X  if (substr(p3, "@@\n", TRUE))			/* attribute mark? */
X    {
X#ifdef NONSCREEN
X      if (fgets(buf2, sizeof(buf2), help_file)) /* get attributes */
X	{
X          count = 0;
X	  p1 = buf1;
X	  p2 = buf2;
X	  while (p1 < p3)
X	    {
X	      if (*p2 == '[')
X		{
X		  if (!graphic)
X		    graphbegin();
X		  addgraphic(*p1);
X		}
X	      else if (*p2 == ' ')
X		{
X	  	  if (highlight)
X	    	    standend();
X	  	  if (graphic)
X	    	    graphend();
X		  fputc(*p1, stdout);
X		}
X	      else
X		{
X		  if (graphic)
X		    graphend();
X		  if (!highlight)
X		    standout();
X		  fputc(*p1, stdout);
X		}
X	      count++;
X	      p1++;
X	      if (*p2)
X		p2++;
X	    }
X	  if (highlight)
X	    standend();
X	  if (graphic)
X	    graphend();
X	  fputc('\n', stdout);
X	  count++;
X	}
X#else
X      if (more_eff || fgets(buf2, sizeof(buf2), help_file))
X	{
X	  if (more_eff)
X	    {
X	      strcpy(buf2, more_eff);
X	      len2 = strlen(buf2);
X	      more_eff = NULL;
X	    }
X	  else
X	    {
X	      len2 = strlen(buf2);
X	      len_eff = len2;
X	    }
X          len1 = strlen(buf1);
X	  if (len2 > (len1 - 2))
X	    {
X	      strcpy(buf2, (buf2 + len2 - (len1 - 2)));
X	      len2 = len1 - 2;
X	    }
X	  count = waddtext(scr->win, buf1, buf2, (scr->win->flags & BOX_FLAG));
X	}
X#endif
X    }
X  return(count);
X}
X
X#ifdef NONSCREEN
static int get_page(help_file, flags)
X  FILE *help_file;
X  int  *flags;
X#else
static int get_page(scr, help_file, flags)
X  SCR  *scr;
X  FILE *help_file;
X  int  *flags;
X#endif
X{
X
X/*
X   Reads enough lines to fill a help page and puts up the header info
X*/
X
X#ifdef NONSCREEN
X  int temp;
X#else
X  int             count, did_eff;
X  REGISTER WINDOW *win;
X#endif
X
X  if (*flags & END_SECTION)
X    return(FALSE);
X  *flags &= ~PAGE_FULL;
X#ifdef NONSCREEN
X  line_count = 0;
X  printf("\n Page %2d", page);
X  for (i = 0, (temp = center(title) - 8); i < temp; i++)
X    fputc(' ', stdout);
X  standout();
X  fputs(title, stdout);
X  standend();
X  fputc('\n', stdout);
X  fputc('\n', stdout);
X  scr_lines = 2;
X#else
X  win = scr->win;
X  werase(win);
X  if (win->flags & BOX_FLAG)
X    wmove(win, 2, 1);
X  else
X    {
X      wmove(win, 0, 1);
X      wprintw(win, "Page %2d", page);
X      wmove(win, 2, 0);
X    }
X#endif
X  while (!(*flags & PAGE_FULL) && (more || fgets(buf1, sizeof(buf1), help_file)))
X    {
X      if (more)
X	{
X	  strcpy(buf1, more);
X          more = NULL;
X	}
X#ifndef NONSCREEN
X      else
X	more_eff = NULL;
X#endif
X      if (is_ruler())
X	;
X#ifdef NONSCREEN
X      else if (is_dot(flags))
X#else
X      else if (is_dot(scr, flags))
X#endif
X	;
X      else if (substr(buf1, "))", TRUE))
X	{
X	  *flags |= END_SECTION;
X	  *flags |= PAGE_FULL;
X	}
X      else
X	{
X#ifdef NONSCREEN
X	  if (is_effect(help_file) == UNDETERMINED)
X	    fputs(buf1, stdout);
X	  if (strlen(buf1) <= COLS)
X	    temp = 1;
X	  else
X	    temp = 2;
X	  line_count += temp;
X	  scr_lines += temp;
X          if (line_count >= page_length)
X	    *flags |= PAGE_FULL;
X#else
X	  if ((count = did_eff = is_effect(scr, help_file)) == UNDETERMINED)
X	    count = waddtext(win, buf1, NULL, (win->flags & BOX_FLAG));
X	  more = buf1 + count;
X	  if (*more)
X	    {
X	      if (did_eff == UNDETERMINED)
X		more_eff = NULL;
X	      else
X	        more_eff = buf2 + ((count < len2) ? count : len2);
X	    }
X	  else
X	    {
X	      more = NULL;
X	      more_eff = NULL;
X	    }
X          if (win->y_cur > (page_length + 1))
X	    *flags |= PAGE_FULL;
X#endif
X	  if ((*flags & HELP_EMPTY) && !line_empty())
X	    *flags &= ~HELP_EMPTY;
X	}
X    }
X#ifndef NONSCREEN
X  if (more)
X    {
X      adjust = strlen(more);
X      if (more_eff)
X	adjust += len_eff;
X    }
X  else
X    adjust = 0;
X#endif
X  if (*flags & HELP_EMPTY)
X    return(FALSE);
X#ifdef NONSCREEN
X  else
X    {
X      while (scr_lines < (LINES - 1))
X	{
X	  fputc('\n', stdout);
X	  scr_lines++;
X	}
X      return(TRUE);
X    }
X#else
X  return(TRUE);
X#endif
X}
X
X#ifdef NONSCREEN
static void helphelp(seek)
X  int seek;
X#else
static void helphelp(scr)
X  SCR *scr;
X#endif
X{
X  char   save_head[HEAD_SIZE], *save_title;
X  char   save_buf1[BUF_SIZE], save_buf2[BUF_SIZE];
X  char   *save_more;
X  long   save_stack[STACK_SIZE];
X  FILE	 *save_file;
X  int    *save_flags, save_page, save_pl, save_si;
X#ifndef NONSCREEN
X  char   *save_me;
X  SCR    new_scr;
X#endif
X
X#ifdef NONSCREEN
X  no_help = TRUE;
X#else
X  new_scr.win = scr->win;
X  new_scr.head = 0;
X  new_scr.func_entry = 0;
X  new_scr.func_loop = scr->func_loop;
X  new_scr.func_chk = 0;
X  new_scr.prompt = 0;
X  new_scr.entry = 0;
X  new_scr.active_entry = 0;
X  new_scr.last_active = 0;
X  new_scr.timeout = scr->timeout;
X  new_scr.help_file = HELPHELP;
X  new_scr.help_section = NULL;
X  new_scr.flags = (scr->flags & (SCR_HELP_LOOP | SCR_NUMERIC));
X  new_scr.flags |= (SCR_RAW | SCR_NO_ERASE | SCR_NO_HELP);
X  new_scr.lflags = 0;
X  new_scr.color = 0;
X#endif
X  save_file = pfile;
X  save_flags = pflags;
X  save_page = page;
X  save_pl = page_length;
X  save_si = stack_index;
X  memcpy(save_stack, stack, sizeof(stack));
X  save_title = title;
X  strcpy(save_head, head);
X  save_more = more;
X#ifndef NONSCREEN
X  save_me = more_eff;
X#endif
X  memcpy(save_buf1, buf1, sizeof(buf1));
X  memcpy(save_buf2, buf2, sizeof(buf2));
X#ifdef NONSCREEN
X  do_help(HELPHELP, NULL, 0);
X#else
X  sdo_help(&new_scr);
X#endif
X  pfile = save_file;
X  pflags = save_flags;
X  page = save_page;
X  page_length = save_pl;
X  stack_index = save_si;
X  memcpy(stack, save_stack, sizeof(stack));
X  title = save_title;
X  strcpy(head, save_head);
X  more = save_more;
X#ifndef NONSCREEN
X  more_eff = save_me;
X#endif
X  memcpy(buf1, save_buf1, sizeof(buf1));
X  memcpy(buf2, save_buf2, sizeof(buf2));
X  quit = FALSE;
X  backup = FALSE;
X#ifdef NONSCREEN
X  if (seek)
X    {
X      fseek(pfile, stack[stack_index], 0);
X      more = NULL;
X      if (stack_index == 0)
X	get_intro(pfile, pflags);
X      *pflags &= ~END_SECTION;
X    }
X  no_help = FALSE;
X#endif
X}
X
X#ifdef NONSCREEN
static int help_chk_key(flags, key)
X  REGISTER int *flags;
X  REGISTER int key;
X#else
static int help_chk_key(scr, key)
X  REGISTER SCR *scr;
X  REGISTER int key;
X#endif
X{
X  int i;
X
X  switch (tolower(key))
X    {
X      case UNDETERMINED :
X	break;
X      case 'q' :
X      case K_QUIT :
X      case K_CANCEL :
X        quit = TRUE;
X#ifdef NONSCREEN
X	*flags |= HAVE_KEY;
X#else
X	scr->lflags |= SCR_QUIT;
X#endif
X	break;
X      case 's' :
X      case K_END_SCREEN :
X      case K_END_BUF :
X      case K_END_LINE :
X	*pflags |= STOP;
X#ifdef NONSCREEN
X	*flags |= HAVE_KEY;
X#else
X	scr->lflags |= SCR_QUIT;
X#endif
X	break;
X      case 't' :
X      case K_BEG_SCREEN :
X      case K_BEG_BUF :
X      case K_BEG_LINE :
X	if (stack_index >= 1)
X	  {
X	    stack_index = 0;
X	    fseek(pfile, stack[stack_index], 0);
X	    more = NULL;
X#ifndef NONSCREEN
X	    more_eff = NULL;
X#endif
X	    get_intro(pfile, pflags);
X	    page = 1;
X	    *pflags &= ~END_SECTION;
X#ifdef NONSCREEN
X	    *flags |= HAVE_KEY;
X#else
X	    scr->lflags |= SCR_QUIT;
X#endif
X	  }
X        break;
X      case ' ' :
X      case K_UP :
X      case K_BACKUP :
X      case K_BWD_SCREEN :
X      case K_BWD_WORD :
X	if (stack_index >= 1)
X	  {
X	    stack_index--;
X	    fseek(pfile, stack[stack_index], 0);
X	    more = NULL;
X#ifndef NONSCREEN
X	    more_eff = NULL;
X#endif
X	    if (stack_index > 0)
X	      page--;
X	    else
X	      {
X	        get_intro(pfile, pflags);
X	        page = 1;
X	      }
X	    *pflags &= ~END_SECTION;
X#ifdef NONSCREEN
X	    *flags |= HAVE_KEY;
X#else
X	    scr->lflags |= SCR_QUIT;
X#endif
X	  }
X        break;
X      case K_HELP :
X      case K_F0 :
X      case '?' :
X#ifdef NONSCREEN
X	if (!no_help)
X	  helphelp(TRUE);
X	*flags |= HAVE_KEY;
X#else
X	if (!(scr->flags & SCR_NO_HELP))
X	  helphelp(scr);
X#endif
X	break;
X      case LF :
X      case CR :
X      case K_DOWN :
X      case K_FWD_SCREEN :
X      case K_FWD_WORD :
X	if (!(*pflags & END_SECTION))
X	  {
X	    stack_index++;
X	    if (stack_index >= STACK_SIZE)
X	      {
X		for (i = 1; i < (STACK_SIZE - 1); i++)
X		  stack[i] = stack[i + 1];
X		stack_index--;
X	      }
X#ifdef NONSCREEN
X	    stack[stack_index] = ftell(pfile);
X#else
X	    stack[stack_index] = ftell(pfile) - adjust;
X#endif
X	    page++;
X	  }
X#ifdef NONSCREEN
X	*flags |= HAVE_KEY;
X#else
X	scr->lflags |= SCR_QUIT;
X#endif
X	break;
X    }
X  return(TRUE);
X}
X
X#ifdef NONSCREEN
static int put_page(help_file, flags)
X  FILE *help_file;
X  int  *flags;
X#else
static int put_page(scr, help_file, flags)
X  SCR  *scr;
X  FILE *help_file;
X  int  *flags;
X#endif
X{
X
X/*
X   Puts the prompt at the bottom of a full page then inputs and interprets
X   the user input
X*/
X
X#ifndef NONSCREEN
X  REGISTER WINDOW *win;
X#endif
X
X#ifndef NONSCREEN
X  win = scr->win;
X  scr->flags &= ~SCR_NO_PROMPT;
X#endif
X  if (*flags & END_SECTION)
X    {
X      if (stack_index >= 1)
X#ifdef NONSCREEN
X	put_prompt(END1_PROMPT);
X#else
X	{
X	  if (win->x_max < 30)
X	    scr->flags |= SCR_NO_PROMPT;
X	  else if (win->x_max < 50)
X	    scr->prompt = END1S_PROMPT;
X	  else if (win->x_max < 80)
X	    scr->prompt = END1M_PROMPT;
X	  else
X	    scr->prompt = END1_PROMPT;
X	}
X#endif
X      else
X#ifdef NONSCREEN
X	put_prompt(END2_PROMPT);
X#else
X	{
X	  if (win->x_max < 30)
X	    scr->flags |= SCR_NO_PROMPT;
X	  else if (win->x_max < 50)
X	    scr->prompt = END2S_PROMPT;
X	  else if (win->x_max < 80)
X	    scr->prompt = END2M_PROMPT;
X	  else
X	    scr->prompt = END2_PROMPT;
X	}
X#endif
X    }
X  else
X    {
X      if (stack_index >= 1)
X#ifdef NONSCREEN
X	put_prompt(MORE2_PROMPT);
X#else
X	{
X	  if (win->x_max < 30)
X	    scr->flags |= SCR_NO_PROMPT;
X	  else if (win->x_max < 50)
X	    scr->prompt = MORE2S_PROMPT;
X	  else if (win->x_max < 80)
X	    scr->prompt = MORE2M_PROMPT;
X	  else
X	    scr->prompt = MORE2_PROMPT;
X	}
X#endif
X      else
X#ifdef NONSCREEN
X	put_prompt(MORE1_PROMPT);
X#else
X	{
X	  if (win->x_max < 30)
X	    scr->flags |= SCR_NO_PROMPT;
X	  else if (win->x_max < 50)
X	    scr->prompt = MORE1S_PROMPT;
X	  else if (win->x_max < 80)
X	    scr->prompt = MORE1M_PROMPT;
X	  else
X	    scr->prompt = MORE1_PROMPT;
X	}
X#endif
X    }
X  pflags = flags;
X  pfile = help_file;
X#ifdef NONSCREEN
X  *flags &= ~HAVE_KEY;
X  do
X    {
X#ifdef DOS
X      help_chk_key(flags, getch());
X#else
X      help_chk_key(flags, getchar());
X#endif
X    }
X  while (!(*flags & HAVE_KEY));
X  fputc('\n', stdout);
X#else
X  do_scr(scr);
X#endif
X  return(TRUE);
X}
X
static void get_end(help_file, offset_end, flags)
X  FILE *help_file;
X  long *offset_end;
X  int  *flags;
X{
X  if (*flags & GOT_INDEX)
X    {
X      if (!(*flags & END_SECTION))
X	{
X	  if (*offset_end != UNDETERMINED)
X	    {
X	      fseek(help_file, *offset_end, 0);
X	      *flags |= END_SECTION;
X	    }
X	  else
X	    {
X	      while (!(*flags & END_SECTION) && fgets(buf1, sizeof(buf1), help_file))
X		{
X		  if (substr(buf1, "))", TRUE))
X		    *flags |= END_SECTION;
X		}
X	      *offset_end = ftell(help_file);
X	    }
X	}
X    }
X  else
X    {
X      while (!(*flags & END_SECTION) && fgets(buf1, sizeof(buf1), help_file))
X	{
X	  if (substr(buf1, "))", TRUE))
X	    *flags |= END_SECTION;
X	}
X      *offset_end = ftell(help_file);
X    }
X}
X
X#ifdef NONSCREEN
static void redirect(file)
X  char *file;
X#else
static void redirect(scr)
X  SCR  *scr;
X#endif
X{
X  char      *p2;
X  char      *help_file, *help_section, *help_buf;
X
X  if (level > 0)
X    level--;
X#ifndef NONSCREEN
X  if (fs_help && (fs_help == scr->win))
X    {
X      if (--fs_count == 0)
X	{
X	  delwin(scr->win, FALSE);
X	  fs_help = WIN_NULL;
X	}
X    }
X  else
X    delwin(scr->win, FALSE);
X  scr->win = WIN_NULL;
X#endif
X  if ((help_section = get_name(buf1 + 4, &p2)) == NULL)
X    return;
X  if ((p2 = get_name(p2, NULL)) != NULL)
X    {
X      help_file = help_section;
X      help_section = p2;
X    }
X  else
X#ifdef NONSCREEN
X    help_file = file;
X#else
X    help_file = scr->help_file;
X#endif
X  if ((help_buf = malloc(strlen(help_file) + 1)) == NULL)
X    return;
X  strcpy(help_buf, help_file);
X#ifdef NONSCREEN
X  do_help(help_buf, help_section, 0);
X#else
X  scr->help_file = help_buf;
X  scr->help_section = help_section;
X  sdo_help(scr);
X#endif
X  free(help_buf);
X}
X
X#ifdef NONSCREEN
static int subhelp_chk_key(flags, file, key)
X  int  *flags;
X  char *file;
X  int  key;
X#else
static int subhelp_chk_key(scr, key)
X  SCR *scr;
X  int key;
X#endif
X{
X  char *help_buf = 0;
X  int  stat;
X#ifdef NONSCREEN
X  static SCR_ENTRY *p;
X#else
X  static int entry_number = 0;
X#endif
X
X
X  key = tolower(key);
X  switch (key)
X    {
X      case UNDETERMINED :
X	break;
X      case 'q' :
X      case K_QUIT :
X	quit = TRUE;
X#ifdef NONSCREEN
X	*flags |= HAVE_KEY;
X	fputc('\n', stdout);
X#else
X	scr->lflags |= SCR_QUIT;
X#endif
X	break;
X      case ' ' :
X      case K_BACKUP :
X      case K_BWD_SCREEN :
X      case K_BWD_WORD :
X	if (level > 1)
X	  {
X	    backup = TRUE;
X#ifdef NONSCREEN
X	    *flags |= HAVE_KEY;
X	    fputc('\n', stdout);
X#else
X	    scr->lflags |= SCR_QUIT;
X#endif
X	  }
X	break;
X      case K_HELP :
X      case K_F0 :
X      case '?' :
X#ifdef NONSCREEN
X	if (!no_help)
X	  helphelp(FALSE);
X	*flags |= HAVE_KEY;
X#else
X	if (!(scr->flags & SCR_NO_HELP))
X	  helphelp(scr);
X#endif
X	break;
X#ifndef NONSCREEN
X      case CR :
X      case LF :
X        if (scr->flags & SCR_NUMERIC)
X	  {
X	    if ((entry_number > 0) && (entry_number <= ss_index))
X	      scr->active_entry = &subsection[entry_number - 1];
X	    entry_number = 0;
X	  }
X	if (scr->active_entry)
X	  {
X	    if (scr->active_entry->pointer)
X	      {
X                if ((help_buf = malloc(strlen(scr->active_entry->pointer) + 1)) == NULL)
X    		  break;
X		strcpy(help_buf, scr->active_entry->pointer);
X                scr->help_file = help_buf;
X	      }
X	    scr->help_section = scr->active_entry->help_section;
X	    scr->active_entry->func = sdo_help;
X	    scr->active_entry->pointer = (char*)scr;
X	    scr->active_entry->flags = (SCR_PPARM | SCR_PUT_ACTIVE);
X	    stat = do_active_entry(scr);
X	    if (help_buf)
X	      free(help_buf);
X	    if (stat)
X	      scr->lflags |= SCR_QUIT;
X	  }
X	break;
X      case K_UP :
X        if (scr->active_entry)
X	  {
X	    put_entry(scr, scr->active_entry, FALSE);
X	    if (scr->active_entry == scr->entry)
X	      scr->active_entry = 0;
X	    else
X	      scr->active_entry--;
X	  }
X	else
X	  scr->active_entry = &subsection[ss_index - 1];
X	if (scr->active_entry)
X	  put_entry(scr, scr->active_entry, TRUE);
X        scr->last_active = scr->active_entry;
X	break;
X      case K_DOWN :
X        if (scr->active_entry)
X	  {
X	    put_entry(scr, scr->active_entry, FALSE);
X	    scr->active_entry++;
X	    if (scr->active_entry->key == UNDETERMINED)
X	      scr->active_entry = 0;
X	  }
X	else
X	  scr->active_entry = scr->entry;
X	if (scr->active_entry)
X	  put_entry(scr, scr->active_entry, TRUE);
X        scr->last_active = scr->active_entry;
X	break;
X      case '0' :
X      case '1' :
X      case '2' :
X      case '3' :
X      case '4' :
X      case '5' :
X      case '6' :
X      case '7' :
X      case '8' :
X      case '9' :
X	if (scr->flags & HELP_NUMERIC)
X	  {
X	    entry_number = (entry_number * 10) + key - '0';
X	    if (entry_number > 99)
X	      entry_number = 0;
X	  }
X	break;
X#endif
X      default :
X	key = key - 'a';
X	if ((key >= 0) && (key < ss_index))
X	  {
X#ifdef NONSCREEN
X	    p = &subsection[key];
X            if ((help_buf = malloc(strlen(p->pointer ? p->pointer : file) + 1)) == NULL)
X              break;
X	    strcpy(help_buf, p->pointer ? p->pointer : file);
X	    stat = do_help(help_buf, p->help_section, 0);
X	    if (help_buf)
X	      free(help_buf);
X	    if (stat)
X	      *flags |= HAVE_KEY;
X#else
X	    scr->active_entry = &subsection[key];
X	    if (scr->active_entry->pointer)
X	      {
X                if ((help_buf = malloc(strlen(scr->active_entry->pointer) + 1)) == NULL)
X    		  break;
X		strcpy(help_buf, scr->active_entry->pointer);
X                scr->help_file = help_buf;
X	      }
X	    scr->help_section = scr->active_entry->help_section;
X	    scr->active_entry->func = sdo_help;
X	    scr->active_entry->pointer = (char*)scr;
X	    scr->active_entry->flags = (SCR_PPARM | SCR_PUT_ACTIVE);
X	    stat = do_active_entry(scr);
X	    if (help_buf)
X	      free(help_buf);
X	    if (stat)
X	      scr->lflags |= SCR_QUIT;
X#endif
X	  }
X	break;
X    }
X  return(TRUE);
X}
X
X#ifndef NONSCREEN
char *set_prompt(scr)
X  SCR *scr;
X{
X  if (level > 1)
X    {
X      if (scr->win->x_max < 30)
X        scr->flags |= SCR_NO_PROMPT;
X      else if (scr->win->x_max < 45)
X        scr->prompt = " (Q)uit, <SPACE> or select ";
X      else 
X        scr->prompt = " (Q)uit, <SPACE> to backup or selection ";
X    }
X  else
X    {
X      if (scr->win->x_max < 25)
X        scr->flags |= SCR_NO_PROMPT;
X      else 
X        scr->prompt = " (Q)uit or selection ";
X    }
X}
X#endif
X
X#ifdef NONSCREEN
static int do_subhelp(file, help_file, offset_end, flags)
X  char *file;
X  FILE *help_file;
X  long *offset_end;
X  int  *flags;
X#else
static int do_subhelp(scr, help_file, offset_end, flags)
X  SCR  *scr;
X  FILE *help_file;
X  long *offset_end;
X  int  *flags;
X#endif
X{
X
X/*
X   If at the end of the help section there is a subsection description, this
X   function processes that description to call nested help.
X*/
X
X#ifdef NONSCREEN
X  int     temp;
X#else
X  int     have_window = FALSE;
X  int     full_screen;
X  WINDOW  *new_win;
X#endif
X  int     empty;
X  char    *help_title, *p1, *p2;
X
X#ifdef NONSCREEN
X  static SCR_ENTRY *p;
X#endif
X
X  backup = FALSE;
X#ifndef NONSCREEN
X  scr->func_chk = subhelp_chk_key;
X  scr->entry = subsection;
X  scr->active_entry = 0;
X  scr->last_active = 0;
X#endif
X  while (!quit && !backup)
X    {
X      *flags &= ~STOP;
X#ifndef NONSCREEN
X      help_y_max = LINES;
X      help_x_max = COLS;
X      help_y_org = 0;
X      help_x_org = 0;
X      win_fg = help_fg;
X      win_bg = help_bg;
X      scr->flags &= (SCR_NUMERIC | SCR_HELP_LOOP | SCR_MPOPUP);
X      scr->flags |= (SCR_NO_INI | SCR_RAW | SCR_MENU);
X      scr->lflags = 0;
X#endif
X      get_end(help_file, offset_end, flags);
X      ss_ptr = ss_array;
X      ss_index = 0;
X      ss_count = 0;
X      help_title = NULL;
X      while (fgets(buf1, sizeof(buf1), help_file))
X	{
X          if ((empty = !line_empty()) != FALSE)
X	    {
X	      if (substr(buf1, ".XXR", TRUE))
X		{
X#ifdef NONSCREEN
X		  redirect(file);
X#else
X		  redirect(scr);
X#endif
X		  return(TRUE);
X		}
X	      else if (substr(buf1, ".XXW", TRUE))
X#ifdef NONSCREEN
X		;
X#else
X		{
X		  get_wsize();
X		  have_window = TRUE;
X		}
X#endif
X	      else if (substr(buf1, ".XXC", TRUE))
X#ifdef NONSCREEN
X		;
X#else
X		get_wcolor();
X#endif
X	      else if (substr(buf1, ".XXT", TRUE))
X		{
X                  if ((help_title = get_name(buf1 + 4, NULL)) == NULL)
X		    break;
X		}
X 	      else if (substr(buf1, ".XXS", TRUE))
X		{
X	          if (ss_index >= (SS_MAX - 1))
X		    break;
X		  subsection[ss_index].key = 0;
X	          subsection[ss_index].pointer = NULL;
X	          subsection[ss_index].help_section = NULL;
X                  if ((subsection[ss_index].text = get_name(buf1 + 4, &p2)) == NULL)
X	            break;
X                  if ((subsection[ss_index].help_section = get_name(p2, &p2)) == NULL)
X		    break;
X                  if ((p2 = get_name(p2, NULL)) != NULL)
X		    {
X		      subsection[ss_index].pointer = subsection[ss_index].help_section;
X		      subsection[ss_index].help_section = p2;
X		    }
X	          ss_index++;
X		}
X	      else
X		break;
X	    }
X	  else if (empty)
X	    break;
X	}
X      subsection[ss_index].key = UNDETERMINED;
X      if (!backup && (ss_index > 0))
X	{
X#ifndef NONSCREEN
X          if (have_window && ((new_win = newwin(help_y_max, help_x_max, help_y_org, help_x_org)) != WIN_NULL))
X	    {
X  	      if (fs_help && (fs_help == scr->win))
X    		{
X      		  if (--fs_count == 0)
X		    {
X	  	      delwin(scr->win, FALSE);
X	  	      fs_help = WIN_NULL;
X		    }
X    		}
X  	      else
X    		delwin(scr->win, FALSE);
X  	      scr->win = new_win;
X  	      full_screen = ((help_y_max == LINES) && (help_x_max == COLS) &&
X      		             (help_y_org == 0) && (help_x_org == 0));
X  	      if (full_screen)
X		{
X		  fs_help = new_win;
X		  fs_count++;
X		}
X	      else
X		{
X		  if (scr->win->x_max < 30)
X		    scr->flags |= SCR_NO_PROMPT;
X		}
X	    }
X	  else
X	    full_screen = TRUE;
X	  wsetcolor(scr->win, win_fg, win_bg);
X	  if (!full_screen)
X	    {
X	      box(scr->win);
X	      scr->flags |= SCR_MPOPUP;
X	    }
X#endif
X	  if (help_title)
X	    p1 = help_title;
X	  else if (*flags & HELP_EMPTY)
X	    p1 = " Help Menu ";
X	  else
X	    p1 = " Additional Help Menu ";
X#ifdef NONSCREEN
X	    fputc('\n', stdout);
X	    for (i = 0, temp = center(p1); i < temp; i++)
X	      fputc(' ', stdout);
X	    standout();
X	    fputs(p1, stdout);
X	    standend();
X	    fputc('\n', stdout);
X	    fputc('\n', stdout);
X	    fputc('\n', stdout);
X#else
X	    scr->head = p1;
X#endif
X#ifdef NONSCREEN
X	  for (temp = 0, p = subsection, scr_lines = 3; scr_lines < (LINES - 1); temp++, p++, scr_lines++)
X	    {
X	      if (temp < ss_index)
X		printf("         %c : %s\n", (temp + 'A'), p->text);
X	      else
X		fputc('\n', stdout);
X	    }
X#endif
X#ifdef NONSCREEN
X	  if (level > 1)
X	    put_prompt(" (Q)uit, <SPACE> to backup or selection ");
X	  else
X	    put_prompt(" (Q)uit or selection ");
X#else
X	    set_prompt(scr);
X#endif
X	  *flags &= ~HAVE_KEY;
X	  pfile = help_file;
X#ifdef NONSCREEN
X	  do
X	    {
X#ifdef DOS
X	      subhelp_chk_key(flags, file, getch());
X#else
X	      subhelp_chk_key(flags, file, getchar());
X#endif
X	    }
X	  while (!(*flags & HAVE_KEY));
X#else
X	  do_scr(scr);
X#endif
X	  *flags &= ~END_SECTION;
X	}
X      else
X        backup = TRUE;
X    }
X  backup = FALSE;
X  return(TRUE);
X}
X
X#ifndef NONSCREEN
static WINDOW *get_window(scr)
X  REGISTER SCR    *scr;
X{
X  int    full_screen;
X  WINDOW *new_win;
X
X  full_screen = ((help_y_max == LINES) && (help_x_max == COLS) &&
X      (help_y_org == 0) && (help_x_org == 0));
X  if (full_screen && fs_help)
X    {
X      new_win = fs_help;
X      fs_count++;
X    }
X  else if ((new_win = newwin(help_y_max, help_x_max, help_y_org, help_x_org)) != WIN_NULL)
X    {
X      if (full_screen)
X	{
X	  fs_help = new_win;
X	  fs_count++;
X	}
X    }
X  else
X    return((WINDOW*)0);
X  wsetcolor(new_win, win_fg, win_bg);
X  if (!full_screen)
X    {
X      box(new_win);
X      page_length = new_win->y_max - 4;
X    }
X  else
X    page_length = new_win->y_max - 4;
X  scr->win = new_win;
X  scr->head = title;
X  scr->func_entry = 0;
X  scr->func_loop = 0;
X  scr->func_chk = help_chk_key;
X  scr->prompt = 0;
X  scr->entry = 0;
X  scr->active_entry = 0;
X  scr->last_active = 0;
X  scr->timeout = UNDETERMINED;
X  scr->help_file = 0;
X  scr->help_section = 0;
X  scr->flags = (SCR_RAW | SCR_NO_ERASE);
X  scr->lflags = 0;
X  scr->color = 0;
X  return(new_win);
X}
X#endif
X
X#ifdef NONSCREEN
int do_help(file, section, xflags)
X  char *file;
X  char *section;
X  int  xflags;
X#else
int sdo_help(scr)
X  SCR *scr;
X#endif
X{
X  FILE   *help_file;
X  long   offset_end;
X  int    stat, flags;
X
X#ifndef NONSCREEN
X  char   *section;
X  SCR    help_scr;
X#endif
X
X#ifdef NONSCREEN
X  if (file)
X    {
X      if ((help_file = fopen(file, "r")) != NULL)
X#else
X  if (scr->help_file)
X    {
X      if ((help_file = fopen(scr->help_file, "r")) != NULL)
X#endif
X        {
X          if (level == 0)
X	    {
X#ifdef NONSCREEN
X#ifdef UNIX
X	      if (!tcap_done)
X		{
X	          if ((LINES = get_icap("li")) == ERROR)
X		    LINES = 24;
X	          if ((COLS = get_icap("co")) == ERROR)
X		    COLS = 80;
X		  tcap_done = TRUE;
X		  if (!(_SO = get_scap("so")) || !(_SE = get_scap("se")))
X		    {
X		      _SO = NULL;
X		      _SE = NULL;
X		    }
X		  graphic = FALSE;
X		  _GS = get_scap("GS");
X		  _GE = get_scap("GE");
X		  _GB = get_scap("GB");
X		  GB_analyze();
X	        }
X	      if (xflags)
X		{
X	          tc_crmode();
X	          tc_noecho();
X		}
X#endif
X#endif
X	      quit = FALSE;
X	      backup = FALSE;
X	    }
X          level++;
X          flags = (IN_INDEX | HELP_EMPTY);
X          offset_end = 0;
X          stack_index = 0;
X          page = 1;
X#ifndef NONSCREEN
X	  if (scr->active_entry)
X	    section = scr->active_entry->help_section;
X	  else
X	    section = scr->help_section;
X#endif
X          if (!section)
X	    section = DEF_SECTION;
X          if (find_section(help_file, section, &offset_end, &flags))
X	    {
X#ifdef NONSCREEN
X              page_length = LINES - 4;
X#else
X	      if (!get_window(&help_scr))
X		{
X		  fclose(help_file);
X		  return(FALSE);
X		}
X	      help_scr.help_file = scr->help_file;
X	      help_scr.flags |= (scr->flags & SCR_NO_HELP);
X	      if (scr->flags & SCR_NUMERIC)
X		{
X		  help_scr.flags |= SCR_NUMERIC;
X                  flags |= HELP_NUMERIC;
X		}
X	      if (scr->flags & SCR_HELP_LOOP)
X		{
X		  help_scr.flags |= SCR_HELP_LOOP;
X		  help_scr.func_loop = scr->func_loop;
X		  help_scr.timeout = scr->timeout;
X		}
X	      if ((scr->flags & SCR_TYPE_AHEAD) && !(scr->lflags & SCR_UP))
X		flags |= NO_REFRESH;
X#endif
X              while (!quit && !(flags & STOP) && !(flags & END_SECTION))
X	        {
X#ifdef NONSCREEN
X	          if (get_page(help_file, &flags))
X	            put_page(help_file, &flags);
X#else
X	          if (get_page(&help_scr, help_file, &flags))
X	            put_page(&help_scr, help_file, &flags);
X#endif
X                }
X	      if (!quit)
X#ifdef NONSCREEN
X                do_subhelp(file, help_file, &offset_end, &flags);
X#else
X                do_subhelp(&help_scr, help_file, &offset_end, &flags);
X#endif
X#ifndef NONSCREEN
X	      if (fs_help && (fs_help == help_scr.win))
X		{
X		  if (--fs_count == 0)
X		    {
X		      if (help_scr.win)
X	                delwin(help_scr.win, !(flags & NO_REFRESH));
X		      fs_help = WIN_NULL;
X		    }
X		}
X	      else
X		{
X		  if (help_scr.win)
X	            delwin(help_scr.win, !(flags & NO_REFRESH));
X		}
X#endif
X	      stat = TRUE;
X	    }
X          else
X	    stat = FALSE;
X          fclose(help_file);
X          if (level > 0)
X	    level--;
X#ifdef NONSCREEN
X	  if (level == 0)
X	    {
X#ifdef UNIX
X	      if (xflags)
X		{
X	          tc_nocrmode();
X		  tc_echo();
X		}
X#endif
X	    }
X#endif
X	}
X      else
X	stat = FALSE;
X    }
X  return(stat);
X}
X
X#ifndef NONSCREEN
int wdo_help(win, file, section, flags)
X  WINDOW *win;
X  char   *file;
X  char   *section;
X  int    flags;
X{
X  SCR scr;
X
X  scr.win = win;
X  scr.head = 0;
X  scr.func_entry = 0;
X  scr.func_loop = 0;
X  scr.func_chk = 0;
X  scr.prompt = 0;
X  scr.entry = 0;
X  scr.active_entry = 0;
X  scr.last_active = 0;
X  scr.timeout = UNDETERMINED;
X  scr.help_file = file;
X  scr.help_section = section;
X  scr.flags = flags;
X  scr.lflags = 0;
X  scr.color = 0;
X  return(sdo_help(&scr));
X}
X#endif
X
END_OF_FILE
if test 40463 -ne `wc -c <'lib/help.c'`; then
    echo shar: \"'lib/help.c'\" unpacked with wrong size!
fi
# end of 'lib/help.c'
fi
echo shar: End of archive 9 \(of 9\).
cp /dev/null ark9isdone
MISSING=""
for I in 1 2 3 4 5 6 7 8 9 ; do
    if test ! -f ark${I}isdone ; then
	MISSING="${MISSING} ${I}"
    fi
done
if test "${MISSING}" = "" ; then
    echo You have unpacked all 9 archives.
    rm -f ark[1-9]isdone ark[1-9][0-9]isdone
else
    echo You still need to unpack the following archives:
    echo "        " ${MISSING}
fi
##  End of shell archive.
exit 0



More information about the Comp.unix.xenix mailing list