|
|
DataMuseum.dkPresents historical artifacts from the history of: Commodore CBM-900 |
This is an automatic "excavation" of a thematic subset of
See our Wiki for more about Commodore CBM-900 Excavated with: AutoArchaeologist - Free & Open Source Software. |
top - metrics - download
Length: 5220 (0x1464)
Types: TextFile
Notes: UNIX file
Names: »io.c«
└─⟦f27320a65⟧ Bits:30001972 Commodore 900 hard disk image with partial source code
└─⟦f4b8d8c84⟧ UNIX Filesystem
└─⟦this⟧ »unimenu/src/menu/io.c«
/*
#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;
}