home *** CD-ROM | disk | FTP | other *** search
/ C/C++ Interactive Guide / c-cplusplus-interactive-guide.iso / c_ref / csource4 / 235_01 / ovhelp.c < prev    next >
Encoding:
C/C++ Source or Header  |  1987-06-18  |  10.3 KB  |  331 lines

  1. /*  009  14-Feb-86  ovhelp.c
  2.  
  3.         Copyright (c) 1986 by Blue Sky Software.  All rights reserved.
  4. */
  5.  
  6. #include <stdio.h>
  7. #include <setjmp.h>
  8. #include "ov.h"
  9.  
  10. #define H_bar (0xcd)
  11.  
  12. #define HLINESIZ 80    /* max size of a help line - coordinate with cvthlp.c */
  13. #define NSELS 20       /* max # menu ents/topic   - coordinate with cvthlp.c */
  14. #define STKSIZ 10      /* depth of prev screen stack */
  15.  
  16. static FILE *hlp;
  17. static char *helpfile = "ov.hlp";
  18. static char *nohelp = " - no help available!";
  19.  
  20. int help_exit(), help_back(), help_sel();
  21.  
  22. extern MENU *top_menu, top_help_menu[];
  23.  
  24. static MENU pmenu =
  25.    { "Prev", "Return to the previous help screen", help_back, top_help_menu };
  26. static MENU qmenu = { "Quit", "Quit help", help_exit, top_help_menu };
  27.  
  28. static int stkidx;
  29. static char *buffer;
  30. static MENU top_help_menu[NSELS];
  31. static unsigned char save_restricted;
  32. static long lastsel, offsets[NSELS], offstack[STKSIZ];
  33.  
  34. extern char *cantopen;
  35. extern MENU_STATE curmenu;
  36. extern jmp_buf back_to_main;
  37. extern unsigned char restricted;
  38. extern unsigned char help_display;
  39.  
  40. FILE *pathopen();
  41. char *strchr(), *getenv(), *hgets();
  42.  
  43.  
  44. /******************************************************************************
  45.                                    H E L P
  46.  *****************************************************************************/
  47.  
  48. help() {               /* provide help on using OverView */
  49.  
  50.    register int ch;
  51.  
  52.    if (help_display)                   /* don't work recurrsively */
  53.       return;
  54.  
  55.    help_init();                        /* locate/open help file */
  56.  
  57.    save_restricted = restricted;       /* save current restricted flag and */
  58.    menu_save();                        /*   menu state before changing them */
  59.  
  60.    restricted = TRUE;                  /* disable cmds we don't want */
  61.    help_display = TRUE;                /* yes, help is active */
  62.    top_menu = top_help_menu;           /* use (tbd) help menu */
  63.  
  64.    savescreen();                       /* save the current display screen */
  65.    savecursor();                       /* save the current cursor state */
  66.    hidecursor();                       /* force the cursor off */
  67.  
  68.    help_on(0L);                        /* provide help with top screen */
  69.  
  70.    disp_status();                      /* don't tell user to hit F1 for help */
  71.  
  72.    menu_init();                        /* initialize help menu */
  73.  
  74.    /* we do our own getchr() and menu selections here because we don't
  75.       know what might have been going on before help was called - if
  76.       we returned to the caller, things might get screwed up */
  77.  
  78.    while (help_display && (ch = getchr()) != EOF_CH) {
  79.  
  80.       switch(ch) {
  81.          case ' ': case 9:             /* advance the menu selection pointer */
  82.             menu_advance();
  83.             break;
  84.  
  85.          case 8:                       /* backup the menu selection pointer */
  86.             menu_backup();
  87.             break;
  88.  
  89.          case RETURN:                  /* CR - do current menu selection */
  90.             menu_do_current();
  91.             break;
  92.  
  93.          case 27:                      /* escape - return to top menu */
  94.             menu_init();               /* reset the menu subsystem */
  95.             break;
  96.  
  97.          default:                      /* see if the 1st letter of selection */
  98.             menu_do_char(ch);          /* do menu selection starting with ch */
  99.             break;
  100.       }
  101.    }
  102.  
  103.    if (help_display)
  104.       help_exit();                     /* in case user ^Z's out */
  105. }
  106.  
  107.  
  108. /****************************************************************************
  109.                             H E L P _ I N I T
  110.  ****************************************************************************/
  111.  
  112. static int
  113. help_init() {          /* initialize the help subsystem */
  114.  
  115.    stkidx = 0;                  /* make sure stack of offsets is empty */
  116.    lastsel = 0;                 /* there was no last help topic selection */
  117.  
  118.    /* try to open the default help file somewhere in the PATH -
  119.       give up if helpfile doesn't open */
  120.  
  121.    if ((hlp = pathopen(helpfile,"rb")) == NULL)
  122.       show_error(0,15,3,cantopen,helpfile,nohelp);
  123.  
  124.    /* try to allocate a large buffer to access the help file */
  125.  
  126.    if (buffer = (char *) malloc(4096))
  127.       setvbuf(hlp,buffer,_IOFBF,4096);
  128. }
  129.  
  130.  
  131. /*****************************************************************************
  132.                              H E L P _ E X I T
  133.  *****************************************************************************/
  134.  
  135. static int
  136. help_exit() {          /* exit from help subsystem */
  137.  
  138.    fclose(hlp);                /* close the help file */
  139.  
  140.    if (buffer)                 /* release buffer if used */
  141.       free(buffer);
  142.  
  143.    menu_restore();                     /* restore prior menu */
  144.    help_display = FALSE;               /* help is signing off for now */
  145.    restricted = save_restricted;       /* restore prior restricted flag */
  146.  
  147.    purge_menu();               /* free strings used by menu */
  148.  
  149.    restorescreen();            /* restore the prior display screen */
  150.    restorecursor();            /* restore the previous cursor state */
  151. }
  152.  
  153.  
  154. /****************************************************************************
  155.                             H E L P _ O N
  156.  ****************************************************************************/
  157.  
  158. static int
  159. help_on(offset)         /* provide help on selected topic */
  160. long offset;
  161. {
  162.    char *title, hline[HLINESIZ+1];
  163.  
  164.    *hline = 'X';                               /* error flag */
  165.  
  166.    if (fseek(hlp,offset,SEEK_SET) == 0)        /* seek to the help frame */
  167.       hgets(hline);                            /* get the header line */
  168.  
  169.    if (*hline != '#') {                        /* header lines start with # */
  170.       show_error(0,0,2,"Error reading help file",nohelp);
  171.       help_exit();
  172.       longjmp(16,back_to_main);        /* should never happen, but... */
  173.    }
  174.  
  175.    /* display the topic title at top of screen */
  176.  
  177.    title = strchr(hline,' ');
  178.  
  179.    center_text(FIRST_HROW-1,title ? title+1 : hline+1);
  180.  
  181.    help_menu(hline,offset == 0);       /* create menu */
  182.  
  183.    help_text(hline);                   /* display text */
  184. }
  185.  
  186.  
  187. /****************************************************************************
  188.                            H E L P _ T E X T
  189.  ****************************************************************************/
  190.  
  191. static int
  192. help_text(buf)         /* display help text */
  193. char *buf;
  194. {
  195.    register int i, ntext;
  196.  
  197.    ntext = fgetc(hlp);                 /* read # text lines */
  198.  
  199.    for (i = 0; i < HELP_ROWS; i++) {
  200.  
  201.       gotorc(i+FIRST_HROW,0);
  202.  
  203.       if (ntext)
  204.          if (hgets(buf)) {
  205.             disp_str(buf);
  206.             ntext--;
  207.          } else
  208.             ntext = 0;
  209.  
  210.       clr_eol();
  211.    }
  212. }
  213.  
  214.  
  215. /****************************************************************************
  216.                            H E L P _ M E N U
  217.  ****************************************************************************/
  218.  
  219. static int
  220. help_menu(buf,top)     /* build a menu_selection structure for selection */
  221. char *buf;
  222. int top;
  223. {
  224.    int i;
  225.    char *bp;
  226.    register MENU *mp;
  227.    register int nmenu;
  228.  
  229.    purge_menu();                       /* clear out last menu */
  230.  
  231.    mp = top_help_menu;
  232.  
  233.    /* process each menu entry in the help file */
  234.  
  235.    for (nmenu = fgetc(hlp), i = 0; nmenu > 0; nmenu--, mp++) {
  236.  
  237.       fread(&offsets[i++],sizeof(long),1,hlp); /* read the ent's offset */
  238.  
  239.       hgets(buf);                              /* read keyword/prompt */
  240.  
  241.       /* build menu selection for this entry */
  242.  
  243.      if (bp = strchr(buf,' ')) {
  244.          mp->choice = Strndup(buf,bp-buf);
  245.          mp->prompt = Strdup(bp+1);
  246.          mp->func = help_sel;
  247.          mp->sub_menu = top_help_menu;
  248.       } else {
  249.         i--;                                   /* shouldn't happen */
  250.         mp--;
  251.       }
  252.    }
  253.  
  254.    /* assign the two constant entries and finish it */
  255.  
  256.    if (!top)                           /* don't include Prev entry if */
  257.       *mp++ = pmenu;                   /*   if this is the top help menu */
  258.    *mp++ = qmenu;
  259.  
  260.    mp->choice = NULL;                  /* terminate menu structure */
  261. }
  262.  
  263.  
  264. /****************************************************************************
  265.                         P U R G E _ M E N U
  266.  ****************************************************************************/
  267.  
  268. static int
  269. purge_menu() {         /* release the strings used by current help menu */
  270.  
  271.    register int i;
  272.    register MENU *mp;
  273.  
  274.    for (i = 0, mp = top_help_menu; i < NSELS; i++, mp++) {
  275.  
  276.       if (mp->choice && mp->choice != pmenu.choice && mp->choice != qmenu.choice) {
  277.          free(mp->choice);
  278.          free(mp->prompt);
  279.       }
  280.  
  281.       mp->choice = NULL;
  282.    }
  283. }
  284.  
  285.  
  286. /*****************************************************************************
  287.                             H E L P _ B A C K
  288.  *****************************************************************************/
  289.  
  290. static int
  291. help_back() {          /* backup to previous help display */
  292.  
  293.    if (stkidx)                 /* anything on stack? */
  294.       help_on(lastsel = offstack[--stkidx]);
  295. }
  296.  
  297.  
  298. /*****************************************************************************
  299.                             H E L P _ S E L
  300.  *****************************************************************************/
  301.  
  302. static int
  303. help_sel() {           /* select a help topic */
  304.  
  305.    /* put last selection on stack */
  306.  
  307.    if (stkidx < STKSIZ)
  308.       offstack[stkidx++] = lastsel;
  309.  
  310.    /* give user help on whatever topic is desired */
  311.  
  312.    help_on(lastsel = offsets[curmenu.current_selection]);
  313. }
  314.  
  315.  
  316. /*****************************************************************************
  317.                               H G E T S
  318.  *****************************************************************************/
  319.  
  320. static char *
  321. hgets(buf)             /* get a line from help file the way we want it */
  322. register char *buf;
  323. {
  324.    if (fgets(buf,HLINESIZ,hlp)) {
  325.       buf[strlen(buf)-1] = '\0';       /* we don't need no stinking \n's */
  326.       return(buf);
  327.    }
  328.  
  329.    return(NULL);                       /* couldn't get a line */
  330. }
  331.