DataMuseum.dk

Presents historical artifacts from the history of:

Commodore CBM-900

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

See our Wiki for more about Commodore CBM-900

Excavated with: AutoArchaeologist - Free & Open Source Software.


top - download

⟦ed5491560⟧ TextFile

    Length: 5220 (0x1464)
    Types: TextFile
    Notes: UNIX file
    Names: »io.c«

Derivation

└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
    └─⟦f4b8d8c84⟧ UNIX V7 Filesystem
        └─ ⟦this⟧ »unimenu/src/menu/io.c« 

TextFile

/*
#define DEBUG
*/

/*
 *			Copyright (c) 1984
 *
 *		LANTECH Systems, Incoroporated
 *
 *			All rights reserved
 */

/*
 * Function:	screen(menu)
 *
 * Purpose:	Print out a pretty screen, based upon info in *menu.
 *
 * Passed:	A pointer to a menu_f struct.
 *
 * Returns:	nothing
 *
 * Called by:	main
 *
 * Calls:	printf
 *		cls
 *
 * Notes:	main knows that this code leaves the cursor near the
 *		bottom left-hand corner of the screen
 *
 * History:	Original Coding June 1984 by Robert Adams
 *		Added cat(), implemented columns, August 84
 *		
 *		Modified by Charles Cavanaugh Aug-84 to print menu ascending 
 *	 	by columns instead of by rows.
 *
 *		Changed screen output mechanism so menu can use sliding
 *		reverse video prompt. screen now just formats a buffer
 *		and fills in some information for the select function.
 *		It uses the uNETix window system call to do screen output.
 *		drm - Mar 85
 */

#include "defs.h"				/* get definitions*/

#define	RV	0x70			/* reverse video */

extern	int	*Scrnbuf;
extern	char	Curdir[];
int	Top = 0;
int	DispCur = 0;
int	Lhcol = -1;

screen (menu)
struct menu_f  *menu;
{
struct choice_f *chp;
int     j;
char *mentry;
char *getentry();
int  cur_col, cur_row, rows, col, entry_count;
int maxlen, len, border;
int	elen;

#ifdef DEBUG
printf("in screen: buffer is %D\n", (long) Scrnbuf);
#endif
	if ( !(col = menu->m_col) )	/* number of columns */
		col = 1;
	else if ( col > SCR_WID/2 )	/* in case some jerk does something */
	{
		col = SCR_WID/2;	/* like makes col = 80 */
		menu->m_col = col;	 /* have to have 4 chars for each col */
	}

	/* 
	 * count menu entries 
	 */ 
	maxlen = 4;
	for (chp = menu -> m_list, entry_count = 0; chp != NULL;
		chp = chp -> c_next, entry_count++) 
	{
			/* need to find the longest entry */
			len = strlen(chp->c_Text);
			if ( (len + 4) > maxlen )
				maxlen = len + 4;	/* +4 gives us space 
							between the entries */
	}

	rows = entry_count/col;			/* number of rows */
	if ( entry_count % col )		/* odd num. add 1 */
		rows++;

	if ( (rows + Top + 4) > SCR_LEN )	/* is the menu is too long */
	{
		Top = SCR_LEN - (rows + 4);
		if ( Top < 0 )
		{
			printf("Too many rows in Menu\n");
			_exit(1);		/* too bad */
		}
	}

	elen = 0;
	for ( chp = menu->m_list; chp != NULL; chp = chp->c_next)
	{
		if ( chp->c_Expl )
			len = strlen(chp->c_Expl);
		if ( len > elen )
			elen = len;
	}

	len = maxlen * col;			/* how wide display area is */
	if ( len < elen )
		len = elen;
	if ( len > SCR_WID )			/* too wide to go on screen */
	{
		maxlen = SCR_WID / col;		/* max length of an entry */
		if ( maxlen < 4 )
		{
			printf("Too many columns or columns too wide.\n");
			_exit(1);
		}
		len = SCR_WID;
		border = 0;
	}
	else if ( Lhcol == -1 )			/* none specified */
	{
		border = (SCR_WID - len) / 2;
	}
	else					/* use theirs */
	{
		if ( Lhcol + len > SCR_WID )
		{
			len = SCR_WID;
			border = 0;
		}
		else
			border = Lhcol;
	}
#ifdef DEBUG
printf("screen: filling screen buffer\n");
printf("rows = %d, cols = %d, border = %d, Top = %d\n", rows, col, border, Top);
#endif
	fillw(Scrnbuf, SCR_LEN * SCR_WID, V_SPACE); /* "clear" the screen */

#ifdef DEBUG
printf("putting attributes \n");
#endif
	bputattr(Scrnbuf, SCR_SIZ.word, Top, border, rows + 4, len, RV);

	if ( menu->m_Title )				/* do the title */
	{
		cur_col = strlen(menu->m_Title);
		if ( len >= cur_col )			/* enough room for it */
		{
			cur_col = border + ((len - cur_col) / 2);
			bputstr(Scrnbuf, SCR_SIZ.word, Top, cur_col, menu->m_Title);
		}
|	}
	else
		cur_col = len;

#ifdef PWDS
	if ( DispCur )			/* stick the current directory in */
	{
		pwd(Curdir);
		if ( strlen(Curdir) < cur_col - 3 ) 	/* cur_col set above */
			bputstr(Scrnbuf, SCR_SIZ.word, Top, border + 2, Curdir);
	}
#endif

	/*
	 * set up the data for select()
	 */
	menu->m_fsiz = maxlen;
	menu->m_ulhr = Top + 1;
	menu->m_ulhc = border;
	menu->m_row = rows + 1;
	menu->m_entries = entry_count;

	cur_row = Top + 2;
	cur_col = border + 2;
	chp = menu->m_list;

	for (j = 1; j <= entry_count; j++)		/* do all entries */
	{

		if ( !chp )				/* sanity check */
			break;
		mentry = chp->c_Text;
		chp = chp->c_next;

		if ( strlen(mentry) > maxlen - 2 )	/* 2 spaces between */
			mentry[maxlen - 2] = '\0';

		bputstr(Scrnbuf, SCR_SIZ.word, cur_row, cur_col, mentry);

		if ( (j % col) == 0 )
		{
			cur_row++;
			cur_col = border + 2;
		}
		else
			cur_col += maxlen;
	}

}

/*
 * return the c_Text string for the ith entry for the menu
 */

char *getentry(m,i)
struct choice_f *m;
int i;
{
int j = 1;

	while( j < i && m->c_next != NULL) 
	{
		m = m->c_next; j++;
	}
	return(m -> c_Text);
}

/*
 * Function:	cat(file)
 *
 * Effect:	display the file as if cat had been called.
 *
 * Notes:	This is here so it and screen may share an output
 *		mechanism.
 *
 * History:	Original Code Robert Adams, August 84
 */
cat (file)
char *file;
{
int	fd;
int	i;
char buf[128];

	if( (fd = open(file, 0)) < 0 )
	{
		printf("Cannot Open: %s\n", file);
		return;
	}

	while ( (i = read(fd, buf, 128)) > 0 )
		write(1, buf, i);

	close(fd);
}

fillw(ip, len, fil)
int	*ip;
int	len;
int	fil;
{
#ifdef DEBUG
printf("fill: %D %d %d\n", (long) ip, len, fil);
#endif
	while( len-- )
		*ip++ = fil;
}