/*Last Modified: 9-MAR-1992 14:51:25.06, By: MARK */ /* manager.c * * Part of the Internet Gopher program, copyright (C) 1991 * University of Minnesota Microcomputer Workstation and Networks Center */ #include "gopher.h" #define MENULINE(x) (x)+3 /* If any gophers to display (screen can be blank), count the number of pages. If there is a remainder greater than zero, add one page */ #define PAGECALC(x,y) (y) ? (x/y) + ((x%y)>0) : 1 #define MIN(x,y) ((x) <= (y) ? (x) : (y)) /* ** Draw the title on the top */ Draw_Banner() { int ret_status, row, col; int rend = SMG$M_REVERSE; int rend_comp = 0; $DESCRIPTOR( d_vers, VERSIONline ); d_vers.dsc$w_length = strlen( VERSIONline ); row = 1; col = ( 80 - strlen( VERSIONline ) ) / 2; ret_status = smg$put_chars( &DisplayId, &d_vers, &row, &col, &rend_comp, &rend ); } /* ** Draw the status line */ Draw_Status(textline) char *textline; { int ret_status, stat_line, stat_col; $DESCRIPTOR( d_qhelp, "Press '?' for Help" ); $DESCRIPTOR( d_text, textline ); d_text.dsc$w_length = strlen( textline ); stat_line = 24; stat_col = 1; ret_status = smg$erase_line( &DisplayId, &stat_line, &stat_col ); ret_status = smg$put_chars(&DisplayId,&d_qhelp,&stat_line,&stat_col); stat_col = 80 - strlen(textline); ret_status = smg$put_chars(&DisplayId,&d_text,&stat_line,&stat_col); } /* ** Man is this ugly. */ Display_Dir_Page(gophers, iNewLine, nNewPage, nMaxPages, iPageLen, iLastPageLen) GopherStruct *gophers; int nNewPage, nMaxPages, iPageLen, iLastPageLen; { int i, iLoop, iOffset, ret_status, mline, mcol, d_str_len, offlen; int outlen; char num_string[10], out_string[255]; $DESCRIPTOR( d_str, num_string ); $DESCRIPTOR( d_space, " " ); $DESCRIPTOR( d_outstring, out_string ); $DESCRIPTOR( d_slash, "/" ); $DESCRIPTOR( d_cso, " " ); $DESCRIPTOR( d_tel, " " ); $DESCRIPTOR( d_question, "> COLS - 16) { c = strchr(d, '/'); if (c == NULL) { c = d; break; /*** No more slashes ***/ } d = c+1; } if (strlen(c) > COLS-16) c[COLS-17] = '\0'; /*** Gack, strip off extra cruft **/ strncpy( out_string, "\0", 255 ); if (c != d) { sprintf( out_string, " ..%s", c+1 ); ret_status = smg$put_chars( &DisplayId, &d_outstring ); } else { sprintf( out_string, " %s", c ); ret_status = smg$put_chars( &DisplayId, &d_outstring ); } } switch(gophers[iOffset].sFileType) { case A_DIRECTORY: ret_status = smg$put_chars( &DisplayId, &d_slash ); break; case A_CSO: ret_status = smg$put_chars( &DisplayId, &d_cso ); break; case A_TELNET: ret_status = smg$put_chars( &DisplayId, &d_tel ); break; case A_INDEX: ret_status = smg$put_chars( &DisplayId, &d_question ); break; case A_SOUND: ret_status = smg$put_chars( &DisplayId, &d_speaker ); /** It's supposed to look like a speaker! **/ break; case A_FILE: ret_status = smg$put_chars( &DisplayId, &d_period ); break; case A_EVENT: ret_status = smg$put_chars( &DisplayId, &d_pound ); break; } } } /* scline - Screen line relocator. * Returns the line resulting from choice */ int scline(iMaxGophers, iOldGopher, iNewGopher, gophers, MenuTitle) int iMaxGophers; /* Total number of gophers on all pages */ int iOldGopher; /* Which gopher previously displayed */ int iNewGopher; /* New gopher to be displayed */ GopherStruct *gophers; char *MenuTitle; { int iPageLen, iLastPageLen; /* Length of normal, final pages */ int nMaxPages, nNewPage, nOldPage; /* Natural numbers */ int iOldLine, iNewLine; /* Screen locations */ int ret_status, row, col, rend; char sPagenum[40]; $DESCRIPTOR( d_3spaces, " " ); $DESCRIPTOR( d_arrow, "-->" ); $DESCRIPTOR( d_menutitle, MenuTitle ); d_menutitle.dsc$w_length = strlen( MenuTitle ); if ((iNewGopher < 0) || (iNewGopher > iMaxGophers)) return(iOldGopher); iPageLen = LINES-6; /* Number of menu lines possible per page */ nMaxPages = PAGECALC(iMaxGophers, iPageLen); /* Total number of pages */ nOldPage = PAGECALC(iOldGopher, iPageLen); nNewPage = PAGECALC(iNewGopher, iPageLen); if ((nNewPage < 1) || (nNewPage > nMaxPages)) /* It won't work , make*/ return(iOldGopher); /* no changes */ iLastPageLen = iMaxGophers % iPageLen; /* Lines on last page */ iOldLine = iOldGopher - ((nOldPage-1)*iPageLen);/* Old Screen location */ iNewLine = iNewGopher - ((nNewPage-1)*iPageLen);/* New Screen location */ if ((iNewLine < 0) || (iNewLine > iPageLen)) return(iOldGopher); if (nOldPage != nNewPage) { Display_Dir_Page(gophers, iNewLine, nNewPage, nMaxPages, iPageLen, iLastPageLen); row = 2; col = (80 - strlen( MenuTitle )) / 2; rend = SMG$M_REVERSE; ret_status = smg$put_chars(&DisplayId,&d_menutitle,&row,&col); } sprintf(sPagenum, " Page: %d/%d", nNewPage, nMaxPages); Draw_Status(sPagenum); row = MENULINE( iOldLine ); col = 4; ret_status = smg$put_chars( &DisplayId, &d_3spaces, &row, &col ); row = MENULINE( iNewLine ); col = 4; ret_status = smg$put_chars( &DisplayId, &d_arrow, &row, &col ); col = 7; ret_status = smg$set_physical_cursor( &PasteId, &row, &col ); return(iNewGopher); } /* ** This routine draws a numbered menu ** from an array of GopherStructs. ** ** It returns the number that the user selected, or it returns ** zero if the user decided to cancel. ** */ int GetMenu(numitems, items, MenuTitle, typedchar, incomingLine) int numitems; GopherStruct *items; char *MenuTitle; int *typedchar; int incomingLine; { short int ch; /* Input character */ int iItem; /* Display line */ int ret_status, row, col, re