Monitor source part 8 of 9

jct jct at jct.UUCP
Tue Jul 11 14:33:00 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 8 (of 9)."
# Contents:  lib/scrout1.c
# Wrapped by jct@ on Mon Jul 10 22:48:32 1989
PATH=/bin:/usr/bin:/usr/ucb ; export PATH
if test -f 'lib/scrout1.c' -a "${1}" != "-c" ; then 
  echo shar: Will not clobber existing file \"'lib/scrout1.c'\"
else
echo shar: Extracting \"'lib/scrout1.c'\" \(37438 characters\)
sed "s/^X//" >'lib/scrout1.c' <<'END_OF_FILE'
X/* module screen output */
X
X/*
X   provides UNIX "curses" type routines
X   define MMAPPED if output is memory mapped
X*/
X
X/*
X   created May 5, 1987 by JCT
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 <fcntl.h>
X#include <ctype.h>
X
X#include <km/defs.h>
X#include <km/ascii.h>
X#include <km/scrio.h>
X#include <km/string1.h>
X
X#ifdef DOS				/* must come after <km/defs.h> */
X#include <dos.h>
X#endif
X
X/*
X  The following are masks and forground, background color bits
X*/
X
X#define A_MASK		0x00ff		/* attribute flags mask */
X#define C_MASK		0x00ff		/* color flags mask */
X#define F_MASK		0x00f0		/* 16 colors, 4 bits */
X#define B_MASK		0x000f		/* 16 colors, 4 bits */
X#define F_BLACK		0x0000
X#define F_RED		0x0010
X#define F_GREEN		0x0020
X#define F_YELLOW	0x0030
X#define F_BLUE		0x0040
X#define F_MAGENTA	0x0050
X#define F_CYAN		0x0060
X#define F_WHITE		0x0070
X#define F_C8		0x0080
X#define F_C9		0x0090
X#define F_C10		0x00a0
X#define F_C11		0x00b0
X#define F_C12		0x00c0
X#define F_C13		0x00d0
X#define F_C14		0x00e0
X#define F_C15		0x00f0
X#define B_BLACK		0x0000
X#define B_RED		0x0001
X#define B_GREEN		0x0002
X#define B_YELLOW	0x0003
X#define B_BLUE		0x0004
X#define B_MAGENTA	0x0005
X#define B_CYAN		0x0006
X#define B_WHITE		0x0007
X#define B_C8		0x0008
X#define B_C9		0x0009
X#define B_C10		0x000a
X#define B_C11		0x000b
X#define B_C12		0x000c
X#define B_C13		0x000d
X#define B_C14		0x000e
X#define B_C15		0x000f
X#define OUTBUF_SIZE	256
X#define IOUTBUF_SIZE	20
X#define COLOR_SIZE	16
X#define BOX_SIZE	11
X
typedef struct
X  {
X    char  *name;
X    short value;
X  } COLOR_ENTRY;
X
typedef struct
X  {
X    int fg;
X    int bg;
X  } COLOR_BITS;
X
int     LINES, COLS;
int     have_standout, have_blink, have_bold, have_underline;
int     have_color, have_graphic, rev_color;
int     def_fg = WHITE, def_bg = BLACK;
WINDOW	*stdscr = WIN_NULL;
WINDOW  *curscr = WIN_NULL;
X#ifdef UNIX
KEY_TBL key_tbl[KEY_TBL_SIZE];
int     key_tbl_index;
X#endif
X
X#ifdef UNIX
static char       termcap[1024], tc_tbl[1024], *tc_ptr;
X#endif
X#ifndef MMAPPED
static char       *_al, *_cd, *_ce, *_ci, *_cl, *_cm, *_dc, *_dl, *_do,
X		  *_ei, *_im, *_is, *_nd, *_se, *_sf, *_so, *_sr, *_te,
X	 	  *_ti, *_ue, *_us, *_ve, *_vs, *_sc, *_gs, *_ge, *_bs,
X		  *_be, *_hs, *_he;
static char       outbuf[OUTBUF_SIZE];
static char       *pout = outbuf;
static char       *color_tbl[COLOR_SIZE];
static int        outbuf_count = 0, pfast = TRUE;
static short      *c_color, *c_attrib, *c_y_cur, *c_x_cur, c_x_max;
X#endif
static char	  *_ke, *_ks, *_gb;
static char       ioutbuf[IOUTBUF_SIZE];
static char       *piout = ioutbuf;
static int        ioutbuf_count = 0;
static char       box_tbl[BOX_SIZE];
static char       fake_tbl[BOX_SIZE] = {'-', '|', '+', '+', '+', '+', '+', '+', '+', '+', '+'};
static int	  LAST_y, LAST_x;
X
static COLOR_ENTRY color_table[] =
X  {
X    "BLACK",        BLACK,
X    "RED",          RED,
X    "GREEN",        GREEN,
X    "YELLOW",       YELLOW,
X    "BLUE",         BLUE,
X    "MAGENTA",      MAGENTA,
X    "CYAN",         CYAN,
X    "WHITE",        WHITE,
X    "COLOR_8",      COLOR_8,
X    "COLOR_9",      COLOR_9,
X    "COLOR_10",     COLOR_10,
X    "COLOR_11",     COLOR_11,
X    "COLOR_12",     COLOR_12,
X    "COLOR_13",     COLOR_13,
X    "COLOR_14",     COLOR_14,
X    "COLOR_15",     COLOR_15,
X    "UNDETERMINED", UNDETERMINED,
X    0, 0
X  };
X
static COLOR_BITS bits_tbl[] =
X  {
X    F_BLACK,   B_BLACK,
X    F_RED,     B_RED,
X    F_GREEN,   B_GREEN,
X    F_YELLOW,  B_YELLOW,
X    F_BLUE,    B_BLUE,
X    F_MAGENTA, B_MAGENTA,
X    F_CYAN,    B_CYAN,
X    F_WHITE,   B_WHITE,
X    F_C8,      B_C8,
X    F_C9,      B_C9,
X    F_C10,     B_C10,
X    F_C11,     B_C11,
X    F_C12,     B_C12,
X    F_C13,     B_C13,
X    F_C14,     B_C14,
X    F_C15,     B_C15,
X  };
X
extern char *malloc(), *getenv(), *tgetstr(), *strcpy();
extern void free();
extern FILE *popen(), *fopen();
X
X/*
X  The following are support routines
X*/
X
X#ifndef MMAPPED
X
X#define _puts(s)	tputs(s, 0, _putchar)
X
static void _flush_outbuf()		/* flush physical output buffer */
X{
X#ifdef DOS
X  int i;
X
X  for (i = 0; i < outbuf_count; i++)
X    bdos(0x06, outbuf[i], 0);
X  pout = outbuf;
X  outbuf_count = 0;
X#else
X  if (outbuf_count > 0)
X    {
X      write(_tty_ch, outbuf, outbuf_count);
X      pout = outbuf;
X      outbuf_count = 0;
X    }
X#endif
X}
X
static void _putchar(data)		/* physical output of data */
X  int data;
X{
X  *pout++ = data;
X  if (++outbuf_count >= OUTBUF_SIZE)
X    _flush_outbuf();
X}
X
static void _putstr(data)
X  REGISTER char *data;
X{
X  if (data)
X    {
X      while (*data)
X	{
X	  *pout++ = *data++;
X	  if (++outbuf_count >= OUTBUF_SIZE)
X	    _flush_outbuf();
X	}
X    }
X}
X
X#endif
X
static void _iflush_outbuf()		/* flush immediate output buffer */
X{
X#ifdef DOS
X  int i;
X
X  for (i = 0; i < ioutbuf_count; i++)
X    bdos(0x06, ioutbuf[i], 0);
X  piout = ioutbuf;
X  ioutbuf_count = 0;
X#else
X  if (ioutbuf_count > 0)
X    {
X      write(_tty_ch, ioutbuf, ioutbuf_count);
X      piout = ioutbuf;
X      ioutbuf_count = 0;
X    }
X#endif
X}
X
static void _iputchar(data)		/* physical output immediate */
X  int data;
X{
X  *piout++ = data;
X  if (++ioutbuf_count >= IOUTBUF_SIZE)
X    _iflush_outbuf();
X}
X
static void _iputs(s)			/* immediate output string */
X  char *s;
X{
X  tputs(s, 0, _iputchar);
X  _iflush_outbuf();
X}
X
X#ifndef MMAPPED
X
static void _goto(y, x)			/* physical cursor positioning */
X  int y;
X  int x;
X{
X  REGISTER WINDOW *p;
X
X  p = curscr;
X  if (p->y_cur == y)
X    {
X      if ((p->x_cur - 1) == x)
X	{
X	  if (BC)
X	    _puts(BC);
X	  else
X	    _putchar(BS);
X	}
X      else if ((p->x_cur + 1) == x)
X	{
X	  if (_nd)
X	    _puts(_nd);
X	  else
X	    _puts(tgoto(_cm, x, y));
X	}
X      else
X	_puts(tgoto(_cm, x, y));
X    }
X  else if (p->x_cur == x)
X    {
X      if ((p->y_cur - 1) == y)
X	{
X	  if (UP)
X	    _puts(UP);
X	  else
X	    _puts(tgoto(_cm, x, y));
X	}
X      else if ((p->y_cur + 1) == y)
X	{
X	  if (_do)
X	    _puts(_do);
X	  else
X	    _puts(tgoto(_cm, x, y));
X	}
X      else
X	_puts(tgoto(_cm, x, y));
X    }
X  else
X    _puts(tgoto(_cm, x, y));
X  p->y_cur = y;
X  p->x_cur = x;
X}
X
static void _setcolor(color)		/* physical set terminal color */
X  int color;
X{
X  REGISTER char *ptr1, *ptr2;
X
X  if (ptr1 = _sc)
X    {
X      while (*ptr1)
X        {
X          if (*ptr1 == '%')
X	    {
X              if (*(ptr1 + 1) == 'f')
X                {
X                  ptr2 = color_tbl[(color >> 4) & 0x0f];
X                  while (*ptr2)
X	            _putchar(*ptr2++);
X	          ptr1++;
X	        }
X              else if (*(ptr1 + 1) == 'b')
X                {
X	          ptr2 = color_tbl[color & 0x0f];
X	          while (*ptr2)
X	            _putchar(*ptr2++);
X	          ptr1++;
X	        }
X              else if (*(ptr1 + 1) == '%')
X                {
X	          _putchar('%');
X	          ptr1++;
X	        }
X	    }
X          else
X            _putchar(*ptr1);
X          ptr1++;
X	}
X    }
X  curscr->color = color;
X}
X
static void _setattrib(attrib, color)	/* physical set terminal attributes */
X  REGISTER int attrib;
X  int          color;
X{
X  REGISTER short *p;
X
X  p = &curscr->attrib;
X  if ((*p & GRAPHIC) && !(attrib & GRAPHIC))
X    _puts(_ge);
X  if (!(rev_color && color) && (*p & STANDOUT) && !(attrib & STANDOUT))
X    _puts(_se);
X  else if (*p & BLINK)
X    _puts(_be);
X  else if (*p & BOLD)
X    _puts(_he);
X  else if (*p & UNDERLINE)
X    _puts(_ue);
X  if (!(*p & GRAPHIC) && (attrib & GRAPHIC))
X    _puts(_gs);
X  if (!(rev_color && color) && !(*p & STANDOUT) && (attrib & STANDOUT))
X    _puts(_so);
X  else if (attrib & BLINK)
X    _puts(_bs);
X  else if (attrib & BOLD)
X    _puts(_hs);
X  else if (attrib & UNDERLINE)
X    _puts(_us);
X  *p = attrib;
X#ifdef DOS
X  curscr->color = 0;
X#endif
X}
X
static int so_analyze()			/* check standout ability */
X{
X  char *so_ptr;
X
X  if (!_se)
X    _so = NULL;
X  if (so_ptr = _so)
X    {
X      while (isdigit(*so_ptr))
X	so_ptr++;
X      if (!isprint(*so_ptr))
X	return(TRUE);
X      else
X	{
X	  _so = NULL;
X	  _se = NULL;
X	  return(FALSE);
X	}
X    }
X  else
X    return(FALSE);
X}
X
static int sc_analyze()			/* check and set color parameters */
X{
X  char *temp;
X  int  i, all_em = FALSE, fg = FALSE, bg = FALSE;
X
X  if (!_sc)
X    return(FALSE);
X  temp = _sc;
X  for (i = 0; i < COLOR_SIZE; i++)
X    color_tbl[i] = NULL;
X  while (*temp)
X    {
X      if (*temp == '%')
X	{
X          if (*(temp + 1) == 'f')
X	    {
X	      fg = TRUE;
X	      temp++;
X	    }
X          else if (*(temp + 1) == 'b')
X	    {
X	      bg = TRUE;
X	      temp++;
X	    }
X          else if (*(temp + 1) == 'c')
X	    {
X	      *temp = '\0';
X	      temp += 2;
X	      i = 0;
X	      while (*temp && (i < COLOR_SIZE))
X	        {
X		  color_tbl[i] = temp;
X		  while (*temp && (*temp != ','))
X		    temp++;
X		  *temp++ = '\0';
X		  i++;
X		}
X	      all_em = (i == COLOR_SIZE);
X	    }
X	}
X      temp++;
X    }
X  if (!fg || !bg || !all_em)
X    {
X      _sc = NULL;
X      return(FALSE);
X    }
X  else
X    return(TRUE);
X}
X
X#endif					/* ifndef MMAPPED */
X
static int gb_analyze()			/* check and set box parameters */
X{
X  char *temp;
X  int  i;
X
X#ifndef MMAPPED
X  if (!_gb || !_gs || !_ge)
X    {
X      _gs = NULL;
X      _ge = NULL;
X      return(FALSE);
X    }
X#endif
X  temp = _gb;
X  for (i = 0; i < BOX_SIZE; i++)
X    box_tbl[i] = UNDETERMINED;
X  i = 0;
X  while (*temp && (i < BOX_SIZE))
X    {
X      box_tbl[i] = *temp;
X      temp++;
X      i++;
X    }
X  if (i != BOX_SIZE)
X    {
X#ifndef MMAPPED
X      _gs = NULL;
X      _ge = NULL;
X#endif
X      return(FALSE);
X    }
X  else
X    return(TRUE);
X}
X
X#ifndef MMAPPED
X
static int us_analyze()
X{
X  if (_us && _ue)
X    return(TRUE);
X  _us = NULL;
X  _ue = NULL;
X  return(FALSE);
X}
X
static int bs_analyze()
X{
X  if (_bs && _be)
X    return(TRUE);
X  _bs = NULL;
X  _be = NULL;
X  return(FALSE);
X}
X
static int hs_analyze()
X{
X  if (_hs && _he)
X    return(TRUE);
X  _hs = NULL;
X  _he = NULL;
X  return(FALSE);
X}
X
X#endif					/* if MMAPPED */
X
X#ifdef UNIX
static void init_key_tbl()
X{
X  key_tbl_index = 0;
X}
X
static void add_key_tbl(name, default_seq, value)
X  char *name;
X  char *default_seq;
X  int  value;
X{
X
X/*
X   adds an ASCII keysequence to the lookup table
X   used to decipher arrows keys, function keys etc...
X*/
X
X  if (key_tbl_index < KEY_TBL_SIZE)
X    {
X      if (!name || (!(key_tbl[key_tbl_index].str = tgetstr(name, &tc_ptr))))
X	key_tbl[key_tbl_index].str = default_seq;
X      key_tbl[key_tbl_index].key = value;
X      key_tbl_index++;
X    }
X}
X#endif
X
X/*
X   The following are standard "curses" like routines that use "static"
X   data or functions. All other functions are in other files.
X*/
X
int endwin()				/* end screen modes */
X{
X  WINDOW *next;
X
X  for (next = stdscr->next; next && next->next; next = next->next)
X    ;
X  for (; next && next->prev; next = next->prev)
X    delwin(next, FALSE);
X  wendattrib(stdscr);
X  wsetcolor(stdscr, def_fg, def_bg);
X  werase(stdscr);
X#ifndef MMAPPED
X  werase(curscr);
X#endif
X  wrefresh(stdscr);
X  keypadend();
X#ifndef MMAPPED
X  if (_te)
X    _puts(_te);
X  if (_ve)
X    _puts(_ve);
X  _flush_outbuf();
X#endif
X  resetty();
X  return(TRUE);
X}
X
WINDOW *initscr()			/* begin screen modes */
X{
X  char *ttptr;
X
X  if (!stdscr)
X    {
X      _tty_ch = fileno(stdout);
X#ifdef DOS
X      ttptr = Def_term;
X#else
X      if (My_term || ((ttptr = getenv("TERM")) == NULL))
X        ttptr = Def_term;
X#endif
X      if (!setterm(ttptr))
X        return(WIN_NULL);
X#ifdef MMAPPED
X      if ((curscr = (WINDOW*)malloc(sizeof(WINDOW))) == WIN_NULL)
X        return(WIN_NULL);
X      curscr->buf_len = 0;
X      curscr->y_max = LINES;
X      curscr->x_max = COLS;
X      curscr->y_org = 0;
X      curscr->x_org = 0;
X      curscr->y_cur = 0;
X      curscr->x_cur = 0;
X      curscr->ch_cur = 0;
X      curscr->ch_first = 0;
X      curscr->ch_last = 0;
X      curscr->color = 0;
X      curscr->attrib = 0;
X      curscr->ch_flags = 0;
X      curscr->flags = 0;
X      curscr->prev = 0;
X      curscr->next = 0;
X#else
X      if ((curscr = newwin(LINES, COLS, 0, 0)) == WIN_NULL)
X        return(WIN_NULL);
X      c_color = &curscr->color;
X      c_attrib = &curscr->attrib;
X      c_y_cur = &curscr->y_cur;
X      c_x_cur = &curscr->x_cur;
X      c_x_max = curscr->x_max;
X#endif
X      if ((stdscr = newwin(LINES, COLS, 0, 0)) == WIN_NULL)
X        {
X#ifndef MMAPPED
X          free(curscr->buf);
X          free(curscr);
X#endif
X          return(WIN_NULL);
X        }
X      LAST_y = LINES - 1;
X      LAST_x = COLS - 1;
X      savetty();
X#ifdef DOS
X      ospeed = 0;
X#else
X      ospeed = _stty.c_cflag & CBAUD;
X#endif
X    }
X  else
X    werase(stdscr);
X#ifndef MMAPPED
X  werase(curscr);
X#endif
X  raw();
X  noecho();
X  nonl();
X#ifndef MMAPPED
X  if (_is)
X    _puts(_is);
X  if (_ti)
X    _puts(_ti);
X  if (_vs)
X    _puts(_vs);
X  _flush_outbuf();			/* force output before keypad */
X#endif
X  keypad();				/* keypad output is immediate */
X  wrefresh(stdscr);
X  return(stdscr);
X}
X
WINDOW *newwin(lines, cols, y_org, x_org)	/* make a new window */
X  int lines;
X  int cols;
X  int y_org;
X  int x_org;
X{
X  WINDOW *win, *p;
X
X  if ((y_org < 0) || (x_org < 0) ||
X      (lines <= 0) || ((y_org + lines) > LINES) ||
X      (cols <= 0) || ((x_org + cols) > COLS))
X    return(WIN_NULL);
X  if ((win = (WINDOW*)malloc(sizeof(WINDOW))) == WIN_NULL)
X    return(WIN_NULL);
X  win->buf_len = lines * cols;
X  if ((win->buf = (YX_ELEMENT*)malloc(win->buf_len * sizeof(YX_ELEMENT))) == (YX_ELEMENT*)NULL)
X    {
X      free((char*)win);
X      return(WIN_NULL);
X    }
X  win->y_max = lines;
X  win->x_max = cols;
X  win->y_org = y_org;
X  win->x_org = x_org;
X  win->y_cur = 0;
X  win->x_cur = 0;
X  win->ch_cur = win->buf;
X  win->ch_first = win->buf + win->buf_len - 1;
X  win->ch_last = win->buf;
X  win->color = 0;
X  win->attrib = 0;
X  win->flags = 0;
X  win->ch_flags = 0;
X  if (stdscr == WIN_NULL)
X    {
X      win->prev = WIN_NULL;
X      win->next = WIN_NULL;
X    }
X  else
X    {
X      for (p = stdscr; p->next != WIN_NULL; p = p->next)
X	;
X      p->next = win;
X      win->prev = p;
X      win->next = NULL;
X    }
X  if ((y_org == 0) && (x_org == 0) && (lines == LINES) && (cols == COLS))
X    win->flags |= FULLWINDOW;
X#ifndef MMAPPED
X  if (((x_org + cols) == COLS) && _ce)
X    win->flags |= TSTCLRTOEOL;
X#endif
X  wsetcolor(win, def_fg, def_bg);
X  werase(win);
X  return(win);
X}
X
int setterm(name)			/* set terminal parameters for name */
X  char *name;
X{
X  int stat = TRUE;
X
X#ifdef UNIX
X  init_key_tbl();
X#endif
X  if (!name || !*name)
X    name = Def_term;
X#ifdef MMAPPED
X  ini_mmscr();
X#endif
X#ifdef DOS
X#ifndef MMAPPED
X  LINES = 25;
X  COLS = 80;
X  _al = "\033[L";
X  BC = 0;
X  _cd = "\033[J";
X  _ce = "\033[K";
X  _cl = "\033[2J\e[H";
X  _cm = "\033[%i%d;%dH";
X  _dc = "\033[P";
X  _dl = "\033[M";
X  _do = 0;
X  _ei = 0;
X  _im = 0;
X  _is = 0;
X  _ke = 0;
X  _ks = 0;
X  _nd = "\033[C";
X  _se = "\033[m";
X  _sf = 0;
X  _so = "\033[7m";
X  _sr = 0;
X  _te = 0;
X  _ti = 0;
X  _ue = "\033[m";
X  UP = "\033[A";
X  _us = "\033[4m";
X  _ve = 0;
X  _vs = 0;
X  PC = 0;
X  _sc = "\033[3%fm\033[4%bm%c0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15";
X  _ci = 0;
X  _gs = "";
X  _ge = "";
X  _bs = "\033[5m";
X  _be = "\033[m";
X  _hs = "\033[1m";
X  _he = "\033[m";
X#endif						/* if MMAPPED */
X  _gb = "\304\263\305\332\302\277\264\331\301\300\303";
X  rev_color = TRUE;
X#else
X  if (tgetent(termcap, name) != 1)
X    {
X      name = "dumb";
X      stat = FALSE;
X    }
X  tc_ptr = tc_tbl;
X  LINES = tgetnum("li");
X  COLS = tgetnum("co");
X  _al = tgetstr("al", &tc_ptr);
X  BC = tgetstr("bc", &tc_ptr);
X  _cd = tgetstr("cd", &tc_ptr);
X  _ce = tgetstr("ce", &tc_ptr);
X  _cl = tgetstr("cl", &tc_ptr);
X  _cm = tgetstr("cm", &tc_ptr);
X  _dc = tgetstr("dc", &tc_ptr);
X  _dl = tgetstr("dl", &tc_ptr);
X  _do = tgetstr("do", &tc_ptr);
X  _ei = tgetstr("ei", &tc_ptr);
X  _im = tgetstr("im", &tc_ptr);
X  _is = tgetstr("is", &tc_ptr);
X  _ke = tgetstr("ke", &tc_ptr);
X  _ks = tgetstr("ks", &tc_ptr);
X  _nd = tgetstr("nd", &tc_ptr);
X  _se = tgetstr("se", &tc_ptr);
X  _sf = tgetstr("sf", &tc_ptr);
X  _so = tgetstr("so", &tc_ptr);
X  _sr = tgetstr("sr", &tc_ptr);
X  _te = tgetstr("te", &tc_ptr);
X  _ti = tgetstr("ti", &tc_ptr);
X  _ue = tgetstr("ue", &tc_ptr);
X  UP = tgetstr("up", &tc_ptr);
X  _us = tgetstr("us", &tc_ptr);
X  _ve = tgetstr("ve", &tc_ptr);
X  _vs = tgetstr("vs", &tc_ptr);
X  PC = tgetchar("pc");
X  _sc = tgetstr("SC", &tc_ptr);
X  _ci = tgetstr("CI", &tc_ptr);
X  _gs = tgetstr("GS", &tc_ptr);
X  _ge = tgetstr("GE", &tc_ptr);
X  _gb = tgetstr("GB", &tc_ptr);
X  _bs = tgetstr("BS", &tc_ptr);
X  _be = tgetstr("BE", &tc_ptr);
X  _hs = tgetstr("HS", &tc_ptr);
X  _he = tgetstr("HE", &tc_ptr);
X  rev_color = tgetflag("RC");
X#endif
X#ifndef MMAPPED
X  have_color = sc_analyze();
X  have_standout = so_analyze();
X  have_underline = us_analyze();
X  have_blink = bs_analyze();
X  have_bold = hs_analyze();
X#endif
X  have_graphic = gb_analyze();
X#ifdef UNIX
X  add_key_tbl("ku", "\005", K_UP);
X  add_key_tbl("kd", "\030", K_DOWN);
X  add_key_tbl("kl", "\023", K_LEFT);
X  add_key_tbl("kr", "\004", K_RIGHT);
X  add_key_tbl("BT", "\033\t", K_BACKTAB);
X  add_key_tbl("BB", "\021\022", K_BEG_BUF);
X  add_key_tbl("EB", "\021\003", K_END_BUF);
X  add_key_tbl("BS", "\021\005", K_BEG_SCREEN);
X  add_key_tbl("ES", "\021\030", K_END_SCREEN);
X  add_key_tbl("BL", "\021\023", K_BEG_LINE);
X  add_key_tbl("EL", "\021\004", K_END_LINE);
X  add_key_tbl("FS", "\003", K_FWD_SCREEN);
X  add_key_tbl("RS", "\022", K_BWD_SCREEN);
X  add_key_tbl("FW", "\006", K_FWD_WORD);
X  add_key_tbl("RW", "\001", K_BWD_WORD);
X  add_key_tbl("DL", "\033y", K_DEL_LINE);
X  add_key_tbl("DW", "\024", K_DEL_WORD);
X  add_key_tbl("DC", "\007", K_DEL_CHAR);
X  add_key_tbl("KI", "\026", K_INSERT);
X  add_key_tbl("KH", "\033h", K_HELP);
X  add_key_tbl("KC", "\033c", K_CANCEL);
X  add_key_tbl("KQ", "\033q", K_QUIT);
X  add_key_tbl("KB", "\033 ", K_BACKUP);
X  add_key_tbl("KP", "\033p", K_PRINT);
X  add_key_tbl("k0", "\0331", K_F0);
X  add_key_tbl("k1", "\0332", K_F1);
X  add_key_tbl("k2", "\0333", K_F2);
X  add_key_tbl("k3", "\0334", K_F3);
X  add_key_tbl("k4", "\0335", K_F4);
X  add_key_tbl("k5", "\0336", K_F5);
X  add_key_tbl("k6", "\0337", K_F6);
X  add_key_tbl("k7", "\0338", K_F6);
X  add_key_tbl("k8", "\0339", K_F8);
X  add_key_tbl("k9", "\0330", K_F9);
X#endif
X#ifndef MMAPPED
X  if ((COLS == ERROR) || (LINES == ERROR) || streq(tgoto(_cm, 0, 0), "OOPS", TRUE))
X    {
X      _cm = NULL;
X      name = "dumb";
X      stat = FALSE;
X    }
X#endif
X  strcpy(ttytype, name);
X  return(stat);
X}
X
static void pos_cursor(win)
X  REGISTER WINDOW *win;
X{
X
X/*
X   Set physical cursor position and color
X*/
X
X#ifdef MMAPPED
X  pos_mmscr(win->y_cur + win->y_org, win->x_cur + win->x_org);
X#else
X  _setattrib(0, win->color);
X  if ((curscr->y_cur != (win->y_cur + win->y_org)) ||
X      (curscr->x_cur != (win->x_cur + win->x_org)))
X    _goto(win->y_cur + win->y_org, win->x_cur + win->x_org);
X  if (have_color && win->color && (curscr->color != win->color))
X    _setcolor(win->color);
X  _flush_outbuf();
X#endif
X}
X
X#ifndef MMAPPED
X
static int do_cur()
X{
X
X/*
X   Special case for  refresh curscr. See wrefresh below.
X   This will clean up the entire screen no matter how many subwindows or
X   what their order. Used to clean the screen after 'noise' or other
X   unwanted chars appear, much like using CTRL-L in vi.
X*/
X
X  int                 i, temp, cur_x, cur_y, color, save_color;
X  int		      weol_x, eol_x, eol_y, chk_color, save_x, save_y;
X  REGISTER YX_ELEMENT *cur_yx;
X
X/*
X   Initialize the counters and pointers
X*/
X
X  cur_y = 0;
X  cur_x = 0;
X  cur_yx = curscr->buf;
X  eol_y = UNDETERMINED;
X  eol_x = COLS;
X  chk_color = *c_color;
X  save_y = *c_y_cur;
X  save_x = *c_x_cur;
X  save_color = *c_color;
X  for (i = curscr->buf_len - 1; i >= 0; i--)
X    {
X      if (!cur_yx->ch)
X	cur_yx->ch = ' ';
X      cur_yx++;
X    }
X  cur_yx = curscr->buf;
X  for (i = curscr->buf_len - 1; i >= 0; i--)
X    {
X      weol_x = 0;
X
X/*
X   Check and set physical screen position
X*/
X
X      if ((cur_y != *c_y_cur) || (cur_x != *c_x_cur))
X	_goto(cur_y, cur_x);
X
X/*
X   Check and set physical screen colors and attributes
X*/
X
X#ifdef DOS
X      if (cur_yx->attrib != *c_attrib)
X	_setattrib(cur_yx->attrib, cur_yx->color);
X      if (chk_color && cur_yx->color && (cur_yx->color != *c_color))
X	_setcolor(cur_yx->color);
X#else
X      if (chk_color && cur_yx->color && (cur_yx->color != *c_color))
X	_setcolor(cur_yx->color);
X      if (cur_yx->attrib != *c_attrib)
X	_setattrib(cur_yx->attrib, cur_yx->color);
X#endif
X
X/*
X   This next part is a little tricky. Eol_y contains the current line that
X   eol_x is calculated for. If its not the current line, eol_x must be
X   recalculated. Eol_x is the first column on a line that contains blanks of
X   the same color up to the end of the line. This is the column where CE may
X   be used. I calculate eol_x once each line instead of looking forward
X   after each character for all blanks as comparing 2 column numbers is much
X   faster that comparing several columns of data. Also note that the
X   window being refreshed must be full to the end of the physical screen
X   else CE does not apply.
X*/
X      if (cur_y != eol_y)
X        {
X	  REGISTER YX_ELEMENT *syxp;
X
X	  eol_y = cur_y;
X	  eol_x = COLS;
X	  syxp = cur_yx + (eol_x - cur_x - 1);
X	  color = syxp->color;
X	  while ((eol_x > cur_x) && (eol_x > weol_x))
X	    {
X	      if ((syxp->ch == ' ') && (!syxp->attrib) &&
X		  (!have_color || (syxp->color == color)))
X		{
X		  eol_x--;
X		  syxp--;
X		}
X	      else
X		break;
X	    }
X	}
X
X/*
X   Test and output CE, update pointers if CE sent
X*/
X
X      if ((cur_yx->ch == ' ') && (cur_x >= eol_x))
X	{
X	  _puts(_ce);
X	  temp = COLS - cur_x;
X	  i -= temp - 1;
X	  cur_x += temp - 1;
X	  cur_yx += temp - 1;
X	}
X      else
X
X/*
X   Output character unless bottom right corner as this may cause screen
X   to scroll up a line
X*/
X
X	{
X	  if ((cur_y != (LINES - 1)) || (cur_x != (COLS - 1)))
X	    {
X	      *pout++ = cur_yx->ch;			/* save putchar */
X	      if (++outbuf_count >= OUTBUF_SIZE)	/* call overhead */
X		_flush_outbuf();
X	      (*c_x_cur)++;
X	    }
X	}
X
X/*
X   Current character position complete, update pointers to next position
X*/
X
X      cur_yx++;
X      cur_x++;
X
X/*
X   Test and set new line in window
X*/
X
X      if (cur_x >= COLS)
X        {
X          cur_y++;
X          cur_x = 0;
X        }
X    }
X
X/*
X   Window refreshed, reset all flags
X   Set physical cursor position and color
X*/
X
X  if ((*c_y_cur != save_y) || (*c_x_cur != save_x))
X    _goto(save_y, save_x);
X  if (have_color && color && (save_color != color))
X    _setcolor(save_color);
X
X/*
X   Flush and remaining buffer data
X*/
X
X  _flush_outbuf();
X  return(TRUE);
X}
X
X#endif					/* ifndef MMAPPED */
X
int wrefresh(win)			/* refresh window */
X  WINDOW *win;
X{
X
X/*
X   This is the most critical routine in the package in determining speed.
X   Function calls, multiplication, division, array subscripting and
X   multiple indirection have been minimized for maximum speed. Instead,
X   inline code (even if bulkier), addition, subtraction and direct register
X   pointers are used as much as possible.
X
X   It is responsible for taking a logical window and transferring it to the
X   physical device. It only updates portions that are different from a window
X   that reflects the physical screen (curscr). This cuts downs on the number
X   of output characters and thus increases the speed.
X
X   It takes into account if a window is partially hidden by an overlaying
X   window or windows.
X
X   Currently uses only CM and CE, needs to be improved to include DC, DL, IC
X   and so on.
X*/
X
X  int                 i, temp, cur_x, cur_y, win_x, win_y;
X  int		      weol_x, win_y_min, win_y_max, in_range;
X  int		      outside, win_x_max, win_x_org;
X  REGISTER YX_ELEMENT *win_yx;
X  WINDOW 	      *next;
X#ifndef MMAPPED
X  int                 eol_y, eol_x, last_x, chk_color, tst_clrtoeol, color;
X  REGISTER YX_ELEMENT *cur_yx;
X#endif
X
X#ifndef MMAPPED
X  if (win == curscr)
X    return(do_cur());
X#endif
X  if (!(win->flags & NO_CHANGE))
X    {
X
X/*
X   Initialize the counters and pointers
X*/
X      if (win->ch_first > win->ch_last)
X	{
X          pos_cursor(win);
X	  return(FALSE);
X        }
X      win_x_max = win->x_max;
X      win_x_org = win->x_org;
X      win_y = (win->ch_first - win->buf) / win_x_max;
X      win_x = (win->ch_first - win->buf) % win_x_max;
X      cur_y = win_y + win->y_org;
X      cur_x = win_x + win_x_org;
X      win_yx = win->ch_first;
X      win_y_min = LINES;
X      win_y_max = 0;
X#ifndef MMAPPED
X      cur_yx = &curscr->buf[(cur_y * c_x_max) + cur_x];
X      eol_y = UNDETERMINED;
X      eol_x = win_x_max;
X      last_x = c_x_max;
X      chk_color = (win->flags & SET_COLOR);
X      tst_clrtoeol = (win->flags & TSTCLRTOEOL);
X#endif
X
X/*
X   Find the min and max y positions of any windows "on top" of this one
X   This simplifys the checking in the main refresh loop when we are out
X   of the possible "on top" range.
X*/
X
X      for (next = win->next; next; next = next->next)
X	{
X	  if ((temp = next->y_org) < win_y_min)
X	    win_y_min = temp;
X	  if ((temp += (next->y_max - 1)) > win_y_max)
X	    win_y_max = temp;
X	}
X      next = win->next;
X      for (i = win->ch_last - win->ch_first; i >= 0; i--)
X	{
X
X/*
X   See if character in window is different from physical screen
X   If not, skip this character.
X   If memory mapped output all.
X*/
X
X#ifndef MMAPPED
X
X	  if ((win_yx->ch != cur_yx->ch) ||
X	      (win_yx->attrib != cur_yx->attrib) ||
X	      (chk_color &&
X	       ((win_yx->color && (win_yx->color != cur_yx->color)) ||
X	        (!win_yx->color && cur_yx->color && (cur_yx->color != *c_color)))))
X
X#endif
X
X	    {
X	      weol_x = 0;
X
X/*
X   See if character position is visable, ie not covered by overlaying window
X*/
X
X	      outside = TRUE;
X	      if ((cur_y >= win_y_min) && (cur_y <= win_y_max))
X		{
X		  REGISTER WINDOW *wptr;
X
X		  outside = FALSE;
X	          for (wptr = next; wptr; )
X	            {
X	              if ((temp = (wptr->x_org + wptr->x_max)) > weol_x)
X		        weol_x = temp;
X	              if ((cur_y < wptr->y_org) ||
X		          (cur_y >= (wptr->y_org + wptr->y_max)) ||
X		          (cur_x < wptr->x_org) ||
X		          (cur_x >= temp))
X		        wptr = wptr->next;
X	              else
X	                break;
X	            }
X		  in_range = (wptr ? FALSE : TRUE);
X		}
X	      if (outside || in_range)
X		{
X
X#ifdef MMAPPED
X
X/*
X   Output character irregardless of what screen currently has
X   Memory mapping is faster than doing all the checking
X*/
X
X                  put_mmscr(cur_y, cur_x, win_yx);
X                  curscr->color = win_yx->color;
X                  curscr->attrib = win_yx->attrib;
X#else
X
X/*
X   Check and set physical screen position
X*/
X
X	          if ((cur_y != *c_y_cur) || (cur_x != *c_x_cur))
X		    {
X/*
X   Test to see if just need to advance one character ahead, if so output
X   character to advance and save cursor motion calculations and output.
X*/
X
X		      if ((cur_y == *c_y_cur) &&
X			  (cur_x == (last_x + 1)) &&
X	      		  ((win_yx - 1)->attrib == *c_attrib) &&
X	      		  (!chk_color ||
X	       		   ((win_yx - 1)->color && ((win_yx - 1)->color == *c_color))))
X			{
X		          *pout++ = (win_yx - 1)->ch;
X		          if (++outbuf_count >= OUTBUF_SIZE)
X			    _flush_outbuf();
X	                  (*c_x_cur)++;
X			}
X		      else
X	                _goto(cur_y, cur_x);
X		    }
X
X/*
X   Check and set physical screen colors and attributes
X*/
X
X#ifdef DOS
X	          if (win_yx->attrib != *c_attrib)
X		    _setattrib(win_yx->attrib, win_yx->color);
X	          if (chk_color && win_yx->color && (win_yx->color != *c_color))
X		    _setcolor(win_yx->color);
X#else
X	          if (chk_color && win_yx->color && (win_yx->color != *c_color))
X		    _setcolor(win_yx->color);
X	          if (win_yx->attrib != *c_attrib)
X		    _setattrib(win_yx->attrib, win_yx->color);
X#endif
X
X/*
X   This next part is a little tricky. Eol_y contains the current line that
X   eol_x is calculated for. If its not the current line, eol_x must be
X   recalculated. Eol_x is the first column on a line that contains blanks of
X   the same color up to the end of the line. This is the column where CE may
X   be used. I calculate eol_x once each line instead of looking forward
X   after each character for all blanks as comparing 2 column numbers is much
X   faster that comparing several columns of data. Also note that the
X   window being refreshed must be full to the end of the physical screen
X   else CE does not apply.
X*/
X	          if (tst_clrtoeol)
X		    {
X	              if (win_y != eol_y)
X		        {
X  		          REGISTER YX_ELEMENT *syxp;
X
X		          eol_y = win_y;
X		          eol_x = win_x_max;
X		          syxp = win_yx + (eol_x - win_x - 1);
X		          color = syxp->color;
X		          while ((eol_x > win_x) &&
X				 (outside || (eol_x > weol_x)))
X			    {
X		              if ((syxp->ch == ' ') && (!syxp->attrib) &&
X			          (!have_color || (syxp->color == color)))
X			        {
X			          eol_x--;
X			          syxp--;
X			        }
X		              else
X			        break;
X		            }
X		        }
X		    }
X
X/*
X   Test and output CE, update pointers if CE sent
X*/
X
X	          if (tst_clrtoeol && (win_yx->ch == ' ') && (win_x >= eol_x))
X		    {
X		      _puts(_ce);
X		      temp = win_x_max - win_x;
X		      i -= temp - 1;
X		      win_x += temp - 1;
X		      cur_x += temp - 1;
X		      while (temp-- > 0)
X		        *cur_yx++ = *win_yx++;
X		      win_yx--;
X		      cur_yx--;
X		    }
X	          else
X
X/*
X   Output character unless bottom right corner as this may cause screen
X   to scroll up a line
X*/
X
X		    {
X		      if ((cur_y != LAST_y) || (cur_x != LAST_x))
X		        {
X		          *pout++ = win_yx->ch;		     /* save putchar */
X		          if (++outbuf_count >= OUTBUF_SIZE) /* call overhead */
X			    _flush_outbuf();
X	                  *cur_yx = *win_yx;
X	                  (*c_x_cur)++;
X		  	  last_x = *c_x_cur;
X		        }
X		    }
X
X#endif                                   /* ifdef MMAPPED */
X
X		}
X	    }
X
X/*
X   Current character position complete, update pointers to next position
X*/
X
X	  win_yx++;
X	  win_x++;
X#ifndef MMAPPED
X	  cur_yx++;
X#endif
X	  cur_x++;
X
X/*
X   Test and set new line in window
X*/
X
X	  if (win_x >= win_x_max)
X	    {
X	      win_y++;
X	      win_x = 0;
X#ifndef MMAPPED
X	      cur_yx += c_x_max - win_x_max;
X#endif
X	      cur_y++;
X	      cur_x = win_x_org;
X	    }
X	}
X
X/*
X   Window refreshed, reset all flags and flush output
X*/
X
X      win->ch_first = win->buf + win->buf_len - 1;
X      win->ch_last = win->buf;
X      win->flags |= NO_CHANGE;
X      pos_cursor(win);
X    }
X  return(TRUE);
X}
X
X/*
X   Extensions to curses
X*/
X
int keypad()				/* put terminal in keypad mode */
X{
X  if (_ks)
X    {
X      _iputs(_ks);
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
X
int keypadend()				/* end terminal keypad mode */
X{
X  if (_ke)
X    {
X      _iputs(_ke);
X      return(TRUE);
X    }
X  else
X    return(FALSE);
X}
X
int tographic(ch)			/* convert to graphic character */
X  REGISTER int ch;
X{
X  if ((ch >= G_H) && (ch <= G_RT))
X    {
X      if (have_graphic)
X        return(box_tbl[ch - G_H]);
X      else
X	return(fake_tbl[ch - G_H]);
X    }
X  else
X    return(' ');
X}
X
int waddgraphic(win, ch)		/* add graphic character */
X  REGISTER WINDOW *win;
X  REGISTER int    ch;
X{
X  int gr_set;
X
X  if ((ch >= G_H) && (ch <= G_RT))
X    {
X      if (have_graphic)
X	{
X          if ((gr_set = (win->attrib & GRAPHIC)) == 0)
X	    win->attrib |= GRAPHIC;
X          waddch(win, box_tbl[ch - G_H]);
X          if (!gr_set)
X            win->attrib &= ~GRAPHIC;
X	}
X      else
X	{
X          if ((gr_set = (win->attrib & GRAPHIC)) != 0)
X	    win->attrib &= ~GRAPHIC;
X	  waddch(win, fake_tbl[ch - G_H]);
X	  if (gr_set)
X	    win->attrib |= GRAPHIC;
X	}
X    }
X  else
X    waddch(win, ' ');
X  return(TRUE);
X}
X
int fg_bits(color)
X  REGISTER int color;
X{
X  if ((color == UNDETERMINED) || (color < BLACK) || (color > COLOR_15))
X    return(UNDETERMINED);
X  else
X    return(bits_tbl[color].fg);
X}
X
int bg_bits(color)
X  REGISTER int color;
X{
X  if ((color == UNDETERMINED) || (color < BLACK) || (color > COLOR_15))
X    return(UNDETERMINED);
X  else
X    return(bits_tbl[color].bg);
X}
X
int wsetcolor(win, foreground, background)	/* set color on a window */
X  REGISTER WINDOW *win; 
X  int             foreground;
X  int             background;
X{
X  int temp;
X
X  if (!have_color || (foreground == background))
X    return(FALSE);
X  if ((temp = fg_bits(foreground)) != UNDETERMINED)
X    win->color = (win->color & ~F_MASK) | temp;
X  if ((temp = bg_bits(background)) != UNDETERMINED)
X    win->color = (win->color & ~B_MASK) | temp;
X  win->flags |= SET_COLOR;
X  return(TRUE);
X}
X
int get_color(color)
X  REGISTER char *color;
X{
X  REGISTER COLOR_ENTRY *tbl_ptr;
X
X  if (color)
X    {
X      tbl_ptr = color_table;
X      while (tbl_ptr->name)
X	{
X          if (streq(color, tbl_ptr->name, TRUE))
X	    return(tbl_ptr->value);
X	  else
X	    tbl_ptr++;
X	}
X    }
X  return(UNDETERMINED);
X}
X
X#ifdef UNIX
int tgetchar(id)			/* termcap get char spec */
X  char *id;
X{
X  char *temp;
X
X  if (temp = tgetstr(id, &tc_ptr))
X    return(*temp);
X  else
X    return('\0');
X}
X
X#ifndef MMAPPED
int print_screen(parm_printer, parm_file)
X  char *parm_printer;
X  char *parm_file;
X{
X  int        i, j, k;
X  int        p_ch, f_ch, effect, have_effect, f_append;
X  int        p_uniplex, env_printer, f_uniplex;
X  WINDOW     *win;
X  YX_ELEMENT *ptr;
X  FILE       *p_file;
X  FILE       *f_file;
X  char       sh_cmd[100], file[50], printer[50], ufile[50];
X  char       *p_buf, *p_ptr, *f_buf, *f_ptr, *e_buf, *e_ptr, *env_ptr;
X
X  win = curscr;
X  if (!(p_buf = malloc(win->x_max + 5)) ||
X      !(f_buf = malloc(win->x_max + 5)) ||
X      !(e_buf = malloc(win->x_max + 5)))
X    return(FALSE);
X  printer[0] = '\0';
X  env_printer = FALSE;
X  p_uniplex = FALSE;
X  f_uniplex = FALSE;
X  f_append = FALSE;
X  if (parm_printer)
X    strncpy(printer, parm_printer, sizeof(printer) - 1);
X  else
X    {
X      if (env_ptr = getenv("SCR_PRINTER"))
X	{
X	  env_printer = TRUE;
X	  strncpy(printer, env_ptr, sizeof(printer) - 1);
X	}
X    }
X  printer[sizeof(printer) - 1] = '\0';
X  if (printer[0] || env_printer)
X    {
X      if (printer[0])
X	{
X	  if (printer[0] == '#')
X	    {
X	      p_uniplex = TRUE;
X	      strcpy(printer, &printer[1]);
X	      sprintf(ufile, "/tmp/scr.%d", getuid());
X	      strcpy(sh_cmd, "cat > ");
X	      strcat(sh_cmd, ufile);
X	    }
X	  else
X	    {
X	      strcpy(sh_cmd, "lp -s -d");
X	      strcat(sh_cmd, printer);
X	    }
X	}
X      else
X	strcpy(sh_cmd, "lp -s");
X      p_file = popen(sh_cmd, "w");
X    }
X  else
X    p_file = NULL;
X  file[0] = '\0';
X  if (parm_file)
X    strncpy(file, parm_file, sizeof(file) - 1);
X  else
X    {
X      if (env_ptr = getenv("SCR_FILE"))
X	strncpy(file, env_ptr, sizeof(file) - 1);
X    }
X  file[sizeof(file) - 1] = '\0';
X  if (file[0])
X    {
X      f_append = FALSE;
X      if (file[0] == '+')
X	{
X	  strcpy(file, &file[1]);
X	  f_append = TRUE;
X	}
X      if (file[0] == '#')
X	{
X	  strcpy(file, &file[1]);
X	  f_uniplex = TRUE;
X          if (file[0] == '+')
X	    {
X	      strcpy(file, &file[1]);
X	      f_append = TRUE;
X	    }
X	}
X      if (f_append)
X	f_file = fopen(file, "a");
X      else
X        f_file = fopen(file, "w");
X    }
X  else
X    f_file = NULL;
X  if (!p_file && !f_file)
X    return(FALSE);
X  j = 0;
X  have_effect = FALSE;
X  p_ptr = p_buf;
X  f_ptr = f_buf;
X  e_ptr = e_buf;
X  for (i = win->buf_len, ptr = win->buf; i; i--, ptr++)
X    {
X      p_ch = ptr->ch;
X      f_ch = ptr->ch;
X      if (ptr->attrib && (p_uniplex || f_uniplex))
X	have_effect = TRUE;
X      if (ptr->attrib & GRAPHIC)
X	{
X	  for (k = 0; k < BOX_SIZE; k++)
X	    {
X	      if (box_tbl[k] == ptr->ch)
X		{
X		  if (p_uniplex)
X		    p_ch = 'A' + k;
X		  else
X		    p_ch = fake_tbl[k];
X		  if (f_uniplex)
X		    f_ch = 'A' + k;
X		  else
X		    f_ch = fake_tbl[k];
X		  break;
X		}
X	    }
X	  effect = '[';
X	}
X      else if (ptr->attrib & BOLD)
X	effect = 'A';
X      else if (ptr->attrib & UNDERLINE)
X	effect = 'C';
X      else if (ptr->attrib & STANDOUT)
X	{
X	  if (p_ch == ' ')
X	    p_ch = '*';
X	  if (f_ch == ' ')
X	    f_ch = '*';
X	  effect = 'Z';
X	}
X      else
X	effect = ' ';
X      j++;
X      *p_ptr++ = p_ch;
X      *f_ptr++ = f_ch;
X      *e_ptr++ = effect;
X      if (j == win->x_max)
X	{
X	  while (*(p_ptr - 1) == ' ')
X	    {
X	      if (p_uniplex)
X		{
X	          if (*(e_ptr - 1) == ' ')
X		    e_ptr--;
X		  else
X		    break;
X		}
X	      p_ptr--;
X	    }
X	  while (*(f_ptr - 1) == ' ') 
X	    {
X	      if (f_uniplex && !p_uniplex)
X		{
X	          if (*(e_ptr - 1) == ' ')
X		    e_ptr--;
X		  else
X		    break;
X		}
X	      f_ptr--;
X	    }
X	  if (p_uniplex && have_effect)
X	    {
X	      *p_ptr++ = '@';
X	      *p_ptr++ = '@';
X	    }
X	  if (f_uniplex && have_effect)
X	    {
X	      *f_ptr++ = '@';
X	      *f_ptr++ = '@';
X	    }
X	  *p_ptr++ = '\n';
X	  *p_ptr = '\0';
X	  *f_ptr++ = '\n';
X	  *f_ptr = '\0';
X	  *e_ptr++ = '\n';
X	  *e_ptr = '\0';
X          if (p_file)
X	    {
X	      fputs(p_buf, p_file);
X	      if (p_uniplex && have_effect)
X		fputs(e_buf, p_file);
X	    }
X          if (f_file)
X	    {
X	      fputs(f_buf, f_file);
X	      if (f_uniplex && have_effect)
X		fputs(e_buf, f_file);
X	    }
X	  j = 0;
X	  have_effect = FALSE;
X	  p_ptr = p_buf;
X	  f_ptr = f_buf;
X	  e_ptr = e_buf;
X	}
X    }
X  free(p_buf);
X  free(f_buf);
X  free(e_buf);
X  if (p_file)
X    pclose(p_file);
X  if (f_file)
X    fclose(f_file);
X  if (p_uniplex)
X    {
X      strcpy(sh_cmd, "/bin/sh -c '/usr/UII/bin/uprint -p ");
X      strcat(sh_cmd, printer);
X      strcat(sh_cmd, " ");
X      strcat(sh_cmd, ufile);
X      strcat(sh_cmd, " 2>/dev/null | lp -s 2>/dev/null'");
X      return(do_command(sh_cmd, FALSE, (int*)0));
X    }
X  return(TRUE);
X}
X#endif
X#endif
X
END_OF_FILE
if test 37438 -ne `wc -c <'lib/scrout1.c'`; then
    echo shar: \"'lib/scrout1.c'\" unpacked with wrong size!
fi
# end of 'lib/scrout1.c'
fi
echo shar: End of archive 8 \(of 9\).
cp /dev/null ark8isdone
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