home *** CD-ROM | disk | FTP | other *** search
/ Fresh Fish 8 / FreshFishVol8-CD1.bin / gnu / src / baseline / jove-4.14.6.lha / jove-4.14.6 / screen.c < prev    next >
C/C++ Source or Header  |  1992-01-10  |  22KB  |  1,099 lines

  1. /***************************************************************************
  2.  * This program is Copyright (C) 1986, 1987, 1988 by Jonathan Payne.  JOVE *
  3.  * is provided to you without charge, and with no warranty.  You may give  *
  4.  * away copies of JOVE, including sources, provided that this notice is    *
  5.  * included in all the files.                                              *
  6.  ***************************************************************************/
  7.  
  8. #include "jove.h"
  9. #include "fp.h"
  10. #include "ctype.h"
  11. #include "termcap.h"
  12. #include "disp.h"
  13. #include <signal.h>
  14.  
  15. #ifdef MSDOS
  16. #define SIGHUP 99
  17. #endif
  18.  
  19. int    AbortCnt,
  20.     tabstop = 8;
  21. bool
  22.     CanScroll = NO;
  23.  
  24. #ifdef    TERMCAP
  25. private void
  26.     (*TTins_line) proto((int, int, int)),
  27.     (*TTdel_line) proto((int, int, int));
  28. #endif    /* TERMCAP */
  29.  
  30. struct scrimage
  31.     *DesiredScreen = NULL,
  32.     *PhysScreen = NULL;
  33.  
  34. struct screenline    *Screen = NULL,    /* the screen (a bunch of screenline) */
  35.             *Curline = NULL;    /* current line */
  36.  
  37. private struct screenline   *Savelines = NULL;    /* another bunch (LI of them) */
  38.  
  39.  
  40. private char    *cursor;            /* offset into current Line */
  41.  
  42. char    *cursend;
  43.  
  44. int    CapCol,
  45.     CapLine,
  46.  
  47.     i_line,
  48.     i_col;
  49.  
  50. #ifdef    IBMPC
  51. extern unsigned char    CHPL;
  52. extern void        near normfun(),
  53.             near scr_win(),
  54.             near clr_page(),
  55.             near clr_eoln();
  56.  
  57. #endif
  58.  
  59. void
  60. make_scr()
  61. {
  62.     register int    i;
  63.     register struct screenline    *ns;
  64.     register char    *nsp;
  65.  
  66.     /* In case we are RESHAPING the window! */
  67.     if (DesiredScreen != NULL)
  68.         free((UnivPtr) DesiredScreen);
  69.     if (PhysScreen != NULL)
  70.         free((UnivPtr) PhysScreen);
  71.     if (Savelines != NULL)
  72.         free((UnivPtr) Savelines);
  73.     if (Screen != NULL) {
  74.         free((UnivPtr) Screen->s_line);    /* free all the screen data */
  75.         free((UnivPtr) Screen);
  76.     }
  77.  
  78.     DesiredScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage));
  79.     PhysScreen = (struct scrimage *) malloc((unsigned) LI * sizeof (struct scrimage));
  80.  
  81.     Savelines = (struct screenline *)
  82.             malloc((unsigned) LI * sizeof(struct screenline));
  83.     ns = Screen = (struct screenline *)
  84.             malloc((unsigned) LI * sizeof(struct screenline));
  85.  
  86.     nsp = (char *) malloc((unsigned)CO * LI);
  87.  
  88.     if (DesiredScreen == NULL
  89.     || PhysScreen == NULL
  90.     || Savelines == NULL
  91.     || ns == NULL
  92.     || nsp == NULL)
  93.     {
  94.         writef("\n\rCannot malloc screen!\n");
  95.         finish(SIGHUP);
  96.     }
  97.  
  98.     for (i = 0; i < LI; i++) {
  99.         ns->s_line = nsp;
  100.         nsp += CO;
  101.         ns->s_length = nsp - 1;        /* End of Line */
  102.         ns += 1;
  103.     }
  104.     cl_scr(0);
  105. }
  106.  
  107. void
  108. clrline(cp1, cp2)
  109. register char    *cp1,
  110.         *cp2;
  111. {
  112.     while (cp1 <= cp2)
  113.         *cp1++ = ' ';
  114. }
  115.  
  116.  
  117. /* Output one character (if necessary) at the current position */
  118.  
  119. #ifdef    MAC
  120.  
  121. /* Character output to bit-mapped screen is very expensive. It makes
  122.    much more sense to write the entire line at once. So, we print all
  123.    the characters, whether already there or not, once the line is
  124.    complete.  */
  125.  
  126. private char sput_buf[256];
  127. private int sput_len = 0;
  128.  
  129. private void
  130. sput_start()
  131. {
  132. /*    if (i_line != CapLine || i_col != CapCol) */
  133.         NPlacur(i_line, i_col);
  134.     sput_len = 0;
  135. }
  136.  
  137. private void
  138. sput_end()
  139. {
  140.     sput_buf[0] = (unsigned char) sput_len;
  141.     writechr(sput_buf);
  142.     sput_len = 0;
  143. }
  144.  
  145. private void
  146. sputc(c)
  147. register int c;
  148. {
  149.     if (sput_len < sizeof(sput_buf)) {
  150.         *cursor++ = c;
  151.         sput_buf[++sput_len] = (c == '0')? 0xAF /* slashed zero */ : c;
  152.         CapCol++;
  153.         i_col++;
  154.     }
  155. }
  156.  
  157. #else    /* !MAC */
  158. #ifdef    IBMPC
  159.  
  160. private bool force = NO;
  161.  
  162. private void
  163. sputc(c)
  164. register int    c;
  165. {
  166.     if (force || (*cursor != c)) {
  167.         if (i_line != CapLine || i_col != CapCol)
  168.             Placur(i_line, i_col);
  169.         *cursor++ = c;
  170.         normfun((char) c);
  171.         AbortCnt -= 1;
  172.         CapCol += 1;
  173.     } else {
  174.         cursor += 1;
  175.     }
  176.     i_col += 1;
  177. }
  178.  
  179. #else    /* !IBMPC */
  180.  
  181. #  define sputc(c)    { \
  182.     if (*cursor != (char) (c)) { \
  183.         do_sputc(c); \
  184.     } else { \
  185.         cursor++; \
  186.         i_col++; \
  187.     } \
  188. }
  189.  
  190. private void
  191. do_sputc(c)
  192. register int    c;
  193. {
  194.     if (*cursor != c) {
  195. # ifdef    ID_CHAR
  196.         if (IN_INSmode)
  197.             INSmode(OFF);
  198. # endif
  199.         if (i_line != CapLine || i_col != CapCol)
  200.             Placur(i_line, i_col);
  201.         if (UL && (c & CHARMASK) == '_' && (*cursor & CHARMASK) != ' ')
  202.             putstr(" \b");        /* Erase so '_' looks right. */
  203.         *cursor++ = c;
  204.         jputchar(c & CHARMASK);
  205.         AbortCnt -= 1;
  206.         CapCol += 1;
  207.     } else {
  208.         cursor += 1;
  209.     }
  210.     i_col += 1;
  211. }
  212.  
  213. #endif    /* !IBMPC */
  214. #endif    /* !MAC */
  215.  
  216. void
  217. cl_eol()
  218. {
  219.     if (cursor > cursend)
  220.         return;
  221.  
  222.     if (cursor < Curline->s_length) {
  223. #ifdef    TERMCAP
  224.         if (CE) {
  225.             Placur(i_line, i_col);
  226.             putpad(CE, 1);
  227.             clrline(cursor, Curline->s_length);
  228.         } else {
  229.             /* Ugh.  The slow way for dumb terminals. */
  230.             register char *savecp = cursor;
  231.  
  232.             while (cursor <= Curline->s_length)
  233.                 sputc(' ');
  234.             cursor = savecp;
  235.         }
  236. #else    /* !TERMCAP */
  237.         Placur(i_line, i_col);
  238.         clr_eoln();
  239.         clrline(cursor, Curline->s_length);
  240. #endif    /* !TERMCAP */
  241.         Curline->s_length = cursor;
  242.     }
  243. }
  244.  
  245. void
  246. cl_scr(doit)
  247. bool doit;
  248. {
  249.     register int    i;
  250.     register struct screenline    *sp = Screen;
  251.  
  252.     for (i = 0; i < LI; i++, sp++) {
  253.         clrline(sp->s_line, sp->s_length);
  254.         sp->s_length = sp->s_line;
  255.         PhysScreen[i].s_id = 0;
  256.     }
  257.     if (doit) {
  258. #ifdef    TERMCAP
  259.         putpad(CL, LI);
  260. #else    /* !TERMCAP */
  261.         clr_page();
  262. #endif    /* !TERMCAP */
  263.         CapCol = CapLine = 0;
  264.         UpdMesg = YES;
  265.     }
  266. }
  267.  
  268. /* Write `line' at the current position of `cursor'.  Stop when we
  269.    reach the end of the screen.  Aborts if there is a character
  270.    waiting.  */
  271.  
  272.  
  273. bool
  274. swrite(line, inversep, abortable)
  275. register char    *line;
  276. bool    inversep;
  277. bool    abortable;
  278. {
  279.     register int    n = cursend - cursor;
  280.     bool    aborted = NO;
  281.  
  282.     if (n > 0) {
  283.  
  284.         register int    c;
  285.         int    col = i_col;
  286. #ifdef    MAC
  287. #        define    spit(c)    sputc(c)
  288. #else    /* !MAC */
  289. #ifdef    IBMPC
  290. #        define    spit(c)    sputc(c)
  291. #else    /* !IBMPC */
  292.         int    or_byte = inversep ? 0200 : 0;
  293. #        define    spit(c)    { int temp = (c) | or_byte; sputc(temp); }
  294. #endif    /* !IBMPC */
  295. #endif    /* !MAC */
  296.  
  297. #ifdef    MAC
  298.         sput_start();    /* Okay, because no interruption possible */
  299. #endif    /* MAC */
  300. #ifdef    IBMPC
  301.         force = inversep;  /* to force a redraw of the modeline */
  302. #endif
  303.         while ((c = *line++) != '\0') {
  304. #            define  spot(c) { if (--n <= 0) break; spit(c); col += 1; }
  305.  
  306.             if (abortable && AbortCnt < 0) {
  307.                 AbortCnt = BufSize;
  308.                 if ((InputPending = charp()) != NO) {
  309.                     aborted = YES;
  310.                     break;
  311.                 }
  312.             }
  313.             if (c == '\t') {
  314.                 int    nchars;
  315.  
  316.                 nchars = (tabstop - (col % tabstop));
  317.                 while (--nchars > 0)
  318.                     spot(' ');
  319.                 c = ' ';
  320.             } else if (jiscntrl(c)) {
  321.                 spot('^');
  322.                 c = (c == '\177') ? '?' : c + '@';
  323. #ifdef    TERMCAP
  324.             } else if (Hazeltine && c == '~') {
  325.                 c = '`';
  326. #endif
  327. #ifdef    IBMPC
  328.             } else if (c == 255) {
  329.                 c = 1;
  330.             } else if (c == ' ' && inversep) {
  331.                 c = 255;
  332. #endif    /* IBMPC */
  333.             }
  334.             spot(c);
  335. #            undef    spot
  336.         }
  337.         if (n <= 0)
  338.             spit(((*line=='\0') && (c!='\t') && !jiscntrl(c))? c : '!');
  339.         if (cursor > Curline->s_length)
  340.             Curline->s_length = cursor;
  341. #ifdef    MAC
  342.         sput_end();
  343. #endif    /* MAC */
  344. #ifdef    IBMPC
  345.         force = NO;
  346. #endif
  347. #        undef    spit
  348.     }
  349.     return !aborted;
  350. }
  351.  
  352. /* This is for writing a buffer line to the screen.  This is to
  353.    minimize the amount of copying from one buffer to another buffer.
  354.    This gets the info directly from the disk buffers. */
  355.  
  356.  
  357. bool
  358. BufSwrite(linenum)
  359. int linenum;
  360. {
  361.     register int    n = cursend - cursor,
  362.             col = 0,
  363.             c = -1;
  364.     register char    *bp;
  365.     int    StartCol = DesiredScreen[linenum].s_offset,
  366.         visspace = DesiredScreen[linenum].s_window->w_flags & W_VISSPACE;
  367.     bool    aborted = NO;
  368.  
  369.     bp = lcontents(DesiredScreen[linenum].s_lp);
  370.     if (*bp) {
  371.         for (;;) {
  372.             if (col >= StartCol) {
  373.                 DesiredScreen[linenum].s_offset = col;
  374.                 break;
  375.             }
  376.  
  377.             c = *bp++ & CHARMASK;
  378.             if (c == '\0')
  379.                 break;
  380.             if (c == '\t')
  381.                 col += (tabstop - (col % tabstop));
  382.             else if (jiscntrl(c))
  383.                 col += 2;
  384.             else
  385.                 col += 1;
  386.         }
  387.     }
  388. #ifdef    MAC
  389.     sput_start();    /* Okay because we can't be interrupted */
  390. #endif
  391.     if (c != '\0') {
  392.         while ((c = *bp++) != '\0') {
  393. #            define spot(c)  { if (--n <= 0) break; sputc(c); col += 1; }
  394.  
  395.             if (AbortCnt < 0) {
  396.                 AbortCnt = BufSize;
  397.                 if ((InputPending = charp()) != NO) {
  398.                     aborted = YES;
  399.                     break;
  400.                 }
  401.             }
  402.             if (c == '\t') {
  403.                 int    nchars = (tabstop - (col % tabstop));
  404.  
  405.                 if (visspace) {
  406.                     spot('>');
  407.                     nchars -= 1;
  408.                 }
  409.                 while (--nchars > 0)
  410.                     spot(' ');
  411.                 c = ' ';
  412.             } else if (jiscntrl(c)) {
  413.                 spot('^');
  414.                 c = (c == '\177') ? '?' : c +