home *** CD-ROM | disk | FTP | other *** search
/ Best Objectech Shareware Selections / UNTITLED.iso / boss / word / text / 019 / screen.c < prev    next >
C/C++ Source or Header  |  1993-01-19  |  24KB  |  1,038 lines

  1. /*
  2.  *  Copyright (c) 1992 John E. Davis  (davis@amy.tch.harvard.edu)
  3.  *  All Rights Reserved.
  4.  */
  5. #define JED_VERSION "Jed <0.80> "
  6.  
  7. #include <stdio.h>
  8. #include <string.h>
  9. #ifndef msdos
  10. #ifndef VMS
  11. #include <malloc.h>
  12. #endif
  13. #else
  14. #include <alloc.h>
  15. #include <dos.h>
  16. extern int Cursor_Row;
  17. #endif
  18. #include "buffer.h"
  19. #include "screen.h"
  20. #include "window.h"
  21. #include "paste.h"
  22.  
  23. #include "ins.h"
  24. #include "ledit.h"
  25. #include "display.h"
  26. #include "sysdep.h"
  27. #include "misc.h"
  28. #include "vterm.h"
  29. #include "slang.h"
  30.  
  31. Screen_Type Screen[80];
  32.  
  33. int Screen_Row = 1;
  34. int Screen_Col = 1;
  35. int Cursor_Motion;    /* indicates cursor movement only */
  36. int Scroll_Region_1;
  37. int Scroll_Region_2;
  38. int Scroll_Lines;
  39.  
  40. int Goal_Column;
  41. int Display_Eight_Bit = 0;
  42.  
  43. void blank_line(int row)
  44. {
  45.     int i, n;
  46.     char *p;
  47.  
  48.     n = Window->width;
  49.     p = Screen[row].old;
  50.     i = 0;
  51.     while(i++ < n) *p++ = ' ';
  52.     *p = 0;
  53. }
  54.  
  55. void update_screen_txt(int row)
  56. {
  57.     char *tmp;
  58.     tmp = Screen[row].new;
  59.     Screen[row].new = Screen[row].old;
  60.     Screen[row].old = tmp;
  61. }
  62.  
  63. int output(unsigned char *line, int len, int row, int max_col)
  64. {
  65.    int i,ii, visible = 0, ok, quit, tabsize = 8, count, tab, mini_flag,
  66.      mark, ebit;
  67.    unsigned char ch, *out;
  68.  
  69.    out = (unsigned char *) Screen[row - 1].new;
  70.    tab = User_Vars.tab;
  71.    i = 0;
  72.    ii = 0;
  73.    quit = 0;
  74.    ok = 0;  /* 1 if ok to start filling the out line */
  75.  
  76.    count = 0;  /* count counts the visible space */
  77.  
  78.    /* deal with mini_buffer prompt */
  79.    if (IS_MINIBUFFER && Mini_Info.prompt_len)
  80.      {
  81.     if (Screen_Width < Mini_Info.prompt_len) 
  82.       {
  83.          len = 0; 
  84.          count = Screen_Width;
  85.       }
  86.     else count = Mini_Info.prompt_len;
  87.     mini_flag = 1;
  88.      }
  89.    else mini_flag = 0;
  90.  
  91.    while (ch = line[i], (i < len) && !quit)  /* && ch != '\n' */
  92.      {
  93.     ebit = 0;
  94.     if (tab && (ch == '\t'))
  95.       {
  96.          tabsize = tab * (count / tab + 1) - count;
  97.          count += tabsize;
  98.       }
  99.     else if ((ch < ' ') || (ch == 127)) count += 2;
  100.     else if (Display_Eight_Bit || (ch < 127)) count++;
  101.     else if (ch < 160) count += 3;
  102.     else if (ch < 255) count += 2;
  103.     else count += 3;
  104.  
  105.     if (count >= Window->column) ok = 1;
  106.     if (count > max_col) break;
  107.  
  108.     i++;
  109.     if (!ok) continue;
  110.  
  111.     if (mini_flag)
  112.       {
  113.          strncpy((char *) out, Mini_Info.prompt, Screen_Width);
  114.          out[Screen_Width] = 0;
  115.          visible += (Screen_Width > Mini_Info.prompt_len ? Mini_Info.prompt_len : Screen_Width);
  116.          ii = visible;
  117.          mini_flag = 0;
  118.       }
  119.  
  120.     if (!Display_Eight_Bit && (ch & 0x80))
  121.       {
  122.          out[ii++] = '~';
  123.          visible += 1;
  124.          ch = ch & 0x7F;
  125.          ebit = 1;
  126.       }
  127.  
  128.     if (!ebit && (ch == '\t') && tab)
  129.       {
  130.          while(tabsize--) out[ii++] = ' ';
  131.       }
  132.  
  133.     else if ((ch < ' ') || (ch == 127))
  134.       {
  135.          out[ii++] = '^';
  136.          if (ch == 127) out[ii++] = '?'; else out[ii++] = ch + 'A' - 1;
  137.          visible += 2;
  138.       }
  139.     else if (ch == ' ') out[ii++] = ' ';
  140.     else
  141.       {
  142.          out[ii++] = ch;
  143.          visible += 1;
  144.       }
  145.      }
  146.  
  147.    /* we have not inserted the prompt */
  148.    if (mini_flag && !len)
  149.      {
  150.     strncpy((char *) out, Mini_Info.prompt, Screen_Width);
  151.     out[Screen_Width] = 0;
  152.     ok = 1;
  153.     ii = visible = (Screen_Width > Mini_Info.prompt_len ? Mini_Info.prompt_len : Screen_Width);
  154.      }
  155.    mark = -1;
  156.    if (ok && count >= max_col)
  157.      {
  158.     out[ii - 1] = '$';
  159.     visible++;
  160.      }
  161.  
  162.    else
  163.      {
  164.     if (!ii)
  165.       {
  166.          out[ii++] = '$';
  167.          visible += 1;
  168.       }
  169.  
  170.     mark = ii;
  171.     while(ii < Window->width) out[ii++] = ' ';
  172.      }
  173.  
  174.    out[ii] = '\0';
  175.  
  176.    if (visible)
  177.      {
  178. #ifdef msdos
  179.     (void) mark;
  180.     smart_puts((char *) out,Screen[row-1].old, row);
  181. #else
  182.     if (mark != -1) out[mark] = 0;
  183.     smart_puts((char *)out,Screen[row-1].old, row);
  184.     if (mark != -1) out[mark] = ' ';
  185. #endif
  186.     Screen[row-1].n = visible;
  187.      }
  188.  
  189.    /* else take care of it in calling routine */
  190.    return(visible);
  191. }
  192.  
  193. void display_line(Line *line, int row)
  194. {
  195.     int len;
  196.  
  197.     if (line != NULL)
  198.       {
  199.           len = line->len;
  200.           if (len) if (line->data[len - 1] == '\n') len--;
  201.  
  202.           if ((len > 0) || (Window->column > 1)
  203.            || ((row == Screen_Height) && Mini_Info.prompt_len))
  204.             {
  205.            len = output(line->data, len, row, Window->column + Window->width - 1);
  206.             }
  207.       }
  208.     else len = 0;
  209.  
  210.     if (len <= 0)
  211.       {
  212.           if (Screen[row-1].n)
  213.             {
  214.                 goto_rc(row,1);
  215.                 tt_del_eol();
  216.             }
  217.           blank_line(row - 1);
  218.           Screen[row - 1].n = 0;
  219.       }
  220.     Screen[row - 1].line = line;
  221.     Screen[row - 1].flags = 0;
  222.     if (len > 0) update_screen_txt(row-1);
  223. }
  224.  
  225. void open_scroll(void)
  226. {
  227.     Scroll_Region_1 = 1;
  228.     Scroll_Region_2 = Screen_Height;
  229.     Scroll_Lines = 0;
  230. }
  231.  
  232. void do_scroll_up(int n)
  233. {
  234.     goto_rc(1,1);
  235.     tt_delete_nlines(n);
  236. }
  237.  
  238. void do_scroll_down(int n)
  239. {
  240.    goto_rc(1,1);
  241.    reverse_index(n);
  242. }
  243.  
  244. void execute_scroll(void)
  245. {
  246.    if (Scroll_Lines > 0)
  247.      {
  248.     set_scroll_region(Scroll_Region_1, Scroll_Region_2);
  249.     do_scroll_up(Scroll_Lines);
  250.      }
  251.    else if (Scroll_Lines < 0)
  252.      {
  253.     set_scroll_region(Scroll_Region_1, Scroll_Region_2);
  254.     do_scroll_down(-Scroll_Lines);
  255.      }
  256.    Scroll_Lines = 0;
  257. }
  258.  
  259. void queue_scroll(int n, int r1, int r2)
  260. {
  261.    if ((r1 != Scroll_Region_1) || (r2 != Scroll_Region_2))
  262.      {
  263.     if ((n == -1) && (Scroll_Region_1 == r1 + Scroll_Lines)
  264.            && (Scroll_Region_2 == r2))
  265.     Scroll_Lines--;
  266.     else
  267.       {
  268.          execute_scroll();
  269.          Scroll_Region_1 = r1;
  270.          Scroll_Region_2 = r2;
  271.          Scroll_Lines = n;
  272.       }
  273.      }
  274.    else Scroll_Lines += n;
  275. }
  276.  
  277. void close_scroll(void)
  278. {
  279.     if (Scroll_Lines) execute_scroll();
  280.     if ((Scroll_Region_1 != 1) | (Scroll_Region_2 != Screen_Height))
  281.       reset_scroll_region();
  282. }
  283.  
  284. /* Here a scrolling region (t,b) is used to scroll line t + n to t.  All
  285.    that is assumed is that  the line at t + n exists! */
  286.  
  287. int scroll_up(int n, int t, int b)
  288. {
  289.     int i, necess;
  290.  
  291.     if (n == 0) return(0);
  292.  
  293.     /* t = Window->top - 1 + t;
  294.        b = Window->top - 1 + b; */
  295.  
  296.     /* check to see if this is really necessary */
  297.     necess = 0;
  298.     for (i = t - 1; i < b; i++)
  299.       {
  300.           if (Screen[i].n)
  301.             {
  302.                 necess = 1;
  303.                 break;
  304.             }
  305.       }
  306.  
  307.     if (!necess) return(0);
  308.  
  309.     queue_scroll(n, t, b);
  310.  
  311.     vscroll_up(t,b,n);
  312.  
  313.     return(necess);
  314. }
  315.  
  316. /* Here a scrolling region (t,b) is used to scroll line t + n to t. */
  317.  
  318. void scroll_down(int n, int t, int b)
  319. {
  320.     if (n == 0) return;
  321.  
  322.     /* t = Window->top - 1 + t;
  323.        b = Window->top - 1 + b; */
  324.     set_scroll_region(t,b);
  325.     reverse_index(n);
  326.     reset_scroll_region();
  327.  
  328.     vscroll_down(t,b,n);
  329. }
  330.  
  331. int update_insert_line(int r1, Line *line)
  332. {
  333.     int i, r2, r, necess;
  334.     Line *bot;
  335.  
  336.     /* normalize r1: */
  337.     /* r1 = Window->top - 1 + r1; */
  338.  
  339.     /* find the first one that is blank to delimit the region so that the
  340.        loss will be minimal */
  341.  
  342.     r = r1;   /* not r1 + 1 as obvious (but naive) as it seems */
  343.     r2 = Window->rows + Window->top - 1;
  344.     while (r < r2)
  345.       {
  346.           if (Screen[r - 1].line == NULL) break;
  347.           r++;
  348.       }
  349.  
  350.     if ((r1 != r2) && (r == r2))
  351.     /* we may have failed so check the bottom up so we don't push linesoff. */
  352.      {
  353.     bot = line;
  354.     for (r = r1 + 1; r <= r2; r++)
  355.       {
  356.          bot = bot->next;
  357.          if (bot == NULL) break;
  358.          if (Screen[r-1].line == bot) break;
  359.       }
  360.     if ((bot != NULL) && (r <= r2)) r--;
  361.     if (r > r2) r = r2;
  362.      }
  363.    
  364.    if (r < r1) r = r1;
  365.    r2 = r;
  366.  
  367.     /* check to see if we gain by doing this */
  368.     necess = 0;
  369.     for (i = r1 - 1; i < r2; i++)
  370.       {
  371.           if (Screen[i].n)
  372.             {
  373.                 necess = 1;
  374.                 break;
  375.             }
  376.       }
  377.     if (r1 == r2) return(0);
  378.     if (!necess) return(0);
  379.  
  380.     queue_scroll(-1, r1, r2);
  381.  
  382.     vscroll_down(r1, r2, 1);
  383.     return(1);
  384. }
  385.  
  386. Line *find_top()
  387. {
  388.     int n, i;
  389.     Line *line, *next, *prev, *this;
  390.