home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / apps / 21 / emacsrc / mldispla.c < prev    next >
Encoding:
C/C++ Source or Header  |  1986-05-14  |  9.8 KB  |  410 lines

  1. /*
  2.  * file:mldisplay.c ::= routines dealing with message line below the mode line.
  3.  *
  4.  * N.B. \033q is sent more often than should be necessary because
  5.  * the ST remains in reverse video, in some situations, even after
  6.  * receiving a \033q.
  7.  */
  8.  
  9. #include        "ed.h"
  10. #include    "osbind.h"
  11.  
  12. #define WFDEBUG 0                       /* Window flag debug. */
  13.  
  14. #define VFCHG   0x0001                  /* Changed. */
  15. #define MDLIN   0x0002
  16.  
  17. extern
  18. int  sgarbf,
  19.      mpresf,
  20.      vtrow,
  21.      vtcol,
  22.      ttrow,
  23.      ttcol;
  24.  
  25.  
  26. extern VIDEO   **vscreen;                      /* Virtual screen. */
  27. extern VIDEO   **pscreen;                      /* Physical screen. */
  28.  
  29. #define NROW    25                      /* Screen size.                 */
  30. #define NCOL    80                      /* Edit if you want to.         */
  31. #define BIAS    0x20                    /* Origin 0 coordinate bias.    */
  32.  
  33. TERM    term    = {
  34.         NROW-1,
  35.         NCOL
  36. };
  37.  
  38. /*
  39.  * Redisplay the mode line for the window pointed to by the "wp". This is the
  40.  * only routine that has any idea of how the modeline is formatted. You can
  41.  * change the modeline format by hacking at this routine. Called by "update"
  42.  * any time there is a dirty window.
  43.  */
  44. modeline(wp)
  45.     WINDOW *wp;
  46. {
  47.     register char *cp;
  48.     register char *mp;
  49.     register int c;
  50.     register int n;
  51.     register BUFFER *bp;
  52.     char     md[NCOL+NCOL];    /* so we can forget about range check */
  53.  
  54.  
  55.     for (mp=md; mp < &md[NCOL];) *mp++ = '-';
  56.  
  57.     n = wp->w_toprow+wp->w_ntrows;              /* Location. */
  58.     vscreen[n]->v_flag |= VFCHG | MDLIN;        /* Redraw next time. */
  59.     vtmove(n, 0);                               /* Seek to right line. */
  60.  
  61.     bp = wp->w_bufp;
  62.     if ((bp->b_flag&BFCHG) != 0)                /* "*" if changed. */
  63.     md[1] = md[2] = '*';
  64.  
  65.     mp = &md[4];
  66.     cp = " microEmacs -- ";
  67.     while ((*mp++ = *cp++) != 0);
  68.     mp --;
  69.  
  70.     cp = &bp->b_bname[0];                     /* Buffer name. */
  71.     while ((*mp++ = *cp++) != 0);
  72.     mp[-1] = ' ';
  73.  
  74.     if (bp->b_fname[0] != 0)            /* File name. */
  75.     {
  76.         cp = "-- File: ";
  77.         while ((*mp++ = *cp++) != 0);
  78.     mp--;
  79.         cp = &bp->b_fname[0];
  80.         while ((*mp++ = *cp++) != 0);
  81.     mp[-1] = ' ';
  82.     }
  83.  
  84.     for(mp=md; mp < &md[NCOL];)
  85.         vtputc(*mp++);
  86. }
  87.  
  88. /*
  89.  * Send a command to the terminal to move the hardware cursor to row "row"
  90.  * and column "col". The row and column arguments are origin 0. Optimize out
  91.  * random calls. Update "ttrow" and "ttcol".
  92.  */
  93. movecursor(row, col)
  94.     {
  95.     static char es[5] = "\033Yrc";
  96.  
  97.     if (row!=ttrow || col!=ttcol)
  98.         {
  99.         ttrow = row;
  100.         ttcol = col;
  101. /*        (*term.t_move)(row, col);    */
  102.     es[2] = (char) row + BIAS;
  103.     es[3] = (char) col + BIAS;
  104.     Cconws(es);
  105.         }
  106.     }
  107.  
  108. /*
  109.  * Erase the message line. This is a special routine because the message line
  110.  * is not considered to be part of the virtual screen. It always works
  111.  * immediately; the terminal buffer is flushed via a call to the flusher.
  112.  */
  113. mlerase()
  114.     {
  115.     movecursor(term.t_nrow, 0);
  116. /*    (*term.t_eeol)();        */
  117. /*    (*term.t_flush)();    */
  118.     Cconws("\033q\033K");
  119.     mpresf = FALSE;
  120.     }
  121.  
  122. /*
  123.  * Ask a yes or no question in the message line. Return either TRUE, FALSE, or
  124.  * ABORT. The ABORT status is returned if the user bumps out of the question
  125.  * with a ^G. Used any time a confirmation is required.
  126.  */
  127. mlyesno(prompt)
  128.     char *prompt;
  129.     {
  130.     register int s;
  131.     char buf[64];
  132.  
  133.     for (;;)
  134.         {
  135.         strcpy(buf, prompt);
  136.         strcat(buf, " [y/n]? ");
  137.         s = mlreply(buf, buf, sizeof(buf));
  138.  
  139.         if (s == ABORT)
  140.             return (ABORT);
  141.  
  142.         if (s != FALSE)
  143.             {
  144.             if (buf[0]=='y' || buf[0]=='Y')
  145.                 return (TRUE);
  146.  
  147.             if (buf[0]=='n' || buf[0]=='N')
  148.                 return (FALSE);
  149.             }
  150.         }
  151.     }
  152.  
  153. /*
  154.  * Write a prompt into the message line, then read back a response. Keep
  155.  * track of the physical position of the cursor. If we are in a keyboard
  156.  * macro throw the prompt away, and return the remembered response. This
  157.  * lets macros run at full speed. The reply is always terminated by a carriage
  158.  * return. Handle erase, kill, and abort keys.
  159.  */
  160. mlreply(prompt, buf, nbuf)
  161.     char *prompt;
  162.     char *buf;
  163.     {
  164.     register int cpos;
  165.     register int i;
  166.     register int c;
  167.  
  168.     cpos = 0;
  169.  
  170.     if (kbdmop != NULL)
  171.         {
  172.         while ((c = *kbdmop++) != '\0')
  173.             buf[cpos++] = c;
  174.  
  175.         buf[cpos] = 0;
  176.  
  177.         if (buf[0] == 0)
  178.             return (FALSE);
  179.  
  180.         return (TRUE);
  181.         }
  182.  
  183.     mlwrite(prompt);
  184.  
  185.     for (;;)
  186.         {
  187. /*      c = (*term.t_getchar)();    */
  188.     c = Crawcin();
  189.         switch (c)
  190.             {
  191.         case 0x12:            /* ^R    */
  192.         case 0x13:            /* ^S    */
  193.         buf[cpos++] = c;    /* fall through! */
  194.             case 0x0D:                  /* Return, end of line */
  195.                 buf[cpos++] = 0;
  196.  
  197.                 if (kbdmip != NULL)
  198.                     {
  199.                     if (kbdmip+cpos > &kbdm[NKBDM-3])
  200.                         {
  201.                         ctrlg(FALSE, 0);
  202. /*                      (*term.t_flush)();    */
  203.                         return (ABORT);
  204.                         }
  205.  
  206.                     for (i=0; i<cpos; ++i)
  207.                         *kbdmip++ = buf[i];
  208.                     }
  209.  
  210.         Cconout('\r');
  211.                 ttcol = 0;
  212. /*              (*term.t_flush)();    */
  213.  
  214.                 if (buf[0] == 0)
  215.                     return (FALSE);
  216.  
  217.                 return (TRUE);
  218.  
  219.             case 0x07:                  /* Bell, abort */
  220.         Cconws("^G");
  221.                 ttcol += 2;
  222.                 ctrlg(FALSE, 0);
  223. /*              (*term.t_flush)();    */
  224.                 return (ABORT);
  225.  
  226.             case 0x7F:                  /* Rubout, erase */
  227.             case 0x08:                  /* Backspace, erase */
  228.                 if (cpos != 0)
  229.                     {
  230.             Cconws("\b \b");
  231.                     --ttcol;
  232.  
  233.                     if (buf[--cpos] < 0x20)
  234.                         {
  235.             Cconws("\b \b");
  236.                         --ttcol;
  237.                         }
  238.  
  239. /*                    (*term.t_flush)();    */
  240.                     }
  241.  
  242.                 break;
  243.  
  244.             case 0x15:                  /* C-U, kill */
  245.                 while (cpos != 0)
  246.                     {
  247.             Cconws("\b \b");
  248.                     --ttcol;
  249.  
  250.                     if (buf[--cpos] < 0x20)
  251.                         {
  252.             Cconws("\b \b");
  253.                         --ttcol;
  254.                         }
  255.                     }
  256.  
  257. /*                (*term.t_flush)();            */
  258.                 break;
  259.  
  260.             default:
  261.                 if (cpos < nbuf-1)
  262.                     {
  263.                     buf[cpos++] = c;
  264.  
  265.                     if (c < ' ')
  266.                         {
  267.             Cconout('^');
  268.                         ++ttcol;
  269.                         c ^= 0x40;
  270.                         }
  271.  
  272.             Cconout(c);
  273.                     ++ttcol;
  274. /*                  (*term.t_flush)();        */
  275.                     }
  276.             }
  277.         }
  278.     }
  279.  
  280. /*
  281.  * Write a message into the message line. Keep track of the physical cursor
  282.  * position. A small class of printf like format items is handled. Assumes the
  283.  * stack grows down; this assumption is made by the "++" in the argument scan
  284.  * loop. Set the "message line" flag TRUE.
  285.  */
  286. mlwrite(fmt, arg)
  287.     char *fmt;
  288.     {
  289.     register int c;
  290.     register char *ap;
  291.  
  292.     Cconws("\033q");    /* !! */
  293.     movecursor(term.t_nrow, 0);
  294.     ap = (char *) &arg;
  295.     while ((c = *fmt++) != 0) {
  296.         if (c != '%') {
  297.         Cconout(c);
  298.             ++ttcol;
  299.             }
  300.         else
  301.             {
  302.             c = *fmt++;
  303.             switch (c) {
  304.                 case 'd':
  305.                     mlputi(*(int *)ap, 10);
  306.                     ap += sizeof(int);
  307.                     break;
  308.  
  309.                 case 'o':
  310.                     mlputi(*(int *)ap,  8);
  311.                     ap += sizeof(int);
  312.                     break;
  313.  
  314.                 case 'x':
  315.                     mlputi(*(int *)ap, 16);
  316.                     ap += sizeof(int);
  317.                     break;
  318.  
  319.                 case 'D':
  320.                     mlputli(*(long *)ap, 10);
  321.                     ap += sizeof(long);
  322.                     break;
  323.  
  324.                 case 's':
  325.                     mlputs(*(char **)ap);
  326.                     ap += sizeof(char *);
  327.                     break;
  328.  
  329.                 default:
  330.             Cconout(c);
  331.                     ++ttcol;
  332.                 }
  333.             }
  334.         }
  335. /*  (*term.t_eeol)();    */
  336. /*  (*term.t_flush)();    */
  337.     Cconws("\033K");
  338.     mpresf = TRUE;
  339.     }
  340.  
  341. /*
  342.  * Write out a string. Update the physical cursor position. This assumes that
  343.  * the characters in the string all have width "1"; if this is not the case
  344.  * things will get screwed up a little.
  345.  */
  346. /*    ---------    #defined as Cconws in ed.h
  347. mlputs(s)
  348.     char *s;
  349.     {
  350.     register int c;
  351.  
  352.     while ((c = *s++) != 0)
  353.         {
  354. *      (*term.t_putchar)(c);    *
  355.     Cconout(c);
  356.         ++ttcol;
  357.         }
  358.     }
  359.     ---------
  360. */
  361.  
  362. /*
  363.  * Write out an integer, in the specified radix. Update the physical cursor
  364.  * position. This will not handle any negative numbers; maybe it should.
  365.  */
  366. mlputi(i, r)
  367.     {
  368.     register int q;
  369.     static char hexdigits[] = "0123456789ABCDEF";
  370.  
  371.     if (i < 0)
  372.         {
  373.         i = -i;
  374.     Cconout('-');
  375.         }
  376.  
  377.     q = i/r;
  378.  
  379.     if (q != 0)
  380.         mlputi(q, r);
  381.  
  382.     Cconout(hexdigits[i%r]);
  383.     ++ttcol;
  384.     }
  385.  
  386. /*
  387.  * do the same except as a long integer.
  388.  */
  389. mlputli(l, r)
  390.     long l;
  391.     {
  392.     register long q;
  393.  
  394.     if (l < 0)
  395.         {
  396.         l = -l;
  397.     Cconout('-');
  398.         }
  399.  
  400.     q = l/r;
  401.  
  402.     if (q != 0)
  403.         mlputli(q, r);
  404.  
  405.     Cconout((int)(l%r)+'0');
  406.     ++ttcol;
  407.     }
  408.  
  409. /* -eof- */
  410.