home *** CD-ROM | disk | FTP | other *** search
/ ARM Club 3 / TheARMClub_PDCD3.iso / hensa / misc / b186_1 / Source / c / display < prev    next >
Text File  |  1987-09-27  |  24KB  |  974 lines

  1. /*
  2.  
  3.        This file is part of the PDP software package.
  4.          
  5.        Copyright 1987 by James L. McClelland and David E. Rumelhart.
  6.        
  7.        Please refer to licensing information in the file license.txt,
  8.        which is in the same directory with this source file and is
  9.        included here by reference.
  10. */
  11.  
  12.  
  13. /* display.c
  14.  
  15.     Update the screen based on the display template
  16.     that we read in from the user.
  17.     
  18.     First version implemented by Elliot Jaffe.
  19.     
  20.     Date of last revision:  8-12-87/JLM.
  21. */
  22. /*LINTLIBRARY*/
  23.  
  24. #include "general.h"
  25. #include "io.h"
  26. #include "variable.h"
  27. #include "template.h"
  28. #include "weights.h"
  29. #include "command.h"
  30.  
  31. /* the top level function in this module is update_display().
  32.  
  33.    This function parses the template list, and prints only those
  34.    things that are turned on.  It prints things using the given
  35.    display type, and tempered by the type of the variable.  This 
  36.    means that there are a lot of small functions here that do  
  37.    specific type and variable-type displaying.
  38.    
  39.    The main program should first call init_display() to set up the
  40.    screen.  This mainly means that the screen is cleared.
  41.    No other updating of the screen is done.
  42.    
  43. */
  44.  
  45. int    num_lines = MAX_SCREEN_LINES;
  46. int    num_cols = MAX_SCREEN_COLUMNS;
  47. int     command_x = 0;        /* start points for the command line */
  48. int     command_y = 0;        /* they default to (0,0) */
  49. int     Display_level = 0;
  50. int     Save_level = 0;
  51. int     Screen_clear = 0;
  52. int    stand_out = 1;        /* stand out mode defaults to on */
  53. int    saveit = 0;
  54. int    logflag = 0;
  55.  
  56. FILE    *lfp = NULL;            /* logfile */
  57.  
  58. /* initialize the display screen */
  59. init_display() {
  60.     int     set_log(),save_screen();
  61.  
  62.     (void) install_command("screen",save_screen, SAVEMENU,(int *) NULL);
  63.     (void) install_var("standout", Int,(int *) & stand_out,0,0, 
  64.                                 DISPLAYOPTIONS);
  65.     (void) install_var("dlevel", Int,(int *) &Display_level, 0, 0,SETPCMENU);
  66.     (void) install_var("slevel", Int,(int *) &Save_level, 0, 0, SETPCMENU);
  67. }
  68.  
  69. end_display() {
  70.     clear_display();
  71.     io_endwin();
  72. }
  73.  
  74. clear_display() {
  75.     io_clear();
  76.     Screen_clear = 1;
  77.     io_refresh();
  78.     return(CONTINUE);
  79. }
  80.  
  81. update_display() {
  82.     struct Template *tp;
  83.     int tindex;
  84.     int saved = 0;
  85.  
  86. /* if the screen is clear, we must begin by printing the background  */
  87.  
  88.     if(Screen_clear && layout_defined)
  89.     display_background();
  90.  
  91.     tindex = ntemplates;
  92.     
  93.     while (--tindex >= 0) {     /* list is backwards */
  94.         tp = torder[tindex];
  95.  
  96.     if ((tp->display_level > 0 && tp->display_level <= Display_level)
  97.         || (tp->display_level == Display_level)
  98.         || (Screen_clear && !tp->display_level)) {
  99.         if(logflag && tp->display_level>0 && 
  100.                         tp->display_level<= Save_level)
  101.          {
  102.          saved++;
  103.          saveit = 1;
  104.          }
  105.         update_template(tp);
  106.         saveit = 0;
  107.     }
  108.     }
  109.     if(saved) {
  110.         fprintf(lfp,"\n");
  111.     fflush(lfp);
  112.     }
  113.     io_refresh();
  114.     Screen_clear = 0;
  115.     return(CONTINUE);
  116. }
  117.  
  118. redisplay() {
  119.     clear_display();
  120.     update_display();
  121. }
  122.  
  123. update_template(tp)
  124. struct Template *tp;
  125. {
  126.     if (tp->defined == 0) {
  127.     if (!try_to_define(tp)) {
  128.         sprintf(err_string,"Undefined variable in template file: %s.",
  129.             tp->var);
  130.         return(put_error(err_string));
  131.     }
  132.     }
  133.     switch (tp->type) {
  134.     case VECTOR: 
  135.         display_vector(tp);
  136.         break;
  137.     case MATRIX: 
  138.         display_matrix(tp);
  139.         break;
  140.     case VARIABLE:
  141.         display_variable(tp);
  142.         break;
  143.     case LABEL: 
  144.         display_label(tp);
  145.         break;
  146.     case LABEL_ARRAY: 
  147.         display_label_array(tp);
  148.         break;
  149.     case LOOK: 
  150.         display_look(tp);
  151.         break;
  152.     case LABEL_LOOK: 
  153.         display_label_look(tp);
  154.         break;
  155.     case FLOATVAR: 
  156.         display_float_variable(tp);
  157.         break;
  158.     default: 
  159.         return(put_error("Error: unknown display type in template\n"));
  160.     }
  161.     return(CONTINUE);
  162. }
  163.  
  164. /* ARGSUSED */
  165. do_update_template(str, intp)
  166. char   *str;
  167. int    *intp;
  168. {
  169.     struct Template *tp = (struct Template *) intp;
  170.  
  171.     return(update_template(tp));
  172. }
  173.  
  174. try_to_define(template)
  175. struct Template *template;
  176. {
  177.     struct Variable *var;
  178.  
  179.     if ((var = lookup_var((char *) template->var)) == NULL)
  180.     return(FALSE);
  181.     else {
  182.     free((char *) template->var);
  183.     template->var = var;
  184.     template->defined = 1;
  185.     return(TRUE);
  186.     }
  187. }
  188.  
  189.  
  190. /* display a string in the given number of spaces with a given number of
  191.    leading spaces     */
  192.  
  193. display_string(str, nchars, npads)
  194. char   *str;
  195. int     nchars;
  196. int     npads;
  197. {
  198.     char    fmt[20];
  199.     char    string[BUFSIZ];
  200.     int        i;
  201.     int        nc;
  202.  
  203.     *string = '\0';
  204.     for(i=0; i < npads; i++)
  205.        strcat(string," ");
  206.     strcat(string,str);
  207.     if (nchars >= 0) {
  208.       (void) sprintf(fmt, "%%-%d.%ds", nchars, nchars);
  209.     }
  210.     else {
  211.       nc = - nchars;
  212.       (void) sprintf(fmt, "%%%d.%ds", nc, nc);
  213.     }
  214.     io_printw(fmt,string);
  215.     if (saveit) fprintf(lfp," %s",str);
  216. }
  217.  
  218.  
  219. /* display an integer given a specific scale and number of digits */
  220.  
  221. display_integer(val, dig, scale)
  222. int     val;
  223. int     dig;
  224. float   scale;
  225. {
  226.     long    lval;
  227.  
  228.     lval = (long)(val * scale);
  229.     print_digits(lval, dig);
  230.     if(saveit) fprintf(lfp," %d",val);
  231. }
  232.  
  233. /* display a float given a specific scale and number of digits */
  234.  
  235. #define FUDGE 0.0000001
  236.  
  237. display_float(val, dig, scale)
  238. float  val;
  239. int     dig;
  240. float  scale;
  241. {
  242.     float  tmp;
  243.     long    lval;
  244.  
  245.     tmp = (val * scale);
  246.     if (tmp >= 0) tmp += FUDGE;
  247.     else tmp -= FUDGE;
  248.     /* FUDGE is supposed to ensure that floats on the razor's edge
  249.        between two integer values are not incorrectly truncated downward */
  250.     lval = (long) tmp;
  251.     print_digits(lval, dig);
  252.     if(saveit) fprintf(lfp," %6.3f",val);
  253. }
  254.  
  255. /* this function prints a single floating value as a float */
  256.  
  257. display_as_float(val, dig, scale)
  258. float  val;
  259. int     dig;
  260. float  scale;
  261. {
  262.     char    fmt[10];
  263.     char    tmp[100];
  264.  
  265.     val = val * scale;
  266.     (void) sprintf(fmt, "%%%d.4f", dig);
  267.     (void) sprintf(tmp,fmt,val);
  268.     (void) sprintf(fmt, "%%%d.%ds",dig,dig);
  269.     io_printw(fmt, tmp);
  270.     if(saveit) fprintf(lfp," %6.3f",val);
  271. }
  272.  
  273. /* finally, we get to the routines for displaying the various
  274.    template types */
  275.  
  276. display_vector(template)
  277. struct Template *template;
  278. {
  279.     float  *fptr;
  280.     int    *iptr;
  281.     char   **sptr;
  282.     int     count, end, start, max_count;
  283.     int     digits;
  284.     boolean orientation;
  285.     float   scale;
  286.  
  287.     if (template->var == NULL)
  288.     return(put_error("Undefined Template Encountered."));
  289.  
  290.     io_move(template->y, template->x);
  291.     start = template->min_x;
  292.     max_count = start+(template->max_x);
  293.     end = template->var->max_x;
  294.     digits = template->digits;
  295.     scale = template->precision;
  296.     orientation=template->orientation;
  297.     switch (template->var->type) {
  298.     case Vint: 
  299.         iptr = (int *) template->var->varptr;
  300.         for (count = start; count < end && count < max_count; count++) {
  301.         if(!orientation) {
  302.             io_move(template->y+count-start,template->x);
  303.         }
  304.         display_integer(iptr[count], digits, scale);
  305.         }
  306.         break;
  307.     case Vfloat: 
  308.         fptr = (float *) template->var->varptr;
  309.         for (count = start; count < end && count < max_count; count++) {
  310.         if(!orientation) {
  311.             io_move(template->y+count-start,template->x);
  312.         }
  313.         display_float(fptr[count], digits, scale);
  314.         }
  315.         break;
  316.     case Vstring: 
  317.         sptr = (char **) template->var->varptr;
  318.         for (count = start; count < end && count < max_count; count++) {
  319.         if(!orientation) {
  320.             io_move(template->y+count-start,template->x);
  321.         }
  322.         display_string(sptr[count], digits,(int)scale);
  323.         }
  324.         break;
  325.     default: 
  326.         sprintf(err_string,"Error: cannot display %s as vector.\n", 
  327.                             template->var->name);
  328.         return(put_error(err_string));
  329.     }
  330.     return(CONTINUE);
  331. }
  332.  
  333. display_matrix(template)
  334. struct Template *template;
  335. {
  336.     float  *fptr;
  337.     float  **pfptr;
  338.     int     maxr,firstr,lastr,maxs,firsts,lasts,r,s,ts,tr;
  339.     int     x,y;
  340.     boolean orientation;
  341.     int     digits;
  342.     float   scale;
  343.     int tempint;
  344.  
  345.     if (template->var == NULL)
  346.     return(put_error("Undefined Template Encountered."));
  347.  
  348.     x = template->x;
  349.     y = template->y;
  350.     maxr = template->var->max_x; /* in the variable structure, x is
  351.                     used to index rows, y columns! */
  352.     firstr = template->min_x;
  353.     lastr = firstr+template->max_x;
  354.     firsts= template->min_y;
  355.     maxs = template->var->max_y;
  356.     lasts = firsts+template->max_y;
  357.     digits = template->digits;
  358.     scale = template->precision;
  359.     orientation = template->orientation;
  360.     pfptr = (float **) template->var->varptr;
  361.     io_move(y, x);
  362.  
  363.     switch (template->var->type) {
  364.     case PVweight: 
  365.         for (r = firstr,tr = 0; r < lastr && r < maxr; r++,tr++) {
  366.          maxs = first_weight_to[r] + num_weights_to[r];
  367.              for (s = firsts,ts = 0; s < lasts && s < maxs; s++,ts++) {
  368.             if (s >= first_weight_to[r]) {
  369.               if (orientation) io_move(y+tr, x+(ts*digits));
  370.               else io_move(y+ts, x+(tr*digits));
  371.               tempint = s - first_weight_to[r];
  372.                   display_float(pfptr[r][tempint], digits, scale);
  373.               /* tempint is a kludge for Microsoft C compiler */
  374.             }
  375.         }
  376.         }
  377.         break;
  378.     case PVfloat: 
  379.         for (r = firstr,tr = 0; r < lastr && r < maxr; r++,tr++) {
  380.              for (s = firsts,ts = 0; s < lasts && s < maxs; s++,ts++) {
  381.             if (orientation) io_move(y+tr, x+(ts*digits));
  382.             else io_move(y+ts, x+(tr*digits));
  383.                 display_float(pfptr[r][s], digits, scale);
  384.  
  385.         }
  386.         }
  387.         break;
  388.     default: 
  389.         sprintf(err_string,"Error: cannot display %s in matrix form\n", 
  390.                             template->var->name);
  391.         return(put_error(err_string));
  392.     }
  393.     return(CONTINUE);
  394. }
  395.  
  396. display_variable(template)
  397. struct Template *template;
  398. {
  399.     float  *fptr;
  400.     int    *iptr;
  401.     char   *cptr;
  402.     char   *sptr;
  403.     int     digits;
  404.     float   scale;
  405.  
  406.     if (template->var == NULL)
  407.     return(put_error("Undefined Template Encountered."));
  408.  
  409.     io_move(template->y, template->x);
  410.     digits = template->digits;
  411.     scale = template->precision;
  412.     switch (template->var->type) {
  413.     case Char: 
  414.         cptr = (char *) template->var->varptr;
  415.         io_printw("%c", *cptr);
  416.         break;
  417.     case Int: 
  418.         iptr = (int *) template->var->varptr;
  419.         display_integer(*iptr, digits, scale);
  420.         break;
  421.     case Float: 
  422.         fptr = (float *) template->var->varptr;
  423.         display_float(*fptr, digits, scale);
  424.         break;
  425.     case String: 
  426.         sptr = (char *) template->var->varptr;
  427.         display_string(sptr, digits, 0);
  428.         break;
  429.     default: 
  430.         sprintf(err_string,
  431.            "Error: cannot display %s as a single variable.\n",
  432.                 template->var->name);
  433.         return(put_error(err_string));
  434.     }
  435.     return(CONTINUE);
  436. }
  437.  
  438. /* display a float as a float using standard printf formatting */
  439.  
  440. display_float_variable(template)
  441. struct Template *template;
  442. {
  443.     float  *fptr;
  444.     int     digits;
  445.     float   scale;
  446.  
  447.     if (template->var == NULL)
  448.     return(put_error("Undefined Template Encountered."));
  449.  
  450.     io_move(template->y, template->x);
  451.     digits = template->digits;
  452.     scale = template->precision;
  453.     switch (template->var->type) {
  454.     case Float: 
  455.         fptr = (float *) template->var->varptr;
  456.         display_as_float(*fptr, digits, scale);
  457.         break;
  458.     default: 
  459.         sprintf(err_string,
  460.             "Error: cannot display %s in floating point notation\n", 
  461.                 template->var->name);
  462.         return(put_error(err_string));
  463.     }
  464.     return(CONTINUE);
  465. }
  466.  
  467.  
  468. /* print the label */
  469. display_label(template)
  470. struct Template *template;
  471. {
  472.     print_string((char *) template->name, template->orientation, 
  473.             template->x, template->y, template->digits);
  474. }
  475.  
  476.  
  477. /* print the label array:  this means running through the array, and 
  478.    printing each label at the correct position.  if the orientation is
  479.    horizontal, then we print horizontaly, and drop one line.  if the 
  480.    orientation is vertical, then we print verticaly, and move over one
  481.    character.
  482. */
  483.  
  484. display_label_array(template)
  485. struct Template *template;
  486. {
  487.     int     count,
  488.             start,
  489.             end,
  490.         max_count;
  491.     int     x,
  492.             y;
  493.     char  **strp;
  494.  
  495.     if (template->var == NULL)
  496.     return(put_error("Undefined Template Encountered."));
  497.  
  498.     if (template->var->type != Vstring) {
  499.         sprintf(err_string,"Error: cannot display %s as label array.",
  500.         template->var->name);
  501.     return(put_error(err_string));
  502.     }
  503.         
  504.     start = template->min_x;
  505.     max_count = start+template->max_x;
  506.     end = template->var->max_x;
  507.     x = template->x;
  508.     y = template->y;
  509.  
  510.     strp = (char **) template->var->varptr + start;
  511.  
  512.     if (template->orientation) {
  513.     for (count = start; count < end && count < max_count; count++, y++) {
  514.         print_string(*strp++, template->orientation, x, y,
  515.              template->digits);
  516.     }
  517.     }
  518.     else {
  519.     for (count = start; count < end && count < max_count; count++, x++) {
  520.         print_string(*strp++, template->orientation, x, y, 
  521.              template->digits);
  522.     }
  523.     }
  524.     return(CONTINUE);
  525. }
  526.  
  527. display_look(template)
  528. struct Template *template;
  529. {
  530.     float  *fptr;
  531.     float  **pfptr;
  532.     int    *iptr;
  533.     char   **look;        /* pointer to the look array */
  534.     int     endr,        /* last column in actual array */
  535.             endc,        /* last row in actual array */
  536.             max_x,        /* largest x index of look array */
  537.             max_y;        /* largest y index of look array */
  538.     int     offx,        /* offsets for the look */
  539.             offy;
  540.     int     y,            /* y index in the look */
  541.             x;            /* x index in the look */
  542.     int     digits;
  543.     float   scale;
  544.     int        spacing;
  545.     int        type;
  546.     int        row, col;        /* indexes to array elements */
  547.     int        windex;        /* weight index */
  548.     int        index;
  549.  
  550.     if (template->var == NULL)
  551.     return(put_error("Undefined Template Encountered."));
  552.  
  553.     look = template->look->look_template;
  554.     offx = template->x;
  555.     offy = template->y;
  556.     endr = template->var->max_x; /* in the variable structure, 
  557.                     x is used to index
  558.                     rows, y to index columns! */
  559.     endc = template->var->max_y;
  560.     max_x = template->look->look_x * template->spacing;
  561.     max_y = template->look->look_y;
  562.     digits = template->digits;
  563.     scale = template->precision;
  564.     spacing = template->spacing;
  565.     type = template->var->type;
  566.     io_move(offy, offx);
  567.     switch (template->var->type) {
  568.     case Vint: 
  569.         iptr = (int *) template->var->varptr;
  570.         for (y = 0; y < max_y; y++) {
  571.         for (x = 0; x < max_x; x += spacing) {
  572.             if ((*look != NOCELL) && ((index = atoi(*look)) < endr)) {
  573.             io_move(offy + y, offx + x);
  574.             display_integer(*(iptr + index), digits, scale);
  575.             }
  576.             look++;    /* go to the next look cell */
  577.         }
  578.         }
  579.         break;
  580.     case Vfloat: 
  581.         fptr = (float *) template->var->varptr;
  582.         for (y = 0; y < max_y; y++) {
  583.         for (x = 0; x < max_x; x += spacing) {
  584.             if ((*look != NOCELL) && ((index = atoi(*look)) < endr)) {
  585.             io_move(offy + y, offx + x);
  586.             display_float(*(fptr + index), digits, scale);
  587.             }
  588.             look++;    /* go to the next look cell */
  589.         }
  590.         }
  591.         break;
  592.     case PVfloat:
  593.     case PVweight:
  594.         pfptr = (float **) template->var->varptr;
  595.         for (y = 0; y < max_y; y++) {
  596.         for (x = 0; x < max_x; x += spacing) {
  597.             if (*look != NOCELL) {
  598.             io_move(offy + y, offx + x);
  599.             sscanf(*look,"%d,%d",&row,&col);
  600.             if (row < endr && col < endc) {
  601.               fptr = pfptr[row];
  602.               if (type == PVfloat) {
  603.                 fptr += col;
  604.                 display_float(*fptr, digits, scale);
  605.               }
  606.               else { /* its a PVweight, so take care of offsets */
  607.                 windex = (col - first_weight_to[row]);
  608.                 if (windex < 0 || windex < num_weights_to[row]) {
  609.                     fptr += windex;
  610.                 display_float(*fptr, digits, scale);
  611.                 }
  612.               }
  613.             }
  614.             }
  615.             look++;
  616.         }
  617.         }
  618.         break;
  619.     default: 
  620.         sprintf(err_string,"Error: look cannot display %s.\n", 
  621.                     template->var->name);
  622.         return(put_error(err_string));
  623.     }
  624.     return(CONTINUE);
  625. }
  626.  
  627. display_label_look(template)
  628. struct Template *template;
  629. {
  630.     char  **look;        /* pointer to the look array */
  631.     char  **sptr;        /* pointer to list of labels */
  632.     int     end,        /* last index in actual array */
  633.             max_x,        /* largest x index of look array */
  634.             max_y;        /* largest y index of look array */
  635.     int     offx,        /* offsets for the look */
  636.             offy;
  637.     int     inc_y, inc_x;    /* increments to y and x */
  638.     int     y,            /* y index in the look */
  639.             x;            /* x index in the look */
  640.     int     digits;
  641.     boolean orientation;
  642.     int     spacing;
  643.     int        index;
  644.  
  645.     if (template->var == NULL)
  646.     return(put_error("Undefined Template Encountered."));
  647.  
  648.     if (template->var->type != Vstring) {
  649.         sprintf(err_string,"Error: cannot display %s as label array.",
  650.         template->var->name);
  651.     return(put_error(err_string));
  652.     }
  653.         
  654.     look = template->look->look_template;
  655.     offx = template->x;
  656.     offy = template->y;
  657.     end = template->var->max_x;
  658.     digits = template->digits;
  659.     orientation = template->orientation;
  660.     spacing = template->spacing;
  661.     if (orientation == HORIZONTAL) {
  662.       max_x = template->look->look_x * spacing;
  663.       max_y = template->look->look_y;
  664.       inc_y = 1;
  665.       inc_x = spacing;
  666.     }
  667.     else {
  668.       max_x = template->look->look_x;
  669.       max_y = template->look->look_y * spacing;
  670.       inc_x = 1;
  671.       inc_y = spacing;
  672.     }
  673.     sptr = (char **) template->var->varptr;
  674.     for (y = 0; y < max_y; y += inc_y) {
  675.     for (x = 0; x < max_x; x += inc_x) {
  676.         if ((*look != NOCELL) && ((index = atoi(*look)) < end)) {
  677.             print_string(*(sptr + index), orientation, x+offx, y+offy,
  678.                              digits);
  679.         }
  680.         look++;    /* go to the next look cell */
  681.     }
  682.     }
  683.     return(CONTINUE);
  684. }
  685.  
  686. /* this procedure is the workhorse for printing numeric values.
  687.    it is optimized for printing digit lengths of 1,2, or 3. But
  688.    it will work for digit lengths up to 10.  It prints the number
  689.    in the correct number of digits, if the number fits.  otherwise
  690.    it prints stars.  A number that is less than 0, is printed in
  691.    reverse video.                        */
  692.  
  693. print_digits(lval, dig)
  694. long    lval;
  695. int     dig;
  696. {
  697.     char    fmt[20];
  698.     long    temp;
  699.     double  pow ();
  700.  
  701.     if (lval < 0) {
  702.       if (stand_out) {
  703.     io_standout();
  704.       }
  705.       else {
  706.     print_neg_digits(lval, dig);
  707.     return;
  708.       }
  709.     }
  710.     temp = ((lval < 0) ? -lval : lval);
  711.     if (dig == 1) {
  712.     if (temp > 9) {
  713.         io_printw("%1s", "*");
  714.     }
  715.     else {
  716.         io_printw("%1ld", temp);
  717.     }
  718.     }
  719.     else
  720.     if (dig == 2) {
  721.         if (temp > 99) {
  722.         io_printw("%2s", "**");
  723.         }
  724.         else {
  725.         io_printw("%2ld", temp);
  726.         }
  727.     }
  728.     else
  729.     if (dig == 3) {
  730.         if (temp > 999) {
  731.         io_printw("%3s", "***");
  732.         }
  733.         else {
  734.         io_printw("%3ld", temp);
  735.         }
  736.     }
  737.     else {
  738.     if ((double) temp > (double)(pow(10.0,(double) dig) - 1.0)) {
  739.         (void) sprintf(fmt, "%%%d.%ds", dig, dig);
  740.         io_printw(fmt, "***********");
  741.     }
  742.     else {
  743.         (void) sprintf(fmt, "%%%dld", dig);
  744.         io_printw(fmt, temp);
  745.     }
  746.     }
  747.     if (lval < 0)
  748.     io_standend();
  749. }
  750.  
  751. /* this procedure is used to print strings.
  752.  
  753.    It is special, in that it will print strings vertically as
  754.    well as the usual horizontal.
  755. */
  756. print_string(str, horizontal, x, y, digits)
  757. char   *str;
  758. boolean horizontal;
  759. int     x,
  760.         y;
  761. int     digits;            /* number of characters to display */
  762. {
  763.     int     count,
  764.             end;
  765.     char    fmt[20];
  766.  
  767.     if (horizontal) {
  768.     io_move(y, x);
  769.     (void) sprintf(fmt, "%%-%d.%ds", digits, digits);
  770.     io_printw(fmt, str);
  771.     }
  772.     else {
  773.     end = strlen(str);
  774.     for (count = 0; count < end && count < digits; count++, str++) {
  775.         io_move(y++, x);
  776.         io_printw("%c", *str);
  777.     }
  778.     }
  779. }
  780.  
  781.  
  782. display_background()
  783. {
  784.    int    x,y;
  785.  
  786.    for(x = 0; x <= num_cols;x++)
  787.        for(y = 0; y <= num_lines-5;y++)
  788.          if( background[y][x] != '\0') {
  789.            io_move(y+5,x);
  790.            io_printw("%c",background[y][x]);
  791.        }
  792. }
  793.        
  794. /* this is called from the command system.  it allows change of
  795.    selected parts of the display.  Essentially, you can turn the display
  796.    on or off, and change the numbers of digits, or the scaling factor.
  797.    */
  798. /* ARGSUSED */
  799. change_display(command_string, tempp)
  800. char   *command_string;
  801. int    *tempp;
  802. {
  803.     struct Template *tp;
  804.     char    command1[BUFSIZ];
  805.     char   *str;
  806.  
  807.     tp = (struct Template  *) tempp;
  808.  
  809.     (void) sprintf(command1,
  810.         "%s: change what  [level = %d, #digits = %d, scale = %.3f]",
  811.         tp->name, tp->display_level, tp->digits, tp->precision);
  812.  
  813.     while ((str = get_command(command1)) != NULL) {
  814.     if (startsame(str, "level")) {
  815.         (void) strcat(command1, " level:");
  816.         if ((str = get_command(command1)) != NULL) {
  817.         if (sscanf(str,"%d",&(tp->display_level)) == 0) {
  818.             return(put_error("Invalid disp level."));
  819.         }
  820.         }
  821.     }
  822.     else
  823.         if (startsame(str, "digits") || startsame(str,"#digits")) {
  824.         (void) strcat(command1, " digits:");
  825.         if ((str = get_command(command1)) != NULL) {
  826.             if (sscanf(str,"%d",&(tp->digits)) == 0) {
  827.                 return(put_error("Invalid digits."));
  828.             }
  829.         }
  830.         }
  831.     else
  832.         if (startsame(str, "scale")) {
  833.         (void) strcat(command1, " scale:");
  834.         if ((str = get_command(command1)) != NULL) {
  835.             if (sscanf(str,"%f",&(tp->precision)) == 0) {
  836.                 return(put_error("Invalid scale."));
  837.             }
  838.         }
  839.         }
  840.     else {
  841.         return(put_error("Unrecognized display option."));
  842.     }
  843.     return(CONTINUE);
  844.     }
  845. }
  846. /* used to print negative digits when standout mode is not set */
  847.  
  848. print_neg_digits(lval, dig)
  849. long    lval;
  850. int     dig;
  851. {
  852.     char    fmt[20];
  853.     char    dstr[10];
  854.     long    temp;
  855.     double  pow ();
  856.     char    *dlets = "oabcdefghiX";
  857.  
  858.     temp = (-lval);
  859.     if (dig == 1) {
  860.     if (temp > 9) {
  861.         io_printw("%1s", "X");
  862.     }
  863.     else {
  864.         io_printw("%c", dlets[temp]);
  865.     }
  866.     }
  867.     else
  868.     if (dig == 2) {
  869.         if (temp < 10) {
  870.             io_printw("%2ld", lval);
  871.         }
  872.         else if (temp > 99) {
  873.         io_printw("%2s", "XX");
  874.         }
  875.         else {
  876.         (void) sprintf(dstr,"%c%c", dlets[temp/10],dlets[temp%10]);
  877.         io_printw("%2s",dstr);
  878.         }
  879.     }
  880.     else
  881.     if (dig == 3) {
  882.         if (temp < 100) {
  883.             io_printw("%3ld",lval);
  884.         }
  885.         else if (temp > 999) {
  886.         io_printw("%3s", "XXX");
  887.         }
  888.         else {
  889.         (void) sprintf(dstr,
  890.             "%c%c%c", dlets[temp/100],dlets[(temp/10)%10],dlets[temp%10]);
  891.         io_printw("%3s",dstr);
  892.         }
  893.     }
  894.     else {
  895.     if ((double) temp > (double)(pow(10.0,(double) dig-1) - 1.0)) {
  896.         (void) sprintf(fmt, "%%%d.%ds", dig, dig);
  897.         io_printw(fmt, "XXXXXXXXXXX");
  898.     }
  899.     else {
  900.         (void) sprintf(fmt, "%%%dld", dig);
  901.         io_printw(fmt, lval);
  902.     }
  903.     }
  904. }
  905.  
  906. set_log() {
  907.     char   *str;
  908.     char string[BUFSIZ];
  909.  
  910.     str = get_command("file name (- to close log): ");
  911.     if (str == NULL ) {
  912.         return(put_error("no change made in logging status"));
  913.     }
  914.  
  915.     if(logflag) fclose(lfp);
  916.  
  917.     logflag = 0;
  918.     
  919.     if (*str == '-') {
  920.     return(CONTINUE);
  921.     }
  922.  
  923.     if ((lfp = fopen(str, "a")) == NULL) {
  924.     return(put_error(
  925.            "cannot open file for output -- logging not enabled"));
  926.     }
  927.     logflag = 1;
  928.     return(CONTINUE);
  929. }
  930.  
  931. save_screen() {
  932.     FILE *sfp;
  933.     char *str;
  934.     int c,l,rval;
  935.     char ch;
  936.     char sv_stout = 0;
  937.     
  938.     rval = CONTINUE;
  939.     
  940.     if (stand_out) sv_stout = 1;
  941.     
  942.     if (sv_stout) {
  943.         stand_out = 0;
  944.         update_display();
  945.     }    
  946.  
  947.     str = get_command("file name (return to abort): ");
  948.     if (str == NULL) goto finish_svscr;
  949.     
  950.     if ((sfp = fopen(str, "a")) == NULL) {
  951.     rval = put_error("cannot open file for screen dump");
  952.     goto finish_svscr;
  953.     }
  954.  
  955.     for (l = 0; l < num_lines; l++) {
  956.         for(c = 0; c < num_cols; c++) {
  957.        io_move(l,c);
  958.        ch = io_inch();
  959.        if (!ch) ch = ' ';
  960.        putc(ch,sfp);
  961.     }
  962.     putc('\n',sfp);
  963.     }
  964.     fclose(sfp);
  965.     
  966. finish_svscr:
  967.     if (sv_stout) {
  968.        stand_out = 1;
  969.        clear_display();
  970.        update_display();
  971.     }
  972.     return(rval);
  973. }
  974.