|
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; }