home *** CD-ROM | disk | FTP | other *** search
/ pc.louisiana.edu/pub/unix/ / Louisiana_UNIX.tar / Louisiana_UNIX / xspread3.0.zoo / screen.c.dist < prev    next >
Text File  |  1994-03-25  |  23KB  |  925 lines

  1. /*    SC    A Spreadsheet Calculator
  2.  *        Curses based Screen driver
  3.  *
  4.  *        original by James Gosling, September 1982
  5.  *        modifications by Mark Weiser and Bruce Israel,
  6.  *            University of Maryland
  7.  *
  8.  *              More mods Robert Bond, 12/86
  9.  *        More mods by Alan Silverstein, 3-4/88, see list of changes.
  10.  *        More mods by Peter Doemel, 2/93: static prvstring in update
  11.  *        Currently supported by gator!sawmill!buhrt (Jeff Buhrt)
  12.  *        $Revision: 6.21 A $
  13.  *
  14.  */
  15.  
  16. #include "config.h"
  17.  
  18. #ifdef DOINGX
  19. #include <stdio.h>
  20. #include <X11/Xlib.h>
  21. #include <X11/Xutil.h>
  22. #else
  23. #include <curses.h>
  24. #endif
  25. #include "sc.h"
  26. #ifdef DOINGX
  27. #include "scXstuff.h"
  28. #else
  29. #ifdef TIOCGWINSZ
  30. #include <sys/types.h>
  31. #include <sys/stream.h>
  32. #ifndef QENAB    /* this works for AT&T SvsV R3.2 */
  33. #include <sys/ptem.h>
  34. #endif
  35. #endif
  36. #endif
  37.  
  38. #ifdef VMS
  39. extern int VMS_read_raw;   /*sigh*/
  40.     VMS_read_raw = 1;
  41. #endif
  42.  
  43. #ifdef BROKENCURSES
  44.         /* nl/nonl bug fix */
  45. #undef nl
  46. #undef nonl
  47. #define nl()     (_tty.sg_flags |= CRMOD,_pfast = _rawmode,stty(_tty_ch, &_tty))
  48. #define nonl()     (_tty.sg_flags &= ~CRMOD, _pfast = TRUE, stty(_tty_ch, &_tty))
  49. #endif
  50.  
  51. char    under_cursor = ' '; /* Data under the < cursor */
  52. char    mode_ind = '.';
  53. extern    char    revmsg[];
  54.  
  55. int prvmx, prvmy, prvcol;   /* line added by Bob Parbs 12-92 */
  56.  
  57. int    rows, lcols;
  58. int    lastmx, lastmy;    /* Screen address of the cursor */
  59. int    lastcol;    /* Spreadsheet Column the cursor was in last */
  60. extern    int *fwidth;
  61. extern    int showrange;    /* Causes ranges to be highlighted    */
  62. extern    int showneed;    /* Causes cells needing values to be highlighted */
  63. extern    int showexpr;    /* Causes cell exprs to be displayed, highlighted */
  64. extern    int showcursor;    /* Causes arrow cursor to be displayed, highlighted */
  65. #ifdef RIGHT_CBUG
  66. extern    int wasforw;    /* Causes screen to be redisplay if on lastcol */
  67. #endif
  68.  
  69. int called = 0;
  70. /*
  71.  * update() does general screen update
  72.  *
  73.  * standout last time in update()?
  74.  *    At this point we will let curses do work
  75.  */
  76. int    standlast    = FALSE;
  77.  
  78. void
  79. update (anychanged)
  80. int    anychanged;    /* did any cell really change in value? */
  81. {
  82.     register    row, col;
  83.     register struct ent **pp;
  84.     int    mxrow, mxcol;
  85.     int    minsr = 0, minsc = 0, maxsr = 0, maxsc = 0;
  86.     register r;
  87.     register i;
  88.     static    int    lastcurcol = -1, lastcurrow = -1;
  89. #if 0    /* this was the original code of xspread 2.1 */
  90.     char field[FBUFLEN]; /*moved by B.P. 12-92 */
  91.     char prvstring[FBUFLEN];
  92. #else    /* the modified (better working) code looks like this:
  93.      * (Peter Doemel, 10-Feb-1993)
  94.      */
  95.     static char field[FBUFLEN], prvstring[FBUFLEN];
  96. #endif
  97.     /*
  98.      * place the cursor on the screen, set col, curcol, stcol, lastcol as
  99.      * needed
  100.      */
  101. if ((curcol != lastcurcol) || FullUpdate)
  102.     {
  103.     while (col_hidden[curcol])   /* You can't hide the last row or col */
  104.         curcol++;
  105.  
  106.     /* First see if the last display still covers curcol */
  107.     if (stcol <= curcol){
  108.         for (i = stcol, lcols = 0, col = RESCOL;
  109.               (col + fwidth[i]) < maintextcols-1 && i < maxcols; i++) {
  110.             lcols++;
  111.  
  112.             if (col_hidden[i])
  113.                 continue;
  114.             col += fwidth[i];
  115.         }
  116.     }
  117.     while (stcol + lcols - 1 < curcol || curcol < stcol) {
  118.         FullUpdate++;
  119.         if (stcol - 1 == curcol) {    /* How about back one? */
  120.             stcol--;
  121.         } else if (stcol + lcols == curcol) {   /* Forward one? */
  122.             stcol++;
  123.         } else {
  124.             /* Try to put the cursor in the center of the screen */
  125.             col = (maintextcols - RESCOL - fwidth[curcol]) / 2 + RESCOL; 
  126.             stcol = curcol;
  127.             for (i=curcol-1; i >= 0 && col-fwidth[i] > RESCOL; i--)
  128.             {    stcol--;
  129.                 if (col_hidden[i])
  130.                     continue;
  131.                 col -= fwidth[i];
  132.             }
  133.         }
  134.         /* Now pick up the counts again */
  135.         for (i = stcol, lcols = 0,col = RESCOL;
  136.             (col + fwidth[i]) < maintextcols-1 && i < maxcols; i++) {
  137.             lcols++;
  138.             if (col_hidden[i])
  139.                 continue;
  140.             col += fwidth[i];
  141.         }
  142.     }
  143.     lastcurcol = curcol;
  144.     }
  145.  
  146.     /* Now - same process on the rows as the columns */
  147.     if ((currow != lastcurrow) || FullUpdate)
  148.     {
  149.     while (row_hidden[currow])   /* You can't hide the last row or col */
  150.         currow++;
  151.     if (strow <= currow){
  152.         for (i = strow, rows = 0, row=RESROW; row<maintextrows && i<maxrows; i++)
  153.         {    rows++;
  154.             if (row_hidden[i])
  155.                 continue;
  156.             row++;
  157.         }
  158.     }
  159.  
  160.     while (strow + rows - 1 < currow || currow < strow) {
  161.         FullUpdate++;
  162.         if (strow - 1 == currow) {    /* How about up one? */
  163.             strow--;
  164.         } else if (strow + rows == currow) {   /* Down one? */
  165.             strow++;
  166.         } else {
  167.             /* Try to put the cursor in the center of the screen */
  168.             row = (maintextrows - RESROW) / 2 + RESROW; 
  169.             strow = currow;
  170.             for (i=currow-1; i >= 0 && row-1 > RESROW; i--) {
  171.                 strow--;
  172.                 if (row_hidden[i])
  173.                     continue;
  174.                 row--;
  175.             }
  176.         }
  177.         /* Now pick up the counts again */
  178.         for (i = strow, rows = 0, row=RESROW; row<maintextrows && i<maxrows; i++) {
  179.             rows++;
  180.             if (row_hidden[i])
  181.                 continue;
  182.             row++;
  183.         }
  184.     }
  185.     lastcurrow = currow;
  186.     }
  187.     mxcol = stcol + lcols - 1;
  188.     mxrow = strow + rows - 1;
  189.  
  190.     /* Get rid of cursor standout on the cell at previous cursor position */
  191. #ifdef DOINGX
  192. #if 0    /* this was the original code of xspread 2.1: */
  193. /* FIXME*/
  194. /* following statement modified by Bob Parbs 12-92 */
  195.     if (showcell && !FullUpdate)
  196.     XDrawImageString(dpy, mainwin, maingc,
  197.                  textcol(prvmx), textrow(prvmy),
  198.                  prvstring, strlen(prvstring) );
  199.  
  200. /* following statement modified by Bob Parbs 12-92 */
  201.  
  202.     if (showcell && !FullUpdate)
  203.     XFillRectangle(dpy, mainwin, invertgc, textcol(prvmx),
  204.                (textrow(prvmy-1)+4),
  205.                textcol(fwidth[prvcol]),textrow(0));
  206.     
  207.  
  208. #else    /* I think the following code looks clearer:
  209.      * (Peter Doemel, 10-Feb-1993)
  210.      */
  211.     if (showcell && !FullUpdate) {
  212.     XDrawImageString(dpy, mainwin, maingc,
  213.                  textcol(prvmx), textrow(prvmy),
  214.                  prvstring, strlen(prvstring) );
  215.     XFillRectangle(dpy, mainwin, invertgc, textcol(prvmx),
  216.                (textrow(prvmy-1)+4),
  217.                textcol(fwidth[prvcol]),textrow(0));
  218.     }
  219. #endif
  220. #else
  221.     if (!FullUpdate)
  222.     {    if (showcell)
  223.         repaint(lastmx, lastmy, fwidth[lastcol]);
  224.  
  225.     (void) move(lastmy, lastmx+fwidth[lastcol]);
  226.  
  227.     if ((inch() & A_CHARTEXT ) == '<')
  228.         (void) addch(under_cursor);
  229.     }
  230. #endif
  231.  
  232.     /* where is the the cursor now? */
  233.     lastmy =  RESROW;
  234.     for (row = strow; row < currow; row++)
  235.     if (!row_hidden[row])
  236.         lastmy++;
  237.  
  238.     lastmx = RESCOL;
  239.     for (col = stcol; col < curcol; col++)
  240.     if (!col_hidden[col])
  241.         lastmx += fwidth[col];
  242.     lastcol = curcol;
  243.  
  244.     /* relabel the rows and columns if a full update is performed */
  245.     if (FullUpdate || standlast) {
  246. #ifdef DOINGX
  247.         cleardownfrom(2);
  248. #else
  249.     (void) move(2, 0);
  250.     (void) clrtobot();
  251.     (void) standout();
  252. #endif
  253.  
  254.     for (row=RESROW, i=strow; i <= mxrow; i++) {
  255.         if (row_hidden[i]) 
  256.             continue;
  257. #ifdef DOINGX
  258.         if (maxrows < 1000)
  259.             sprintf(stringbuf, "%-*d", RESCOL-1, i);
  260.         else
  261.             sprintf(stringbuf, "%-*d", RESCOL, i);
  262.         XDrawImageString(dpy, mainwin, maingcreversed,
  263.             textcol(0), textrow(row),
  264.             stringbuf, strlen(stringbuf) );
  265. #else
  266.         (void) move(row,0);
  267.         if (maxrows < 1000)
  268.             (void) printw("%-*d", RESCOL-1, i);
  269.         else
  270.             (void) printw("%-*d", RESCOL, i);
  271. #endif
  272.         row++;
  273.     }
  274. #ifdef DOINGX
  275.         /* the following will work as long as RESCOL<20.  It is 
  276.      * more efficient than the usual sprintf(stringbuf..) and
  277.      * XDrawString(...strlen(stringbuf)) combination
  278.      */
  279.         XDrawImageString(dpy,mainwin,maingcreversed,
  280.              textcol(0),textrow(3),
  281.              "                    ",RESCOL);
  282. #else
  283. #ifdef RIGHT_CBUG
  284.     if(wasforw) {
  285.         clearok(stdscr, TRUE);
  286.         wasforw = 0;
  287.     }
  288. #endif
  289.     (void) move(RESCOL-1, 0);
  290.     (void) printw("%*s", RESCOL, " ");
  291. #endif    /* DOINGX */
  292.     for (col=RESCOL, i = stcol; i <= mxcol; i++) {
  293.         register int k;
  294.         if (col_hidden[i])
  295.         continue;
  296. #ifndef DOINGX                          /* ifn added by Bob Parbs 12-92 */
  297.         (void) move(RESCOL-1, col);
  298. #endif
  299.         k = fwidth[i]/2;
  300. #ifdef DOINGX
  301.         if (k == 0)
  302.               sprintf(stringbuf,"%1s", coltoa(i));
  303.         else
  304.               sprintf(stringbuf,"%*s%-*s", k, " ", fwidth[i]-k, coltoa(i));
  305.             XDrawImageString(dpy,mainwin,maingcreversed,
  306.                              textcol(col), textrow(3),
  307.                              stringbuf, strlen(stringbuf) );
  308. #else
  309.         if (k == 0)
  310.         (void) printw("%1s", coltoa(i));
  311.         else
  312.             (void) printw("%*s%-*s", k, " ", fwidth[i]-k, coltoa(i));
  313. #endif
  314.         col += fwidth[i];
  315.     }
  316. #ifndef DOINGX
  317.     (void) standend();
  318. #endif
  319.     }
  320.  
  321.     if (showrange) {
  322.     minsr = showsr < currow ? showsr : currow;
  323.     minsc = showsc < curcol ? showsc : curcol;
  324.     maxsr = showsr > currow ? showsr : currow;
  325.     maxsc = showsc > curcol ? showsc : curcol;
  326.  
  327.     if (showtop) {
  328. #ifdef DOINGX
  329.         sprintf(stringbuf,"Default range:  %s",
  330.                 r_name(minsr, minsc, maxsr, maxsc)); 
  331.             XDrawImageString(dpy,mainwin,maingc,
  332.                              textcol(0), textrow(1),
  333.                              stringbuf, strlen(stringbuf) );
  334. #else
  335.         (void) move(1,0);
  336.         (void) clrtoeol();
  337.         (void) printw("Default range:  %s",
  338.                 r_name(minsr, minsc, maxsr, maxsc));
  339. #endif
  340.     }
  341.     }
  342.  
  343. #ifdef FIXME
  344.     /* if the current cell was previously painted over by laststring, we
  345.      * don't need to look it up again, unless it has changed.  So, we can 
  346.      * say we have the cursor accounted for */
  347.     if ((row == currow) && (lstringstart <= curcol) && (lstringend >= curcol))
  348.     {    found_cursor = 1;
  349.     }
  350. #endif
  351.  
  352.     /* Repaint the visible screen */
  353.     if (showrange || anychanged || FullUpdate || standlast)
  354.     {
  355.     /* may be reset in loop, if not next time we will do a FullUpdate */
  356.       if (standlast)
  357.       {    FullUpdate = TRUE;
  358.     standlast = FALSE;
  359.       }
  360.  
  361.       for (row = strow, r = RESROW; row <= mxrow; row++) {
  362.     register c = RESCOL;
  363.     int do_stand = 0;
  364.     int fieldlen;
  365.     int nextcol;
  366.  
  367.     if (row_hidden[row])
  368.         continue;
  369.     for (pp = ATBL(tbl, row, col = stcol); col <= mxcol;
  370.              pp += nextcol - col,  col = nextcol, c += fieldlen) {
  371.  
  372.         nextcol = col+1;
  373.         if (col_hidden[col]) {
  374.         fieldlen = 0;
  375.         continue;
  376.         }
  377.  
  378. #ifdef FIXME
  379.         /*
  380.          * if we are on the cursor row, and we have not accounted for the
  381.          * cursor, look at contents of all cells, in order to get correct
  382.          * laststring
  383.          */
  384.         if ((row == currow) && !found_cursor)
  385.         get_value = 1;
  386. #endif
  387.  
  388.         fieldlen = fwidth[col];
  389.  
  390.         /*
  391.          * Set standout if:
  392.          *
  393.          * - showing ranges, and not showing cells which need to be filled
  394.          *     in, and not showing cell expressions, and in a range, OR
  395.          *
  396.          * - if showing cells which need to be filled in and this one is
  397.          *     of that type (has a value and doesn't have an expression,
  398.          *     or it is a string expression), OR
  399.          *
  400.          * - if showing cells which have expressions and this one does.
  401.          */
  402.         if ((showrange && (! showneed) && (! showexpr)
  403.                && (row >= minsr) && (row <= maxsr)
  404.                && (col >= minsc) && (col <= maxsc))
  405.             || (showneed && (*pp) && ((*pp) -> flags & is_valid) &&
  406.               (((*pp) -> flags & is_strexpr) || !((*pp) -> expr)))
  407.             || (showexpr && (*pp) && ((*pp) -> expr)))
  408.         {
  409. #ifndef DOINGX
  410.         (void) move(r, c);
  411.         (void) standout();
  412. #endif
  413.         standlast++;
  414.         if (!*pp)    /* no cell, but standing out */
  415.         {
  416. #ifdef DOINGX
  417.             sprintf(stringbuf, "%*s", fwidth[col], " ");
  418.             XDrawImageString(dpy, mainwin, maingcreversed,
  419.                      textcol(c), textrow(r),
  420.                      stringbuf, strlen(stringbuf) );
  421. #else
  422.             (void) printw("%*s", fwidth[col], " ");
  423.             (void) standend();
  424. #endif
  425.             continue;
  426.         }
  427.         else
  428.             do_stand = 1;
  429.         }
  430.         else
  431.         do_stand = 0;
  432.  
  433.         if ((*pp) && (((*pp) -> flags & is_changed || FullUpdate) || do_stand)) {
  434.         if (do_stand) {
  435.             (*pp) -> flags |= is_changed; 
  436.         } else {
  437. #ifndef DOINGX
  438.             (void) move(r, c);
  439. #endif
  440.             (*pp) -> flags &= ~is_changed;
  441.         }
  442.  
  443.         /*
  444.          * Show expression; takes priority over other displays:
  445.          */
  446.  
  447.         if ((*pp)->cellerror) {
  448. #ifdef DOINGX
  449.             sprintf(stringbuf, "%*.*s", fwidth[col], fwidth[col],
  450.               (*pp)->cellerror == CELLERROR ? "ERROR" : "INVALID");
  451.             XDrawImageString(dpy,mainwin,
  452.                     do_stand ? maingcreversed : maingc,
  453.                     textcol(c),textrow(r),
  454.                     stringbuf, strlen(stringbuf));
  455.  
  456. #else
  457.             (void) printw("%*.*s", fwidth[col], fwidth[col],
  458.               (*pp)->cellerror == CELLERROR ? "ERROR" : "INVALID");
  459. #endif
  460.         }
  461.         else
  462.         if (showexpr && ((*pp) -> expr)) {
  463.             linelim = 0;
  464.             editexp(row, col);        /* set line to expr */
  465.             linelim = -1;
  466.             showstring(line, /* leftflush = */ 1, /* hasvalue = */ 0,
  467.                 row, col, & nextcol, mxcol, & fieldlen, r, c);
  468.         } else {
  469.             /*
  470.              * Show cell's numeric value:
  471.                      */
  472.  
  473.             if ((*pp) -> flags & is_valid) {
  474.             /*char field[FBUFLEN]; moved to top fnctn B.P. */
  475.  
  476.             if ((*pp) -> format) {
  477.                 (void) format((*pp) -> format, (*pp) -> v,
  478.                          field, sizeof(field));
  479.             } else {
  480.                 (void) engformat(realfmt[col], fwidth[col], 
  481.                                              precision[col], (*pp) -> v, 
  482.                                              field, sizeof(field));
  483.             }
  484.                         if (strlen(field) > fwidth[col]) {
  485.                 for(i = 0; i<fwidth[col]; i++)
  486. #ifdef DOINGX
  487.                     field[i] = '*';
  488.                 field[fwidth[col]] = '\0';
  489.  
  490. /* following statement to print case of field too long Bob Parbs 12-92 */
  491.  
  492.                                XDrawImageString(dpy,mainwin,
  493.                                   do_stand ? maingcreversed : maingc,
  494.                                   textcol(c + fwidth[col] - strlen(field)),
  495.                                   textrow(r), field, strlen(field));
  496. #else
  497.                     (void)addch('*');
  498. #endif
  499.             } else {
  500. #ifdef DOINGX
  501.                 XDrawImageString(dpy,mainwin,
  502.                     do_stand ? maingcreversed : maingc,
  503.                     textcol(c + fwidth[col] - strlen(field)),
  504.                     textrow(r), field, strlen(field));
  505. #if 0    /* this was the original code of xspread 2.1 */
  506.                                     *prvstring = *field;
  507. #else    /* I'm not sure what the intention was for this, but I think
  508.      * the following looks safer: (Peter Doemel, 10-Feb-1993)
  509.      */
  510.                     strncpy( prvstring, field, FBUFLEN);
  511. #endif
  512. #else
  513.                 for(i = 0; i < fwidth[col] - strlen(field);i++)
  514.                     (void)addch(' ');
  515.                 (void)addstr(field);
  516. #endif
  517.             }
  518.             }
  519.  
  520.             /*
  521.              * Show cell's label string:
  522.              */
  523.  
  524.             if ((*pp) -> label) {
  525.             showstring((*pp) -> label,
  526.                     (*pp) -> flags & (is_leftflush|is_label),
  527.                     (*pp) -> flags & is_valid,
  528.                     row, col, & nextcol, mxcol,
  529.                     & fieldlen, r, c);
  530.             }
  531.             else    /* repaint a blank cell: */
  532.             if ((do_stand || !FullUpdate) &&
  533.                 ((*pp)->flags & is_changed) &&
  534.                 !((*pp)->flags & is_valid) && !(*pp)->label) {
  535. #ifdef DOINGX
  536.             sprintf (stringbuf, "%*s", fwidth[col], " ");
  537.             XDrawImageString(dpy,mainwin,
  538.                     do_stand ? maingcreversed : maingc,
  539.                     textcol(c),textrow(r),
  540.                     stringbuf, strlen(stringbuf));
  541. #else
  542.             (void) printw("%*s", fwidth[col], " ");
  543. #endif
  544.             }
  545.         } /* else */
  546.  
  547.         if (do_stand) {
  548. #ifndef DOINGX
  549.             (void) standend();
  550. #endif
  551.             do_stand = 0;
  552.         }
  553.         }
  554.     }
  555.     r++;
  556.       }
  557.     }
  558. #ifdef DOINGX
  559. called++;
  560.  
  561. /* next two statements commented out by Bob Parbs 12-92 */
  562.  
  563. /*sprintf(stringbuf,"tc1 %d, tr1 %d, tc2 %d, tr2 %d (%d, %d), called %d",
  564.     textcol(lastmx), textrow(lastmy),
  565.     textcol(lastmx+fwidth[lastcol]), textrow(lastmy+1),
  566.     textcol(fwidth[lastcol]), textrow(1), called);*/
  567. /*XDrawImageString(dpy, mainwin, maingc,
  568.     textcol(0), textrow(5), stringbuf, strlen(stringbuf));*/
  569.  
  570. /* following statement modified by Bob Parbs to fix cursor position, size 12-92 */
  571.  
  572. if (called){
  573.     XFillRectangle(dpy,mainwin, invertgc, textcol(lastmx),
  574.                (textrow(lastmy-1)+4),
  575.                textcol(fwidth[lastcol]), textrow(0));
  576. /*               textcol(lastmx+fwidth[lastcol]), curfontheight);*/
  577. /*               textrow(lastmy+1));*/
  578.  
  579.         prvmx = lastmx;   /* three statements added by Bob Parbs 12-92 */
  580.         prvmy = lastmy;   /* to prevent screen write if no cursor      */
  581.         *prvstring = '\0';/* movement but other command executed.      */
  582.            }
  583.  
  584. #else
  585.     /* place 'cursor marker' */
  586.     if (showcell && (! showneed) && (! showexpr)) {
  587.     (void) move(lastmy, lastmx);
  588.         (void) standout();
  589.         repaint(lastmx, lastmy, fwidth[lastcol]);
  590.         (void) standend();
  591.     }
  592.     (void) move(lastmy, lastmx+fwidth[lastcol]);
  593.     under_cursor = (inch() & A_CHARTEXT);
  594.     if ( showcursor )
  595.     (void) addch('<');
  596. #endif
  597.     (void) show_top_line();
  598.  
  599.     FullUpdate = FALSE;
  600. }
  601.  
  602. #ifndef DOINGX
  603. /* redraw what is under the cursor from curses' idea of the screen */
  604. void
  605. repaint(x, y, len)
  606. int x, y, len;
  607. {
  608.     int c;
  609.  
  610.     while(len-- > 0) {
  611.     (void) move(y, x);
  612.     c = inch() & A_CHARTEXT;
  613.     (void) addch(c);
  614.     x++;
  615.     }
  616. }
  617. #endif
  618.  
  619. int seenerr;
  620.  
  621. /* error routine for yacc (gram.y) */
  622. void
  623. yyerror(err)
  624. char *err; {
  625.     if (seenerr) return;
  626.     seenerr++;
  627.  
  628.     clearlines(1,1);
  629. #ifdef DOINGX
  630.     sprintf(stringbuf,"%s: %.*s<=%s",err,linelim,line,line+linelim);
  631.     XDrawImageString(dpy, mainwin, maingc,
  632.              textcol(0), textrow(1), stringbuf, strlen(stringbuf));
  633.     XFlush(dpy);
  634. #else
  635.     (void) printw("%s: %.*s<=%s",err,linelim,line,line+linelim);
  636. #endif
  637. }
  638.  
  639. #ifdef XENIX2_3
  640. struct termio tmio;
  641. #endif
  642.  
  643. #ifndef DOINGX
  644. void
  645. startdisp()
  646. {
  647. #if sun
  648.     int     fd;
  649.     fd = dup(0);
  650. #endif
  651.  
  652. #ifdef TIOCGSIZE
  653.     {    struct ttysize size;
  654.     if (ioctl(0, TIOCGSIZE, &size) == 0)
  655.     {     maintextrows = LINES = size.ts_lines;
  656.         maintextcols = COLS = size.ts_cols;
  657.     }
  658.     }
  659. #endif
  660.  
  661. #if defined(TIOCGWINSZ) && !defined(SYSV3)
  662. {
  663.     struct    winsize w;
  664.  
  665.     if(ioctl(0, TIOCGWINSZ, &w) == 0)
  666.     {    maintextrows = LINES = w.ws_row;
  667.         maintextcols = COLS  = w.ws_col;
  668.     }
  669. }
  670. #endif
  671.  
  672. #ifdef XENIX2_3
  673.     (void) ioctl (fileno (stdin), TCGETA, & tmio);
  674. #endif
  675.     (void) initscr();
  676. #if sun
  677.     close(0);
  678.     dup(fd);
  679.     close(fd);
  680. #endif
  681.     (void) clear();
  682. #ifdef VMS
  683.     VMS_read_raw = 1;
  684. #else
  685.     nonl();
  686.     noecho ();
  687.     cbreak();
  688. #endif
  689.     initkbd();
  690.     scrollok(stdscr, 1);
  691.  
  692. #if defined(SYSV3) && !defined(NOIDLOK)
  693. # ifndef IDLOKBAD
  694.     /*
  695.      * turn hardware insert/delete on, if possible.
  696.      * turn on scrolling for systems with SYSVr3.{1,2} (SYSVr3.0 has this set
  697.      * as the default)
  698.      */
  699.      idlok(stdscr,TRUE);
  700. # else    /*
  701.      * This seems to fix (with an empty spreadsheet):
  702.      *    a) Redrawing the bottom half of the screen when you
  703.      *        move between row 9 <-> 10
  704.      *    b) the highlighted row labels being trash when you
  705.      *        move between row 9 <-> 10
  706.      *    c) On an xterm on Esix Rev. D+ from eating lines
  707.      *     -goto (or move) a few lines (or more) past the bottom
  708.      *     of the screen, goto (or move) to the top line on the
  709.      *     screen, move upward and the current line is deleted, the
  710.      *     others move up even when they should not, check by
  711.      *     noticing the rows become 2, 3, 40, 41, 42... (etc).
  712.      */
  713.      idlok(stdscr,FALSE);
  714. # endif
  715. #endif
  716.  
  717.     FullUpdate++;
  718. }
  719. #endif
  720.  
  721. void
  722. stopdisp()
  723. {
  724. #ifndef DOINGX
  725.     deraw();
  726.     resetkbd();
  727.     endwin();
  728. #ifdef XENIX2_3
  729.     (void) ioctl (fileno (stdin), TCSETAW, & tmio);
  730. #endif
  731. #endif
  732. }
  733.  
  734. /* init curses */
  735. #ifdef VMS
  736.  
  737. goraw()
  738. {
  739.     VMS_read_raw = 1;
  740.     FullUpdate++;
  741. }
  742.  
  743. deraw()
  744. {
  745. #ifndef DOINGX
  746.     (void) move (maintextrows - 1, 0);
  747.     (void) clrtoeol();
  748.     (void) refresh();
  749. #endif
  750.     VMS_read_raw = 0;
  751. }
  752.  
  753. #else /* VMS */
  754.  
  755. #ifndef DOINGX
  756. void
  757. goraw()
  758. {
  759. #if SYSV2 || SYSV3
  760.     fixterm();
  761. #else /* SYSV2 || SYSV3 */
  762.     cbreak();
  763.     nonl();
  764.     noecho ();
  765. #endif /* SYSV2 || SYSV3 */
  766.     kbd_again();
  767.     (void) clear();
  768.     FullUpdate++;
  769. }
  770.  
  771. /* clean up curses */
  772. void
  773. deraw()
  774. {
  775.     (void) move (maintextrows - 1, 0);
  776.     (void) clrtoeol();
  777.     (void) refresh();
  778. #if SYSV2 || SYSV3
  779.     resetterm();
  780. #else
  781.     nocbreak();
  782.     nl();
  783.     echo();
  784. #endif
  785.     resetkbd();
  786. }
  787. #endif /* !DOINGX */
  788. #endif /* VMS */
  789.  
  790. void
  791. show_top_line()
  792. {   
  793.     clearlines(0,0);
  794.  
  795.     stringbuf[0] = '\0';
  796.     if (linelim >= 0) {
  797.     sprintf(stringbuf,"%c> %s_", mode_ind, line);
  798. #ifndef DOINGX
  799.     (void) addstr(stringbuf);
  800. (void) move((linelim + 3) / maintextcols, (linelim+3) % maintextcols);
  801. #endif
  802.     }
  803.     else
  804.     if (showtop) {            /* show top line */
  805.         register struct ent *p1;
  806.         int printed = 0;        /* printed something? */
  807.         
  808.             /* show the current cell's format */
  809.         if ((p1 = *ATBL(tbl, currow, curcol)) && p1->format)
  810.         sprintf(stringbuf, "%s%d (%s) ", coltoa(curcol), currow,
  811.             p1->format);
  812.         else
  813.         sprintf(stringbuf, "%s%d (%d %d %d) ", coltoa(curcol), currow,
  814.             fwidth[curcol], precision[curcol], realfmt[curcol]);
  815.  
  816.         if (p1) {
  817.         if (p1 -> expr) {
  818.             /* has expr of some type */
  819.             linelim = 0;
  820.             editexp(currow, curcol);    /* set line to expr */
  821.             linelim = -1;
  822.         }
  823.  
  824.         /*
  825.          * Display string part of cell:
  826.          */
  827.  
  828.         if ((p1 -> expr) && (p1 -> flags & is_strexpr)) {
  829.              if( (p1-> flags & is_label) )
  830.             strcat(stringbuf, "|{");
  831.             else
  832.             strcat(stringbuf, ((p1 -> flags & is_leftflush) ? "<{" : ">{"));
  833.             strcat(stringbuf, line);
  834.             strcat(stringbuf, "} ");    /* and this '}' is for vi % */
  835.             printed = 1;
  836.  
  837.         } else if (p1 -> label) {
  838.             /* has constant label only */
  839.             if( (p1-> flags & is_label) )
  840.             strcat(stringbuf, "|\"");
  841.             else
  842.             strcat(stringbuf, (p1 -> flags & is_leftflush) ? "<\"" : ">\"");
  843.             strcat(stringbuf, p1 -> label);
  844.             strcat(stringbuf, "\" ");
  845.             printed = 1;
  846.         }
  847.  
  848.         /*
  849.          * Display value part of cell:
  850.          */
  851.  
  852.         if (p1 -> flags & is_valid) {
  853.             /* has value or num expr */
  854.             if ((! (p1 -> expr)) || (p1 -> flags & is_strexpr))
  855.             (void) sprintf (line, "%.15g", p1 -> v);
  856.  
  857.             strcat(stringbuf, "[");
  858.             strcat(stringbuf, line);
  859.             strcat(stringbuf, "]");
  860.             *line = '\0'; /* this is the input buffer ! */
  861.             printed = 1;
  862.         }
  863.         }
  864.         if (! printed)
  865.         strcat(stringbuf, "[]");
  866.         /* Display if cell is locked */
  867.         if (p1 && p1->flags&is_locked)
  868.         strcat(stringbuf, " locked");
  869. #ifndef DOINGX
  870.         addstr(stringbuf);
  871.     (void) move(lastmy, lastmx+fwidth[lastcol] + (showcursor ? 0 : -1 ));
  872. #endif
  873.     }
  874. #ifdef DOINGX
  875.     XDrawImageString(dpy, mainwin, maingc,
  876.          textcol(0), textrow(0), stringbuf, strlen(stringbuf));
  877. #endif
  878.  
  879.     if (revmsg[0]) {
  880.     clearlines(0,0);
  881. #ifdef DOINGX
  882.     XDrawImageString(dpy,mainwin,maingc,
  883.              textcol(0), textrow(0),
  884.              revmsg, strlen(revmsg));
  885. #else
  886.     (void) printw(revmsg);
  887. (void) move (lastmy, lastmx + fwidth[lastcol] + (showcursor ? 0 : -1));
  888. #endif
  889.     *revmsg = '\0';        /* don't show it again */
  890.     }
  891. #ifndef DOINGX
  892.     refresh();
  893. #endif
  894.     FullUpdate = 0;
  895. }
  896.  
  897. /*
  898.  * function clearlines() clears the lines start through end, given in text
  899.  * coordinates
  900.  */
  901. void
  902. clearlines(start, end)
  903. int start, end;
  904. {
  905.     int temp; /* swap variable */
  906.     if (start>end)  
  907.     {
  908.         temp = end;
  909.         end = start;
  910.         start = temp;
  911.     }
  912. #ifdef DOINGX
  913.     XClearArea(dpy,mainwin,
  914.          0,textrow(start) - curfontheight + 3,          /*top left corner of area */
  915.          0,                             /* 0 width => full window width*/
  916.          textrow(end) - textrow(start) + curfontheight  + 1,/* height of area */
  917.          0);                            /* don't send Expose events */
  918. #else
  919.     for(; start <= end; start++)
  920.     {    (void) move(0, start);
  921.         (void) clrtoeol ();    /* get rid of topline display */
  922.     }
  923. #endif
  924. }
  925.