DataMuseum.dk

Presents historical artifacts from the history of:

DKUUG/EUUG Conference tapes

This is an automatic "excavation" of a thematic subset of
artifacts from Datamuseum.dk's BitArchive.

See our Wiki for more about DKUUG/EUUG Conference tapes

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - metrics - download
Index: T p

⟦4295eaa7f⟧ TextFile

    Length: 7540 (0x1d74)
    Types: TextFile
    Names: »pager.c«

Derivation

└─⟦9ae75bfbd⟧ Bits:30007242 EUUGD3: Starter Kit
    └─⟦e7f64e0c0⟧ »EurOpenD3/mail/vmh.tar.Z« 
        └─⟦dcb95597f⟧ 
            └─⟦this⟧ »pager.c« 

TextFile

#ifndef lint
static char rcsid[] =
	"$Header: pager.c,v 1.10 88/01/13 19:14:52 deboor Exp $";

static char notice[] =
	"This program is in the public domain and is available for unlimited \
distribution as long as this notice is enclosed.";
#endif lint

/*
 * support routines for paging things in the bottom display window.
 *
 * $Source: /c/support/deboor/usr/src/old/vmh/RCS/pager.c,v $
 * $Revision: 1.10 $
 * $Author: deboor $
 *
 * FUNCTIONS:
 *	end_pager	finish out pager session
 *	init_pager	initialize pager variables
 *	newline		do a newline in a window. returns ERR if at end of page
 *	nextpage	prompt for another page
 *	putstr		print a string worrying about word wrap.
 */

#include "vmh.h"
#include <sys/file.h>


typedef	struct	_blist {	/* structure to implement 'b' in nextpage() */
	off_t		bl_off;	/* offset where last page was */
	struct	_blist	*bl_next, /* pointer to structure for previous page */
			*bl_prev;
} BLIST;

static	int	lines;		/* the number of lines printed */
static	int	fLines;		/* the number of lines in the file so far */
static	int	lastpage;	/* the last page number (set in nextpage()) */

static	BLIST	bL0 = { 0, 0, 0 };

static	struct {
	BLIST	*head,
		*tail,
		*cur;
	int	pageno;
} backList;

static	FILE	*curFile;
static	WINDOW	*curWin;

/*
 * init_pager(fl, win) FILE *fl; WINDOW *win;
 *	Initializes pager-related variables. Must be called before using pager
 *	routines.
 */
init_pager(fl, win)
	FILE	*fl;
	WINDOW	*win;
{
	curWin = win;
	curFile = fl;

	lines = win->_maxy - 1;
	fLines = 0;

	backList.head = backList.tail = backList.cur = &bL0;
	bL0.bl_next = (BLIST *) 0;
	lastpage = backList.pageno = 0;
}

/*
 * end_pager()
 *	frees up any backList remaining. Should be called when done using pager
 *	routines.
 */
end_pager()
{
	register BLIST	*bL;

	for (bL = backList.head->bl_next; bL; bL = bL->bl_next)
		Free ((char *) bL);

	curFile = (FILE *) 0;
	curWin = (WINDOW *) 0;
}

/*
** newline ()
**	simulates a '\n' being printed to window curWin.
**	if we're on the bottom line already, then calls
**	scrollup() to scroll the window, else it just
**	increments the y coordinate. In either case
**	curx is set back to 0. If the newly-incremented
**	global variable 'lines' is equal to maxy, ERR
**	is returned, else OK is returned.
*/
newline (godown)
    int		godown;
{
	BLIST	*bL;

	wclrtoeol(curWin);
	curWin->_curx = 0;

	fLines++;

	if ((fLines % curWin->_maxy == 0) && curFile) {
		backList.cur = backList.cur->bl_next;
		if (! backList.cur) {
			bL = AllocST(BLIST);
			bL->bl_off = ftell (curFile);
			bL->bl_prev = backList.tail;
			backList.tail->bl_next = bL;
			backList.cur = backList.tail = bL;
			bL->bl_next = (BLIST *) 0;
		}
		backList.pageno++;
	}

	if (! lines--) {
		lines = (curWin->_maxy - 1) - LEFTOVER;
		return ERR;
	} else {
	    if (godown) {
		if (curWin->_cury >= curWin->_maxy - 1)
			scrollup(curWin);
		else
			curWin->_cury++;
		wclrtoeol(curWin);
	    }
	    return OK;
	}
}


/*
 * nextpage ()
 *	Prompt for next page?  Returns 1 if done, 0 to continue...
 *	win is the window in which the file was being displayed.
 *	if curFile is set, backpaging is enabled and all that goes with it.
 *	the --More-- prompt is always displayed in the cmdWin. 
 */

nextpage()
{
	register int	c;		/* input character */
			
	struct	stat	sb;
	int		pct;		/* the percent seen and a general
					 * flag telling if curFile is valid */

	if (!curFile) {
		pct = -1;
	} else if (fstat (fileno(curFile), &sb) < 0) {
		pct = -1;
	} else {
		/*
		 * if ftell returns an error, pct will be
		 * negative so it won't be used
		 */
		pct = ftell (curFile) * 100 / sb.st_size;
	}
		
	wrefresh(curWin);
waitforit:
	for ( ; ; )             /* Loop till non-^L key pushed */
	{
		wmove(cmdWin, 0, 0);
		wstandout(cmdWin);
		waddstr (cmdWin, "--More--");
		if (pct >= 0)
			wprintw (cmdWin,"(%d%%)", pct);
		if (! terse)
			waddstr (cmdWin, "[Press space to continue, 'q' to quit]");
		wclrtoeol (cmdWin);
		wstandend(cmdWin);
		wrefresh(cmdWin);

		_puts (SE);			/* turn the damn thing OFF */
		curscr->_flags &= ~_STANDOUT;

		c = mygetch(cmdWin) & 0177;
		werase(cmdWin);
		wrefresh(cmdWin);            /* This is pretty weird logic */
		if (c == '\014' || c == '\022')	/*^L or ^R redraws the screen */
			cmdRedraw();  /* I think it must be time to go */
		else
			break;                  /* home and get some sleep */
		/* beware of standout curses bug! */
	}

	if (c == 'b') {
		if (pct < 0) {
			beep();
			goto waitforit;
		}
		backList.cur = (backList.cur->bl_prev) ?
				backList.cur->bl_prev :
				backList.cur;
		backList.pageno--;
		if (lastpage == backList.pageno) {
			backList.cur = (backList.cur->bl_prev) ?
					backList.cur->bl_prev :
					backList.cur;
			backList.pageno--;
		}
		Fseek (curFile, backList.cur->bl_off, L_SET);
		fLines -= curWin->_maxy-1;
		lines = curWin->_maxy-1;
		lastpage = backList.pageno;

		wmove (curWin, 0, 0);
		return (0);
	}
	lastpage = backList.pageno; /* ???? */

	if (c == '\n' || c == '\r') {
		scrollup (curWin);
		wmove (curWin, curWin->_maxy - 1, 0);
		wclrtobot(curWin);
		lines = 0;
		return (0);
	}
	if( c == ' ' ) {

		if (do_page) {
			wmove(curWin, 0, 0);
			lines += LEFTOVER;
		} else {
			scrollup (curWin);
		}
		return( 0 );
	}
	else if( c >= '0' && c <= '9') {  /* scroll n lines */
		lines = c - '0';
		scrollup (curWin);
		return( 0 );
	}
	else if (c != 'q') {
		/*
		 * put character back in buffer as first chr$ of command
		 */
		ungetc (c, stdin);
	}

	return( 1 );
}

/*
** putstr (str) register char *str;
**	prints the specified string  str  to the specified window  win 
**	performing margin-wraping and changing any non-printable characters
**	besides ' ', '\t' '\n' and '\f' into printable ones using unctrl().
**	If the printing of a character returns ERR, nextpage() is called to
**	prompt for input. If this returns 1, output is stopped with a 1 return
**	code, else the printing of  str  continues.
**	WrapMargin is the offset from the right side of the window at which to
**	start looking for spaces which can be changed to '\n's.
*/
putstr (str)
	Reg4	char	*str;
{
	Reg2	int	i;
	Reg3	int	j;
	Reg1	char	*cp;
	Reg5	int	gotSpace;

	/*
	 * first we try to stick in extra newlines to do wordwrap nicely.
	 */
	for (gotSpace = 0, cp = str, i = curWin->_curx; *cp; cp++) {
		switch (*cp) {
		case '\t':
			i = (i + 8) & ~7;
			gotSpace = 1;
			break;
		case ' ':
			gotSpace = 1;
			i++;
			break;
		case '\n':
			i = 0;
			break;
		default:
			i++;
		}
		if (i >= curWin->_maxx) {
			if (gotSpace) {
				while (!isspace (*cp))
					cp--;
				*cp = '\n';
				gotSpace = i = 0;
			} else {
				/*
				 * there's nothing to do if there's no space
				 * in the preceeding line. We just break it
				 * unnaturally and hope for the best
				 */
				i = 0;
				gotSpace = 0;
			}
		}
	}

	for (i = curWin->_curx; *str; str++) {
		if (*str == '\n') {
			i = 0;
			if (newline(1) == ERR && nextpage())
				return 1;
		} else if ( ! isspace (*str) && ! isprint (*str)) {
			wstandout (curWin);
			waddch (curWin, (*str & 037) + '@');
			wstandend (curWin);
			i++;
		} else {
			waddch (curWin, *str);
			i++;
		}
		/*
		 * if we've hit the end of the line without a newline,
		 * we have to do one anyway to keep the number of lines
		 * we've printed up to date. We do the same sort of processing
		 * as for an existing newline, including calling newline() and
		 * nextpage().
		 */
		if (i >= curWin->_maxx) {
			i = 0;
			if (newline(0) == ERR && nextpage()) {
				return (1);
			}
		} 
	}
	return 0;
}