home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume7 / rvi / part2 / rv_fetch.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-11-30  |  3.8 KB  |  173 lines

  1. #include "rv.h"
  2.  
  3.  
  4. void
  5. fetch_window(first, redraw_flag)
  6. /*
  7.  * Fetch a window starting at line 'first' in the file.
  8.  * Adjust current line if necessary
  9.  * Redraw screen
  10.  */
  11. INT first;
  12. boolean redraw_flag;    /* TRUE if redraw requested */
  13. {
  14.     register struct li_line   *line;
  15.     register struct sc_screen *sc;
  16.     register struct wi_window *wi;
  17.     char buf[512];
  18.     INT    last, i, j;
  19.     extern alarmring();
  20.  
  21.     sc = &screen;
  22.     wi = &window;
  23.  
  24.     xmit_curline();
  25.     /*
  26.      * Free old window's text
  27.      */
  28.     if (file.fi_numlines > 0)
  29.         for (line=wi->wi_topline; line <= wi->wi_botline; ++line)
  30.             if (line->li_text) {
  31.                 free(line->li_text);
  32.                 line->li_text = NULL;
  33.             }
  34.     
  35.     /*
  36.      * Set first/last lines
  37.      */
  38.     if (first < 1)
  39.         first = 1;
  40.     last = first + NUM_WINDOW_LINES-1;
  41.     if (last > file.fi_numlines)
  42.         last = file.fi_numlines;
  43.  
  44. retry:
  45.     /*
  46.      * Send request to ed
  47.      */
  48.     xmit_sync();
  49.     xmit_ed("$=\n");
  50.     xmit_ed("%d,%dp\n", first, last);
  51.  
  52.     (void) recv_sync(FALSE);
  53.     alarm(RV_TIMEOUT);
  54.     (void) fgets(buf, 511, file.fi_fpin);
  55.  
  56.     if ((i = atoi(buf)) == 0 && buf[0] != '0')
  57.         panic("$= request to ed failed\n\n");
  58.  
  59.     if (i <= 0) {
  60.         /*
  61.          * Deleted whole file
  62.          */
  63.         wi->wi_topline = &line_array[NUM_WINDOW_LINES/4];
  64.         wi->wi_botline = wi->wi_topline;
  65.         wi->wi_topline->li_text = xalloc(1);
  66.         wi->wi_topline->li_text[0] = '\0';
  67.         wi->wi_topline->li_segments = 1;
  68.         wi->wi_topline->li_width = 0;
  69.         sc->sc_curline = wi->wi_topline;
  70.         sc->sc_lineno = 1;
  71.         sc->sc_column = 0;
  72.         sc->sc_abovetop = 0;
  73.         sc->sc_topline = sc->sc_botline = sc->sc_curline;
  74.         file.fi_numlines = 1;
  75.         alarm(0);
  76.         redraw_screen((struct li_line *)0);
  77.         xmit_ed("0a\n\n.\n");
  78.         return;
  79.     }
  80.  
  81.     file.fi_numlines = i;
  82.     if (last > i) {
  83.         /*
  84.          * The file shrunk below our requested window size.
  85.          * Probably due to a .,$d command.
  86.          *
  87.          * Shift the window towards the top of whatever
  88.          * text is left.
  89.          */
  90.         last = i;
  91.         first = last - (NUM_WINDOW_LINES+1);
  92.         if (first < 1)
  93.             first = 1;
  94.         goto retry;
  95.     }
  96.     /*
  97.      * See if file grew and window can be extended
  98.      */
  99.     j = first + NUM_WINDOW_LINES-1;
  100.     if (j > file.fi_numlines)
  101.         j = file.fi_numlines;
  102.     if (j != last) {
  103.         last = j;
  104.         goto retry;
  105.     }
  106.  
  107.     /*
  108.      * Read in window lines
  109.      */
  110.     line = &line_array[0];
  111.     for (i=first; i <= last; ++i, ++line) {
  112.         if (fgets(buf, 511, file.fi_fpin) == NULL)
  113.             panic("Error during input from ed\n\n");
  114.         /*
  115.          * Strip trailing \n
  116.          */
  117.         if ((j = strlen(buf)) > 0 && buf[j-1] == '\n')
  118.             buf[--j] = '\0';
  119.         line->li_text = xalloc(j+1);
  120.         strcpy(line->li_text, buf);
  121.         line->li_width = j;
  122.         line->li_segments = 1 + (screen_column(buf, j-1)+set_list)/COLS;
  123.     }
  124.     alarm(0);
  125.  
  126.     wi->wi_topline = &line_array[0];
  127.     wi->wi_botline = line-1;
  128.     sc->sc_abovetop = 0;
  129.     if (sc->sc_lineno >= first && sc->sc_lineno <= last) {
  130.         /*
  131.          * Case 1 - Current line is still in window
  132.          *          Calculate curline, topline
  133.          */
  134.         line = wi->wi_topline + (sc->sc_lineno - first);
  135.         i = sc->sc_curline - sc->sc_topline;
  136.         if (sc->sc_lineno - i < first)
  137.             sc->sc_topline = wi->wi_topline;
  138.         else
  139.             sc->sc_topline = line - i;
  140.         sc->sc_curline = line;
  141.     } else {
  142.         /*
  143.          * Case 2 - Current line outside window
  144.          *          Choose new current line, topline
  145.          */
  146.         line = wi->wi_topline + NUM_WINDOW_LINES/4 + LINES/2 - 1;
  147.         if (line > wi->wi_botline)
  148.             line = wi->wi_botline;
  149.         sc->sc_topline = line - (LINES/2 - 1);
  150.         if (sc->sc_topline < wi->wi_topline ||
  151.             sc->sc_topline > wi->wi_botline)
  152.             sc->sc_topline = wi->wi_topline;
  153.         sc->sc_lineno = first + (line - wi->wi_topline);
  154.         sc->sc_curline = line;
  155.     }
  156.  
  157.     if (redraw_flag) { /* If redraw requested */
  158.         redraw_screen((struct li_line *)0);
  159.         move_cursor(sc->sc_lineno, COL_FIRST_NONWHITE);
  160.     } else {
  161.         /*
  162.          * Compute bottom line
  163.          */
  164.         line = sc->sc_topline;
  165.         for (j = line->li_segments; j < LINES; j += line->li_segments) {
  166.             ++line;
  167.             if (line > wi->wi_botline)
  168.                 break;
  169.         }
  170.         sc->sc_botline = line-1;
  171.     }
  172. }
  173.