home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 October / usenetsourcesnewsgroupsinfomagicoctober1994disk2.iso / unix / volume18 / mush6.4 / part04 / help.c < prev    next >
Encoding:
C/C++ Source or Header  |  1989-03-12  |  9.1 KB  |  321 lines

  1. /* @(#)help.c    (c) copyright 10/15/86 (Dan Heller) */
  2.  
  3. /*
  4.  * This file contains two main routines:
  5.  *    display_help() and find_help()
  6.  * Both are virtually equivalent in functionality; they are passed
  7.  * a char * or a char **. If a char * is passed, then open "file"
  8.  * argument (containing help strings) and search for %str% and read
  9.  * the following text until %% or EOF into a local buffer.
  10.  * If str is a char **, then that array of strings is used directly.
  11.  *
  12.  * If display_help is used, then the final array of strings used is
  13.  * displayed in the center of the bitmapped console in a box with
  14.  * shading and the user must hit the left mouse button to remove the
  15.  * message.  the fd passed is the fd of the window locking the screen.
  16.  *
  17.  * In text mode, the routine find_help is used (or, if the graphics
  18.  * mode doesn't want to lock the screen to display a message). The
  19.  * same actions occur, but instead of "ifdef"ing up one function, I
  20.  * just made two for readability.
  21.  */
  22. #include <stdio.h>
  23. #include "strings.h"
  24.  
  25. #define NULL_FILE (FILE *)0
  26.  
  27. #ifdef SUNTOOL
  28. #include <suntool/tool_hs.h>
  29. #include <signal.h>
  30. #include <suntool/fullscreen.h>
  31.  
  32. #define l_width()      font->pf_defaultsize.x /* width of letter */
  33. #define l_height()      font->pf_defaultsize.y /* height of letter */
  34.  
  35. #define draw(win,x1,y1,x2,y2,OP)     pw_vector(win, x1,y1,x2,y2,OP,1)
  36. #define box(win, x1,y1,x2,y2,OP) \
  37.     draw(win,x1,y1, x1,y2, OP), \
  38.     draw(win,x1,y2, x2,y2, OP), \
  39.     draw(win,x2,y2, x2,y1, OP), \
  40.     draw(win,x2,y1, x1,y1, OP)
  41.  
  42. #define DEF_CONT_MSG    "Click LEFT mouse Button to continue."
  43. DEFINE_CURSOR(oldcursor, 0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0);
  44.  
  45. /* shading */
  46. static short dat_shade_25[] = {
  47. #include <images/square_25.pr>
  48. };
  49.  
  50. static short dat_shade_50[] = {
  51. #include <images/square_50.pr>
  52. };
  53.  
  54. static short dat_shade_75[] = {
  55. #include <images/square_75.pr>
  56. };
  57.  
  58. static short dat_mouse_left[] = {
  59. #include <images/confirm_left.pr> 
  60. };
  61.  
  62. mpr_static(shade_25,        16, 16, 1, dat_shade_25);
  63. mpr_static(shade_50,        16, 16, 1, dat_shade_50);
  64. mpr_static(shade_75,        16, 16, 1, dat_shade_75);
  65. mpr_static(confirm_pr,      16, 16, 1, dat_mouse_left);
  66.  
  67. static struct cursor confirm_cursor = { 3, 3, PIX_SRC, &confirm_pr };
  68. static struct pixrect *shading;
  69.  
  70. #else
  71.  
  72. #include <sys/types.h>
  73. #define wprint printf
  74. #define print  printf
  75. #define TRUE   1
  76. #define FALSE  0
  77.  
  78. #endif /* SUNTOOL */
  79.  
  80. /* what to print if nothing was found */
  81. static char *def_msg[] = {
  82.     "There is no help found for \"%s\".",
  83.     "Perhaps getting help from another item",
  84.     "would be of some use.", 0
  85. };
  86.  
  87. #define MAXLINES    40
  88. #define MAXLENGTH    128
  89.  
  90. #ifdef SUNTOOL
  91. display_help(fd, str, file, font)
  92. register caddr_t *str;   /* could be a single or double pointer */
  93. register char *file;
  94. register struct pixfont *font;
  95. {
  96.     struct fullscreen *fs;
  97.     struct inputmask im, old_im;
  98.     struct inputevent event;
  99.     struct rect rect;
  100.     register char *p;
  101.     register int x, y, z, height;
  102.     struct pixrect *saved, *save_bits();
  103.     int width = 0, old_link;
  104.     char *cont_msg = DEF_CONT_MSG, *getenv();
  105.     char args[MAXLINES][MAXLENGTH], help_str[40];
  106.     FILE *fp;
  107.  
  108.     if (!shading)
  109.     if (p = getenv("SHADE")) {
  110.         register int x = atoi(p);
  111.         if (x <= 25)
  112.         shading = &shade_25;
  113.         else if (x <= 50)
  114.         shading = &shade_50;
  115.         else
  116.         shading = &shade_75;
  117.     } else
  118.         shading = &shade_25;
  119.  
  120.     /* If no file given, take "str" arg as message to print */
  121.     if (!file || !*file) {
  122.     for (height = 0; *str && height < MAXLINES-1; height++) {
  123.         if (!compose_str(*str, &width))
  124.         break;
  125.         (void) strcpy(args[height], *str++);
  126.     }
  127.     } else {
  128.     if (!(fp = fopen(file, "r")))
  129.         return -1;
  130.     /* look for %str% in helpfile */
  131.     (void) sprintf(help_str, "%%%s%%\n", str);
  132.  
  133.     while(p = fgets(args[0], MAXLENGTH, fp))
  134.         if (*p == '%' && !strcmp(p, help_str))
  135.         break;
  136.  
  137.     if (!p || !fgets(args[0], MAXLENGTH, fp)) {
  138.         char buf[64];
  139.         for(height = 0; def_msg[height] && height < MAXLINES-1; height++) {
  140.         sprintf(buf, def_msg[height], str);
  141.         compose_str(buf, &width);
  142.         (void) strcpy(args[height], buf);
  143.         }
  144.     } else
  145.         for (height = 0; p && *p && strcmp(p, "%%\n"); height++) {
  146.         compose_str(p, &width);
  147.         p = fgets(args[height+1], MAXLENGTH, fp);
  148.         }
  149.     }
  150.     if (height == MAXLINES - 1)
  151.     print("Help message is too long!\n");
  152.  
  153.     fclose(fp);
  154.  
  155.     fs = fullscreen_init(fd);
  156.     /* Figure out the height and width in pixels (rect.r_height, rect.r_width)
  157.      * Remember to provide for the "confirm" line (cont_msg).
  158.      * extend the new box by 15 pixels on the sides (30 total), top, and bottom.
  159.      * finally, add 16 pixels for "shadow" -- remove before clearing area
  160.      * to preserve background and give a shadow-like appearance.
  161.      */
  162.     if ((x = strlen(cont_msg)) > width)
  163.     width = x; /* this x value must be saved! */
  164.     rect.r_width = (width*l_width()) + 30 + 16;
  165.     rect.r_height = ((height+1) * l_height()) + 30 + 16;
  166.     rect.r_left = fs->fs_screenrect.r_left +
  167.     (fs->fs_screenrect.r_width / 2) - (rect.r_width / 2);
  168.     rect.r_top = fs->fs_screenrect.r_top +
  169.     (fs->fs_screenrect.r_height / 2) - (rect.r_height / 2);
  170.  
  171.     /* save old area */
  172.     saved = save_bits(fs->fs_pixwin, &rect);
  173.  
  174.     /* prepare surface, clear the background, and reset rect for shadow */
  175.     pw_preparesurface(fs->fs_pixwin, &rect);
  176.     pw_lock(fs->fs_pixwin, &rect);
  177.     rect.r_width -= 16;
  178.     rect.r_height -= 16;
  179.  
  180.     pw_writebackground(fs->fs_pixwin,
  181.     rect.r_left, rect.r_top, rect.r_width, rect.r_height, PIX_CLR);
  182.  
  183.     /* make a box that's 5 pixels thick. Then add a thin box inside it */
  184.     for (z = 0; z < 5; z++)
  185.     box(fs->fs_pixwin,
  186.         rect.r_left+z, rect.r_top+z,
  187.         rect.r_left+rect.r_width-z-1, rect.r_top+rect.r_height-z-1,
  188.         PIX_SRC);
  189.     box(fs->fs_pixwin,
  190.     rect.r_left+z+2, rect.r_top+z+2,
  191.     rect.r_left+rect.r_width-z-3, rect.r_top+rect.r_height-z-3,
  192.     PIX_SRC);
  193.  
  194.     /* shading -- pw_replrop() doesn't work (bug)
  195.      * NOTE: fs->fs_screenrect.r_top and r_left are negative values
  196.      */
  197.     pr_replrop(fs->fs_pixwin->pw_pixrect,
  198.        rect.r_left + rect.r_width - fs->fs_screenrect.r_left,
  199.        rect.r_top + 16 - fs->fs_screenrect.r_top,
  200.        16, rect.r_height-16, PIX_SRC|PIX_DST, shading, 0, 0);
  201.     pr_replrop(fs->fs_pixwin->pw_pixrect,
  202.        rect.r_left + 16 - fs->fs_screenrect.r_left,
  203.        rect.r_top+rect.r_height - fs->fs_screenrect.r_top,
  204.        rect.r_width, 16, PIX_SRC|PIX_DST, shading, 0, 0);
  205.  
  206.     if (x > width)
  207.     x = 15;
  208.     else
  209.     x = rect.r_width/2 - (x*l_width())/2;
  210.     y = rect.r_height - 15;
  211.  
  212.     /* Print everything in reverse order now; start with the "confirm" string
  213.      * (which is centered and highlighted)
  214.      */
  215.     pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y, PIX_SRC,font, cont_msg);
  216.     pw_text(fs->fs_pixwin, rect.r_left+x+1, rect.r_top+y, PIX_SRC|PIX_DST, font,
  217.         cont_msg);
  218.  
  219.     y -= (5 + l_height());
  220.     x = 15;
  221.  
  222.     /* now print each string in reverse order (start at bottom of box) */
  223.     for (height--; height >= 0; height--) {
  224.     pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y,
  225.         PIX_SRC, font, args[height]);
  226.     y -= l_height();
  227.     }
  228.  
  229.     pw_unlock(fs->fs_pixwin);
  230.  
  231.     /* wait for user to read and confirm */
  232.     win_getinputmask(fd, &old_im, &old_link);
  233.     input_imnull(&im);
  234.     im.im_flags |= IM_ASCII;
  235.     win_setinputcodebit(&im, MS_LEFT);
  236.     win_setinputcodebit(&im, MS_MIDDLE);
  237.     win_setinputcodebit(&im, MS_RIGHT);
  238.     win_setinputmask(fd, &im, &im, WIN_NULLLINK);
  239.     win_getcursor(fd, &oldcursor);
  240.     win_setcursor(fd, &confirm_cursor);
  241.     while (input_readevent(fd, &event) != -1 && event.ie_code != MS_LEFT);
  242.  
  243.     /* restore old cursor */
  244.     win_setcursor(fd, &oldcursor);
  245.  
  246.     /* restore old pixrect (size already restored) */
  247.     rect.r_height += 16; /* to take care of the shadow */
  248.     rect.r_width += 16;
  249.     restore_bits(fs->fs_pixwin, &rect, saved);
  250.     /* release screen */
  251.     fullscreen_destroy(fs);
  252.     win_setinputmask(fd, &old_im, &old_im, old_link);
  253.     return 0;
  254. }
  255.  
  256. static
  257. compose_str(p, width)
  258. register char *p;
  259. int *width;
  260. {
  261.     register int x;
  262.     if (!p || !*p)
  263.     return 0;
  264.     x = strlen(p);
  265.     if (p[x-1] == '\n')
  266.     p[--x] = 0; /* get rid of newline */
  267.     if (x > *width)
  268.     *width = x;
  269.     return 1;
  270. }
  271. #endif /* SUNTOOL */
  272.  
  273. find_help(str, file)
  274. register caddr_t *str;
  275. register char *file;
  276. {
  277.     register char    *p;
  278.     char        buf[BUFSIZ], help_str[40];
  279.     register int    height;
  280.     extern char        *no_newln();
  281.     FILE        *fp;
  282.  
  283.     /* If no file given, take "str" arg as message to print */
  284.     if (!file || !*file) {
  285.     /* use the pager on the args to the function */
  286.     do_pager(NULL, TRUE);
  287.     while (*str) {
  288.         (void) do_pager(*str++, FALSE);
  289.         if (do_pager("\n", FALSE) == EOF)
  290.         break;
  291.     }
  292.     do_pager(NULL, FALSE);
  293.     return 0;
  294.     }
  295.  
  296.     if (!(fp = fopen(file, "r")))
  297.     return -1;
  298.     /* look for %str% in helpfile */
  299.     (void) sprintf(help_str, "%%%s%%\n", str);
  300.  
  301.     while (p = fgets(buf, sizeof buf, fp))
  302.     if (*p == '%' && !strcmp(p, help_str))
  303.         break;
  304.     if (!p)
  305.     /* Didn't find the help requested */
  306.     for (height = 0; def_msg[height]; height++) {
  307.         wprint(def_msg[height], str);
  308.         wprint("\n");
  309.     }
  310.     else {
  311.     do_pager(NULL, TRUE);
  312.     while ((p = fgets(buf, sizeof buf, fp)) && strcmp(p, "%%\n"))
  313.         if (do_pager(buf, FALSE) == EOF)
  314.         break;
  315.     do_pager(NULL, FALSE);
  316.     }
  317.     fclose(fp);
  318.  
  319.     return 0;
  320. }
  321.