home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume14 / mush6.0 / part04 / help.c next >
Encoding:
C/C++ Source or Header  |  1988-04-12  |  9.5 KB  |  321 lines

  1. /* @(#)help.c    (c) copyright 10/15/86 (Dan Heller) */
  2.  
  3. /*
  4.  * This file conatins 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.  
  76. #endif /* SUNTOOL */
  77.  
  78. /* what to print if nothing was found */
  79. static char *def_msg[] = {
  80.     "There is no help found for this item.",
  81.     "Perhaps getting help from another item",
  82.     "would be of some use.", 0
  83. };
  84.  
  85. #define MAXLINES    40
  86. #define MAXLENGTH    128
  87. static FILE *help_file;
  88. static char file_name[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.  
  107.     if (!shading)
  108.     if (p = getenv("SHADE")) {
  109.         register int x = atoi(p);
  110.         if (x <= 25)
  111.         shading = &shade_25;
  112.         else if (x <= 50)
  113.         shading = &shade_50;
  114.         else
  115.         shading = &shade_75;
  116.     } else
  117.         shading = &shade_25;
  118.  
  119.     /* If no file given, take "str" arg as message to print */
  120.     if (!file || !*file) {
  121.     file = NULL;
  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 (!*file_name || strcmp(file_name, file)) {
  129.         (void) strcpy(file_name, file);
  130.         if (help_file)
  131.         fclose(help_file), help_file = NULL_FILE;
  132.     }
  133.     /* file remains open */
  134.     if (!help_file && !(help_file = fopen(file_name, "r")))
  135.         return -1;
  136.     /* look for %str% in helpfile */
  137.     (void) sprintf(help_str, "%%%s%%\n", str);
  138.  
  139.     rewind(help_file);
  140.  
  141.     while(p = fgets(args[0], MAXLENGTH, help_file))
  142.         if (*p == '%' && !strcmp(p, help_str))
  143.         break;
  144.  
  145.     if (!p || !fgets(args[0], MAXLENGTH, help_file))
  146.         for(height = 0; def_msg[height] && height < MAXLINES-1; height++) {
  147.         compose_str(def_msg[height], &width);
  148.         (void) strcpy(args[height], def_msg[height]);
  149.         }
  150.     else for (height = 0; p && *p && strcmp(p, "%%\n"); height++) {
  151.         compose_str(p, &width);
  152.         p = fgets(args[height+1], MAXLENGTH, help_file);
  153.         }
  154.     }
  155.     if (height == MAXLINES - 1)
  156.     print("Help message is too long!\n");
  157.  
  158.     fs = fullscreen_init(fd);
  159.     /* Figure out the height and width in pixels (rect.r_height, rect.r_width)
  160.      * Remember to provide for the "confirm" line (cont_msg).
  161.      * extend the new box by 15 pixels on the sides (30 total), top, and bottom.
  162.      * finally, add 16 pixels for "shadow" -- remove before clearing area
  163.      * to preserve background and give a shadow-like appearance.
  164.      */
  165.     if ((x = strlen(cont_msg)) > width)
  166.     width = x; /* this x value must be saved! */
  167.     rect.r_width = (width*l_width()) + 30 + 16;
  168.     rect.r_height = ((height+1) * l_height()) + 30 + 16;
  169.     rect.r_left = fs->fs_screenrect.r_left +
  170.     (fs->fs_screenrect.r_width / 2) - (rect.r_width / 2);
  171.     rect.r_top = fs->fs_screenrect.r_top +
  172.     (fs->fs_screenrect.r_height / 2) - (rect.r_height / 2);
  173.  
  174.     /* save old area */
  175.     saved = save_bits(fs->fs_pixwin, &rect);
  176.  
  177.     /* prepare surface, clear the background, and reset rect for shadow */
  178.     pw_preparesurface(fs->fs_pixwin, &rect);
  179.     pw_lock(fs->fs_pixwin, &rect);
  180.     rect.r_width -= 16;
  181.     rect.r_height -= 16;
  182.  
  183.     pw_writebackground(fs->fs_pixwin,
  184.     rect.r_left, rect.r_top, rect.r_width, rect.r_height, PIX_CLR);
  185.  
  186.     /* make a box that's 5 pixels thick. Then add a thin box inside it */
  187.     for (z = 0; z < 5; z++)
  188.     box(fs->fs_pixwin,
  189.         rect.r_left+z, rect.r_top+z,
  190.         rect.r_left+rect.r_width-z-1, rect.r_top+rect.r_height-z-1,
  191.         PIX_SRC);
  192.     box(fs->fs_pixwin,
  193.     rect.r_left+z+2, rect.r_top+z+2,
  194.     rect.r_left+rect.r_width-z-3, rect.r_top+rect.r_height-z-3,
  195.     PIX_SRC);
  196.  
  197.     /* shading -- pw_replrop() doesn't work (bug)
  198.      * NOTE: fs->fs_screenrect.r_top and r_left are negative values
  199.      */
  200.     pr_replrop(fs->fs_pixwin->pw_pixrect,
  201.        rect.r_left + rect.r_width - fs->fs_screenrect.r_left,
  202.        rect.r_top + 16 - fs->fs_screenrect.r_top,
  203.        16, rect.r_height-16, PIX_SRC|PIX_DST, shading, 0, 0);
  204.     pr_replrop(fs->fs_pixwin->pw_pixrect,
  205.        rect.r_left + 16 - fs->fs_screenrect.r_left,
  206.        rect.r_top+rect.r_height - fs->fs_screenrect.r_top,
  207.        rect.r_width, 16, PIX_SRC|PIX_DST, shading, 0, 0);
  208.  
  209.     if (x > width)
  210.     x = 15;
  211.     else
  212.     x = rect.r_width/2 - (x*l_width())/2;
  213.     y = rect.r_height - 15;
  214.  
  215.     /* Print everything in reverse order now; start with the "confirm" string
  216.      * (which is centered and highlighted)
  217.      */
  218.     pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y, PIX_SRC,font, cont_msg);
  219.     pw_text(fs->fs_pixwin, rect.r_left+x+1, rect.r_top+y, PIX_SRC|PIX_DST, font,
  220.         cont_msg);
  221.  
  222.     y -= (5 + l_height());
  223.     x = 15;
  224.  
  225.     /* now print each string in reverse order (start at bottom of box) */
  226.     for (height--; height >= 0; height--) {
  227.     pw_text(fs->fs_pixwin, rect.r_left+x, rect.r_top+y,
  228.         PIX_SRC, font, args[height]);
  229.     y -= l_height();
  230.     }
  231.  
  232.     pw_unlock(fs->fs_pixwin);
  233.  
  234.     /* wait for user to read and confirm */
  235.     win_getinputmask(fd, &old_im, &old_link);
  236.     input_imnull(&im);
  237.     im.im_flags |= IM_ASCII;
  238.     win_setinputcodebit(&im, MS_LEFT);
  239.     win_setinputcodebit(&im, MS_MIDDLE);
  240.     win_setinputcodebit(&im, MS_RIGHT);
  241.     win_setinputmask(fd, &im, &im, WIN_NULLLINK);
  242.     win_getcursor(fd, &oldcursor);
  243.     win_setcursor(fd, &confirm_cursor);
  244.     while (input_readevent(fd, &event) != -1 && event.ie_code != MS_LEFT);
  245.  
  246.     /* restore old cursor */
  247.     win_setcursor(fd, &oldcursor);
  248.  
  249.     /* restore old pixrect (size already restored) */
  250.     rect.r_height += 16; /* to take care of the shadow */
  251.     rect.r_width += 16;
  252.     restore_bits(fs->fs_pixwin, &rect, saved);
  253.     /* release screen */
  254.     fullscreen_destroy(fs);
  255.     win_setinputmask(fd, &old_im, &old_im, old_link);
  256.     return 0;
  257. }
  258.  
  259. static
  260. compose_str(p, width)
  261. register char *p;
  262. int *width;
  263. {
  264.     register int x;
  265.     if (!p || !*p)
  266.     return 0;
  267.     x = strlen(p);
  268.     if (p[x-1] == '\n')
  269.     p[--x] = 0; /* get rid of newline */
  270.     if (x > *width)
  271.     *width = x;
  272.     return 1;
  273. }
  274. #endif /* SUNTOOL */
  275.  
  276. find_help(str, file)
  277. register caddr_t *str;
  278. register char *file;
  279. {
  280.     register char    *p;
  281.     char        args[MAXLINES][MAXLENGTH], help_str[40];
  282.     register int    n, height;
  283.     extern char        *no_newln();
  284.  
  285.     /* If no file given, take "str" arg as message to print */
  286.     if (!file || !*file) {
  287.     file = NULL;
  288.     for(height = 0; *str && height < MAXLINES-1; height++)
  289.         (void) strcpy(args[height], *str++);
  290.     } else {
  291.     if (!*file_name || strcmp(file_name, file)) {
  292.         (void) strcpy(file_name, file);
  293.         if (help_file)
  294.         fclose(help_file), help_file = NULL_FILE;
  295.     }
  296.     /* file remains open */
  297.     if (!help_file && !(help_file = fopen(file_name, "r")))
  298.         return -1;
  299.     /* look for %str% in helpfile */
  300.     (void) sprintf(help_str, "%%%s%%\n", str);
  301.     rewind(help_file);
  302.     while(p = fgets(args[0], MAXLENGTH, help_file))
  303.         if (*p == '%' && !strcmp(p, help_str))
  304.         break;
  305.     if (!p || !fgets(args[0], MAXLENGTH, help_file))
  306.         for(height = 0; def_msg[height] && height < MAXLINES-1; height++)
  307.         (void) strcpy(args[height], def_msg[height]);
  308.     else for (height = 0; p && *p && strcmp(p, "%%\n"); height++)
  309.         p = fgets(args[height+1], MAXLENGTH, help_file);
  310.     }
  311.     if (height == MAXLINES - 1)
  312.     print("Help message is too long!\n");
  313.  
  314.     for (n = 0; n < height; n++) {
  315.     (void) no_newln(args[n]);
  316.     wprint("%s\n", args[n]);
  317.     }
  318.  
  319.     return 0;
  320. }
  321.