home *** CD-ROM | disk | FTP | other *** search
/ Usenet 1994 January / usenetsourcesnewsgroupsinfomagicjanuary1994.iso / sources / unix / volume26 / most-3.2 / part02 / window.c < prev   
Encoding:
C/C++ Source or Header  |  1993-04-13  |  17.9 KB  |  805 lines

  1. #include <stdio.h>
  2. #include "externs.h"
  3. #include "window.h"
  4. #include "line.h"
  5. #include "display.h"
  6.  
  7. Window *WIN;
  8. Window *TOP_WIN;
  9. int COLUMN = 1;
  10. int BEEP_MINI_B = 0;
  11. int MINIBUFFER_SELECTED = 0;
  12. int CURS_ROW;
  13. int CURS_COL;
  14. int RESTORE_WIDTH_TO = 0;
  15. unsigned char *CURS_POS;
  16.  
  17. int read_string(char *str)
  18. {
  19.     char ch;
  20.     int i;
  21.  
  22.     i = strlen(str);
  23.     do 
  24.       {
  25.           ch = getkey();
  26.           if ((ch == '\b') || (ch == 127))
  27.             {
  28.                 if (i > 0)
  29.                   {
  30.                       if (str[--i] < 32) fputs("\b \b",stdout); /* erase the ^ */
  31.                       fputs("\b \b",stdout);
  32.                   }
  33.                 else fputc('\007',stdout);
  34.             }
  35.           else if ((ch < 32) && (ch != 10) && (ch != 13))
  36.             {
  37.         if ((ch == '\007') || (ch == '\025')) /* ^G or ^U aborts */
  38.            {
  39.               fputc('\007',stdout);
  40.               return(-1);    /* ^G quits */
  41.            }
  42.         if (ch == '\033')  /* Allow KP ENTER as a terminator */
  43.            {
  44.               ch = getkey();
  45.               if (ch == 'O')
  46.              {
  47.                 ch = getkey();
  48.                 if (ch == 'M')
  49.                    {
  50.                   str[i] = '\0';
  51.                   return(i);
  52.                    }
  53.                 else
  54.                    {
  55.                    fputc('^',stdout);
  56.                    fputc('[',stdout);
  57.                    fputc(str[i++] = 'O', stdout);
  58.                    fputc(str[i++] = ch, stdout);
  59.                    }
  60.              }
  61.               else
  62.              {
  63.                 fputc('^',stdout);
  64.                 fputc('[',stdout);
  65.                 fputc(str[i++] = ch, stdout);
  66.              }
  67.            }
  68.         else
  69.            {
  70.               str[i++] = ch;
  71.               fputc('^',stdout);
  72.               fputc(ch + '@',stdout);
  73.            }
  74.             }
  75.           else if (ch == '`')   /* quoted insert */
  76.             {
  77.                 ch = getkey();
  78.                 str[i++] = ch;
  79.                 if ((ch < ' ') || (ch == 127)) 
  80.                   {
  81.                       if (ch == 127) ch = '?'; else ch = ch + '@';
  82.                       fputc('^',stdout);
  83.                   }
  84.                 fputc(ch,stdout);
  85.             }
  86.       else if ((ch != 10) && (ch != 13))
  87.             {
  88.                 str[i++] = ch;
  89.                 fputc(ch,stdout);
  90.             }
  91.           
  92.           fflush(stdout);
  93.       }
  94.     while ((ch != 10) && (ch != 13));
  95.       
  96.     str[i] = '\0';
  97.     return(i);
  98. }
  99.  
  100.  
  101. void message(char *what, int how)
  102. {
  103.     strcpy(MINI_BUF,what);
  104.     if (how) BEEP_MINI_B = 1; else BEEP_MINI_B = 0;
  105. }
  106.  
  107. void select_minibuffer()
  108. {
  109.     if (MINIBUFFER_SELECTED) return;
  110.     MINIBUFFER_SELECTED = 1;
  111.     set_scroll_region(1,SCREEN_HEIGHT);
  112.     goto_rc(SCREEN_HEIGHT,1);
  113.     fflush(stdout);
  114. }
  115.  
  116. void exit_minibuffer()
  117. {
  118.     if (!MINIBUFFER_SELECTED) return;
  119.     MINIBUFFER_SELECTED = 0;
  120.     set_scroll_region(WIN->top,WIN->bot);
  121.     fflush(stdout);
  122. }
  123.  
  124. /* put out string, expanding control chars */
  125. void nicely_puts(char *str, FILE *fp)
  126. {
  127.     while (*str != '\0')
  128.       {
  129.           if ((*str < ' ') || (*str == 127))
  130.             {
  131.                 fputc('^',fp);
  132.                 if (*str != 127) fputc(*str + '@',fp); else fputc('?',fp);
  133.             }
  134.           else fputc(*str,fp);
  135.           str++;
  136.       }
  137. }
  138.  
  139. void put_message()
  140. {
  141.     select_minibuffer();
  142.     delete_line(1);
  143.     if (BEEP_MINI_B) fputc('\007',stdout);
  144.     BEEP_MINI_B = 0;
  145.     if (*MINI_BUF != '\0') nicely_puts((char *) MINI_BUF, stdout);
  146.     exit_minibuffer();
  147. }
  148.  
  149. /* puts 'what in the minibuffer to be edited. */
  150. /* returns number of chars read */
  151. int read_from_minibuffer(char *prompt, char *what)
  152. {
  153.     int i;
  154.     char str[132];
  155.     
  156.     select_minibuffer();
  157.     fputs(prompt,stdout);
  158.     if (*what != '\0')
  159.       nicely_puts(what,stdout);
  160.     fflush(stdout);
  161.     strcpy(str,what);
  162.     i = read_string(str);
  163.     if (i > 0) strcpy(what,str);
  164.     delete_line(1);
  165.     exit_minibuffer();
  166.     return(i);
  167. }
  168.  
  169.     
  170. void clear_minibuffer()
  171. {
  172.     MINI_BUF[0] = '\0';
  173.     BEEP_MINI_B = 0;
  174.     put_message();
  175. }
  176.  
  177.  
  178. int get_scroll(int *line)
  179. {
  180.     /* line is the line we want at the topo of the window if possible */
  181.     int dtop, dbot,n,top,bot,wsize;
  182.  
  183.     top = WIN->beg_line;
  184.     wsize = WIN->bot - WIN->top; /* actually 1 less than window size */
  185.     bot = top + wsize;
  186.  
  187.     if ((*line == 1) && (top == 1))
  188.       {
  189.           message("Top of Buffer.",1);
  190.           return(0);
  191.       }
  192.     
  193.     /* handles endof file in a window */
  194.     if ((bot > NUM_LINES) && *line > C_LINE)
  195.       {
  196.           *line = top;
  197.           message("End of Buffer.",1);
  198.           return(0);
  199.       }
  200.     
  201.     if (NUM_LINES <= wsize)     /* short file */
  202.       {
  203.           *line = 1;
  204.           return(0);
  205.       }
  206.  
  207.     dtop = top - 1;
  208.     dbot = NUM_LINES - bot;
  209.     n = *line - top;
  210.  
  211.     if ((n>0) && (dbot < n))
  212.       {
  213.           n = dbot;
  214.           *line = top + n;
  215.           if (!n) message("End of buffer.",1);
  216.       }
  217.     else if ((n < 0) && (dtop + n < 0))
  218.       {
  219.           n = -dtop;
  220.           if (!n) message("Top of buffer.",1);
  221.           *line = n + top;
  222.       }
  223.     return(n);
  224. }
  225.  
  226.  
  227. void update_window(int line)
  228. {
  229.     int n,max_n, save_line, save_col, npos;
  230.     unsigned char *save_pos;
  231.  
  232.     if (COLUMN != WIN->col)
  233.       {
  234.           if (COLUMN < 1) COLUMN = 1;
  235.           if (COLUMN != WIN->col)
  236.             {
  237.                 save_pos = CURS_POS; save_line = CURS_ROW; save_col = CURS_COL;
  238.                 redraw_window();
  239.                 update_status(0);
  240.                 WIN->curs_pos = CURS_POS = save_pos;
  241.                 WIN->curs_line = CURS_ROW = save_line;
  242.                 WIN->curs_col = CURS_COL = save_col;
  243.             }
  244.           return;
  245.       }
  246.  
  247.     
  248.     n = get_scroll(&line);
  249.     max_n = WIN->bot - WIN->top;
  250.     if (abs(n) > max_n)
  251.       {
  252.           goto_line(line);
  253.           redraw_window();
  254.           update_status(0);
  255.           return;
  256.       }
  257.     if (!n) return;
  258.  
  259.     goto_rc(1,1);
  260.     forward_line(n);
  261.     WIN->beg_pos = C_POS;
  262.     WIN->beg_line = C_LINE;
  263.  
  264.     if (n>0)
  265.       {
  266.           npos = 1;
  267.           delete_nlines(n);
  268.           goto_rc(WIN->bot - WIN->top - n + 2,1);
  269.           forward_line(max_n - n + 1);
  270.       }
  271.     else
  272.       {
  273.           npos = 0;
  274.           CURS_ROW = 1; CURS_COL = 1; CURS_POS = C_POS;
  275.           n = -n;
  276.           reverse_index(n);
  277.       }
  278.     n = n - 1;
  279.     display_line();
  280.     while(n--)
  281.       {
  282.           forward_line(1);
  283.           fputc('\n',stdout);
  284.           display_line();
  285.       }
  286.     if (npos) 
  287.       {
  288.           
  289.           CURS_ROW = C_LINE - WIN->beg_line + 1;
  290.           CURS_COL = 1; CURS_POS = C_POS;
  291.       }
  292.     
  293.     C_POS = WIN->beg_pos;
  294.     C_LINE = WIN->beg_line;
  295.     update_status(0);
  296.     fflush(stdout);
  297. }
  298.  
  299. /* updates current window as well as scroll lock ones */
  300. /* Although current window is update in an absolute fashion, scroll locked
  301.    ones are updated in a relative fashion */
  302. void update_windows(int line)
  303. {
  304.     int dline,flg;
  305.     Window *w;
  306.     
  307.     dline = line - C_LINE;
  308.     update_window(line);
  309.     if (!WIN->lock) return;
  310.     flg = 0;
  311.     w = WIN;
  312.     while(WIN = WIN->next, WIN != w)
  313.       {
  314.           if (WIN->lock)
  315.             {
  316.                 flg = 1;
  317.                 set_window(WIN);
  318.                 line = C_LINE + dline;
  319.                 update_window(line);
  320.             }
  321.       }
  322.     WIN = w;
  323.     if (flg) set_window(WIN);
  324. }
  325.  
  326.  
  327. void redraw_window()
  328. {
  329.     int n,t;
  330.     t = WIN->top;
  331.     if (t == 1) clear_window();
  332.     goto_rc(1, 1);
  333.     n = WIN->bot - WIN->top;
  334.     if ((C_LINE + n) > NUM_LINES) goto_line(NUM_LINES - n);
  335.     WIN->curs_pos = CURS_POS = WIN->beg_pos = C_POS;
  336.     WIN->beg_line = C_LINE;
  337.     WIN->col = COLUMN;
  338.     WIN->curs_col = CURS_COL = 1;
  339.     WIN->curs_line = CURS_ROW = 1;
  340.     if (t != 1) delete_line(1);
  341.     display_line();
  342.     while(n--)
  343.       {
  344.           fputc('\n',stdout);
  345.           if (t != 1) delete_line(1);
  346.           if (forward_line(1)) display_line();
  347.       }
  348.     
  349.         
  350.     C_POS = WIN->beg_pos;
  351.     C_LINE = WIN->beg_line;
  352. }
  353.  
  354. /* associates current window with current buffer */
  355. void save_win_flags(Window *w)
  356. {
  357.     w->flags = 0;
  358.     if (MOST_V_OPT) w->flags |= _MOST_V_OPT;
  359.     if (MOST_B_OPT) w->flags |= _MOST_B_OPT;
  360.     if (MOST_T_OPT) w->flags |= _MOST_T_OPT;
  361.     if (MOST_W_OPT) w->flags |= _MOST_W_OPT;
  362.     if (SQUEEZE_LINES) w->flags |= _MOST_SQ_OPT;
  363.     w->n_lines = NUM_LINES;
  364.     w->display = MOST_S_OPT;
  365. }
  366.  
  367. void window_buffer()
  368. {
  369.     WIN->beg_line = C_LINE;
  370.     WIN->beg_pos = C_POS;
  371.     WIN->col = COLUMN;
  372.     WIN->buf = BUF;
  373.     MOST_S_OPT = 0;
  374.     save_win_flags(WIN);
  375. }
  376.  
  377. void clear_window()
  378. {
  379.     int i,n;
  380.     i = WIN->top;
  381.     n = WIN->bot - WIN->top;
  382.     if (i == 1)
  383.       {
  384.           goto_rc(WIN->bot - WIN->top + 1,SCREEN_WIDTH);
  385.           clr_bos();
  386.       }
  387.     else
  388.       {
  389.           goto_rc(i - WIN->top + 1,1);
  390.           delete_line(1);
  391.           while(n--)
  392.             {
  393.                 fputc('\n',stdout);
  394.                 delete_line(1);
  395.             }
  396.       }
  397.     
  398.     goto_rc(i - WIN->top + 1,1);
  399.     fflush(stdout);
  400. }
  401.  
  402. void restore_win_flags()
  403. {
  404.     MOST_V_OPT = WIN->flags & _MOST_V_OPT;
  405.     MOST_B_OPT = WIN->flags & _MOST_B_OPT;
  406.     MOST_T_OPT = WIN->flags & _MOST_T_OPT;
  407.     MOST_W_OPT = WIN->flags & _MOST_W_OPT;
  408.     SQUEEZE_LINES = WIN->flags & _MOST_SQ_OPT;
  409.     NUM_LINES = WIN->n_lines;
  410.     MOST_S_OPT = WIN->display;
  411. }
  412.  
  413.  
  414. Window *make_window(int r1,int r2)
  415. {
  416.     int i;
  417.     Window *new;
  418.     new = (Window *) malloc(sizeof(Window));
  419.     new->status = (char *) malloc(135);
  420.     for (i = 0; i <= SCREEN_WIDTH; i++) new->status[i] = '\0';
  421.     new->col = COLUMN;
  422.     new->top = r1;
  423.     new->bot = r2;
  424.     new->lock = 0;
  425.     save_win_flags(new);
  426.     return(new);
  427. }
  428.  
  429. void init_display()
  430. {
  431.     int i;
  432.     fputs("\033[?6h",stdout);
  433.     TOP_WIN = WIN = make_window(1,SCREEN_HEIGHT - 2);
  434.     WIN->prev = WIN->next = WIN;
  435.     cls();
  436.     set_scroll_region(WIN->top, WIN->bot);
  437.     goto_rc(1,1);
  438.     fflush(stdout);
  439. }
  440.  
  441. void reset_display()
  442. {
  443.     set_scroll_region(1,SCREEN_HEIGHT);
  444.     fputs("\033[?6l",stdout);   /* normal origin mode */
  445.     goto_rc(SCREEN_HEIGHT,1);
  446.     if (RESTORE_WIDTH_TO)
  447.       {
  448.           set_width(RESTORE_WIDTH_TO, 0);
  449.           RESTORE_WIDTH_TO = 0;
  450.       }
  451.     
  452.     fflush(stdout);
  453. }
  454.  
  455. update_status1(int new_status)
  456. {
  457.     char str[30], ch, *strp;
  458.     static char new[135];
  459.     int i,ii,r,x,line_p = 60;
  460.  
  461.     r = WIN->bot + 1;
  462.     goto_rc(r,1);
  463.  
  464.     i = ii = 0;
  465.     new[ii++] = '-';
  466.     if (WIN->lock) new[ii++] = '*'; else new[ii++] = '-';
  467.     strp = " MOST: ";
  468.     while(*strp != '\0') new[ii++] = *strp++;
  469.     
  470.     while(ch = WIN->buf->file[i++], ch != '\0') new[ii++] = ch;
  471.  
  472.     while(ii < line_p) new[ii++] = ' ';
  473.  
  474.     x = (C_LINE + WIN->bot - WIN->top) * 100; x = x / NUM_LINES;
  475.  
  476.     /* for files with end of file above the bottom row (due to window manipulations) */
  477.     if (x > 100) x = 100;
  478.     sprintf(str,"(%d,%d) %d%%",C_LINE,COLUMN,x);
  479.     i = 0; while(ch = str[i++], ch != '\0') new[ii++] = ch;
  480.  
  481.     while(ii < SCREEN_WIDTH) new[ii++] = '-';
  482.     new[SCREEN_WIDTH] = '\0';
  483.     set_attribute(7);
  484.     if (new_status)
  485.       fputs(new,stdout);
  486.     else
  487.       smart_puts(new,WIN->status,stdout);
  488.     set_attribute(0);
  489.     strcpy(WIN->status,new);
  490. }
  491.  
  492. void update_status(int new_status)
  493. {
  494.  
  495.     C_LINE = WIN->beg_line;
  496.     C_POS = WIN->beg_pos;
  497.     set_scroll_region(1,SCREEN_HEIGHT);
  498.     update_status1(new_status);
  499.     set_scroll_region(WIN->top,WIN->bot);
  500.     fflush(stdout);
  501. }
  502.  
  503. /* splits window-- no screen update, does not affect scrolling region */
  504. int split_window()
  505. {
  506.     Window *new, *old;
  507.     int b2,t2,b1, line;
  508.  
  509.     b2 = WIN->bot;
  510.     b1 = (WIN->bot + WIN->top) / 2 - 1;
  511.     t2 = b1 + 2;
  512.     if ((b1 == WIN->top) || (t2 == b2)) return(0);
  513.  
  514.     /* line is top line of new window. */
  515.     line = WIN->beg_line + t2 - WIN->top;
  516.     old = WIN;
  517.     WIN->bot = b1;
  518.     new = make_window(t2,b2);
  519.     /* add to ring */
  520.     WIN->next->prev = new;
  521.     new->next = WIN->next;
  522.     new->prev = WIN;
  523.     WIN->next = new;
  524.  
  525.     new->beg_line = line;
  526.     new->buf = BUF;
  527.     /* new window status line is at same position as old */
  528.     strcpy(new->status,WIN->status);
  529.     return(1);
  530. }
  531.  
  532.     
  533. void two_windows()
  534. {
  535.     int line;
  536.     Window *new, *old;
  537.     if (!split_window()) return;
  538.  
  539.     old = WIN;
  540.     new = WIN->next;
  541.     line = new->beg_line;
  542.     if (line + new->bot - new->top > NUM_LINES)
  543.       {
  544.           other_window(1);
  545.           /* since split window left new window undefined... */
  546.           C_POS = old->beg_pos;
  547.           C_LINE = old->beg_line;
  548.           if (NUM_LINES <= new->bot - new->top + 1)
  549.             {
  550.                 C_LINE = new->beg_line = 1;
  551.                 C_POS = new->beg_pos = BUF->beg;
  552.                 redraw_window();
  553.                 update_status(0);
  554.             }
  555.           else if (line > NUM_LINES)
  556.             {
  557.                 goto_line(NUM_LINES - new->bot + new->top);
  558.                 WIN->beg_pos = C_POS;
  559.                 WIN->beg_line = C_LINE;
  560.                 redraw_window();
  561.                 update_status(0);
  562.             }    
  563.           else
  564.             {
  565.                 goto_line(line);
  566.                 WIN->beg_pos = C_POS;
  567.                 WIN->beg_line = C_LINE;
  568.                 update_window(NUM_LINES - new->bot + new->top);
  569.             }
  570.           WIN->curs_line = 1;
  571.           WIN->curs_col = COLUMN;
  572.           WIN->curs_pos = C_POS;
  573.           other_window(-1);
  574.       }
  575.     else
  576.       {
  577.           WIN = new;
  578.           (void) forward_line(line - old->beg_line);
  579.           new->beg_pos = C_POS;
  580.           new->beg_line = C_LINE;
  581.           new->curs_line = 1;
  582.           new->curs_col = COLUMN;
  583.           new->curs_pos = C_POS;
  584.           update_status(0);
  585.           WIN = old;
  586.       }    
  587.     update_status(1);
  588. }
  589.  
  590. void expand_window1(int dn)
  591. {
  592.     int l, save_top, save_line;
  593.     unsigned char *save_pos;
  594.  
  595.     /* l is line after last line of current window (where status line is) */
  596.     l = WIN->beg_line + WIN->bot - WIN->top + 1;
  597.     save_top = WIN->top;
  598.     WIN->top = WIN->bot + 1;
  599.     WIN->bot = WIN->bot + dn;
  600.     set_scroll_region(WIN->top, WIN->bot);
  601.     if (l > NUM_LINES)
  602.       {
  603.           clear_window();
  604.       }
  605.     else
  606.       {
  607.           /* should add something here for smarter scrolling...
  608.              if ((WIN->next->BUF == BUF) && (l >= WIN->next->beg_line)
  609.              && (l <= (WIN->next->beg_line + WIN->next)
  610.              */
  611.                 
  612.           save_line = C_LINE;
  613.           save_pos = C_POS;
  614.           goto_line(l);
  615.           redraw_window();
  616.           WIN->beg_line = C_LINE = save_line;
  617.           WIN->beg_pos = C_POS = save_pos;
  618.       }
  619.     WIN->top = save_top;
  620.     set_scroll_region(WIN->top, WIN->bot);
  621. }
  622.  
  623. void one_window()
  624. {
  625.     Window *w, *tmp;
  626.     int diff;
  627.     
  628.     if (WIN->next == WIN) return;
  629.     w = WIN;
  630.     WIN = WIN->next;
  631.     /* delete other windows preserving the ring! */
  632.     while(WIN != w)
  633.       {
  634.           free_window_buffer(); /* needs a ring */
  635.           tmp = WIN->next;
  636.           /* if this is the bottom window, save its status line */
  637.           if (tmp == TOP_WIN) strcpy(w->status,WIN->status);
  638.           tmp->prev = WIN->prev;
  639.           WIN->prev->next = tmp;
  640.           free(WIN);
  641.           WIN = tmp;
  642.       }
  643.     WIN = w;
  644.     /* slide the window to the top and expand it */
  645.     diff = WIN->top - 1;
  646.     if (diff)
  647.       {
  648.           set_scroll_region(1,SCREEN_HEIGHT - 2);
  649.           goto_rc(1,1);
  650.           delete_nlines(diff);
  651.           WIN->top = 1;
  652.           WIN->bot -=  diff;
  653.           TOP_WIN = WIN;
  654.       }
  655.     expand_window1(SCREEN_HEIGHT - 2 - WIN->bot);
  656.     update_status(0);
  657. }
  658.  
  659.           
  660. void set_window(Window *w)
  661. {
  662.     WIN = w;
  663.     CURS_ROW = WIN->curs_line;
  664.     CURS_COL = WIN->curs_col;
  665.     CURS_POS = WIN->curs_pos;
  666.     C_LINE = WIN->beg_line;
  667.     C_POS = WIN->beg_pos;
  668.     COLUMN = WIN->col;
  669.     BUF = WIN->buf;
  670.     switch_to_buffer(BUF);
  671.     set_scroll_region(WIN->top,WIN->bot);
  672.     restore_win_flags();
  673.     fflush(stdout);
  674. }
  675.  
  676. void other_window(int n)
  677. {
  678.     if (!n) return;
  679.     WIN->beg_pos = C_POS;
  680.     WIN->curs_pos = CURS_POS;
  681.     WIN->curs_line = CURS_ROW;
  682.     WIN->curs_col = CURS_COL;
  683.     WIN->beg_line = C_LINE;
  684.     save_win_flags(WIN);
  685.     if (n < 0)
  686.       while (n++) WIN = WIN->prev;
  687.     else
  688.       while (n--) WIN = WIN->next;
  689.     set_window(WIN);
  690. }
  691.  
  692.  
  693.  
  694. /* kills window by moving lower window up */
  695. delete_as_top_window()
  696. {
  697.     int t1,t2,b1,b2;
  698.     t1 = WIN->top;
  699.     t2 = WIN->next->top;
  700.     b1 = WIN->bot;
  701.     b2 = WIN->next->bot;
  702.     WIN->prev->next = WIN->next;
  703.     WIN->next->prev = WIN->prev;
  704.  
  705.     /* scroll contents of window below to top */
  706.     set_scroll_region(t1,b2);
  707.     goto_rc(1,1);
  708.     delete_nlines(t2 - t1);
  709.     other_window(1);
  710.     WIN->top = t1;
  711.     WIN->bot = b2 - t2 + t1;
  712.     expand_window1(b2 - WIN->bot);
  713.     update_status(0);
  714. }
  715.  
  716. /* free buffer for this window if no other windows are viewing it. */
  717. free_window_buffer()
  718. {
  719.     Window *w;
  720.     int f = 1;
  721.     w = WIN;
  722.     WIN = w->next;
  723.     while((WIN != w) && f)
  724.       {
  725.           if (!strcmp(WIN->buf->file,w->buf->file)) f = 0;
  726.           WIN = WIN->next;
  727.       }
  728.     WIN = w;
  729.     if (f) free(WIN->buf);
  730. }
  731.  
  732.  
  733. delete_window()
  734. {
  735.     int new_b, old_b;
  736.     Window *w;
  737.     
  738.     w = WIN;
  739.     if (WIN->next == WIN) return;
  740.     free_window_buffer();
  741.     if (WIN->next != TOP_WIN)
  742.       {
  743.           if (WIN == TOP_WIN)
  744.             {
  745.                 delete_as_top_window();
  746.                 TOP_WIN = WIN;  /* not anymore, this one is */
  747.             }
  748.           else
  749.             delete_as_top_window();
  750.           
  751.           free(w);
  752.           return;
  753.       }
  754.     old_b = WIN->top - 2;
  755.     new_b = WIN->bot;
  756.     other_window(-1);
  757.     expand_window1(new_b - old_b);
  758.     strcpy(WIN->status,w->status); /* share the same line */
  759.     
  760.     WIN->next = w->next;
  761.     WIN->next->prev = WIN;
  762.     free(w);
  763.     update_status(0);
  764. }
  765.  
  766. void redraw_display()
  767. {
  768.     Window *w;
  769.     int n,t;
  770.     fputs("\033[?6h",stdout);   /* relative origins */
  771.     set_scroll_region(1,SCREEN_HEIGHT);
  772.     cls();
  773.     save_win_flags(WIN);
  774.     w = WIN;
  775.     do
  776.       {
  777.           WIN = WIN->next;
  778.           t = WIN->top;
  779.           goto_rc(t, 1);
  780.           C_POS = WIN->beg_pos;
  781.           C_LINE = WIN->beg_line;
  782.           COLUMN = WIN->col;
  783.           switch_to_buffer(WIN->buf);
  784.           restore_win_flags();
  785.           n = WIN->bot - WIN->top;
  786.           display_line();
  787.           while(n--)
  788.             {
  789.                 fputc('\n',stdout);
  790.                 if (forward_line(1)) display_line();
  791.             }
  792.           C_LINE = WIN->beg_line;
  793.           C_POS = WIN->beg_pos;
  794.           update_status1(1);
  795.       }
  796.     while(WIN != w);
  797.     set_window(w);
  798. }
  799.  
  800. void toggle_lock()
  801. {
  802.     WIN->lock = !(WIN->lock);
  803.     update_status(0);
  804. }
  805.