home *** CD-ROM | disk | FTP | other *** search
/ Programmer 7500 / MAX_PROGRAMMERS.iso / INFO / EDITOR / MG2A_SRC.ZIP / SYS / AMIGA / TTY.C < prev    next >
Encoding:
C/C++ Source or Header  |  1988-08-23  |  10.3 KB  |  498 lines

  1. /*
  2.  * Name:    MG 2a
  3.  *        Amiga console device virtual terminal display
  4.  * Last Edit:    29-Nov-87 mic@emx.cc.utexas.edu
  5.  * Created:    19-Apr-86 mic@emx.cc.utexas.edu
  6.  *
  7.  * Drives the Amiga console device display.  The code is basically
  8.  * like the termcap driver in that it uses the console device
  9.  * scrolling region.  It also has some hacks to manage the console
  10.  * device colors.  The latest hack is to inform the terminal I/O
  11.  * driver when we intend to do an escape sequence; this allows the
  12.  * terminal I/O driver to turn off the cursor without breaking up
  13.  * the sequences, leading to a garbled screen.
  14.  */
  15.  
  16. #include <exec/types.h>
  17. #include <exec/nodes.h>
  18. #include <exec/lists.h>
  19. #include <exec/tasks.h>
  20. #include <exec/ports.h>
  21. #include <exec/io.h>
  22. #include <devices/console.h>
  23. #include <libraries/dos.h>
  24. #include <graphics/clip.h>
  25. #include <graphics/view.h>
  26. #include <graphics/rastport.h>
  27. #include <graphics/layers.h>
  28. #include <graphics/text.h>
  29. #include <graphics/gfxbase.h>
  30. #ifndef    MANX
  31. #include <intuition/intuitionbase.h>
  32. #endif
  33. #include <intuition/intuition.h>
  34.  
  35. #undef    TRUE
  36. #undef    FALSE
  37. #include    "def.h"
  38.  
  39. #define    BEL    0x07            /* BEL character.        */
  40. #define    ESC    0x1B            /* ESC character.        */
  41. #define    LF    0x0A            /* Linefeed character        */
  42. #define    CSI    0x9B            /* Command Sequence Introducer    */
  43.  
  44. extern    int    ttrow;
  45. extern    int    ttcol;
  46. extern    int    tttop;
  47. extern    int    ttbot;
  48. extern    int    tthue;
  49.  
  50. int    tceeol    =    3;        /* Costs, ANSI display.        */
  51. int    tcinsl    =     17;
  52. int    tcdell    =    16;
  53.  
  54.  
  55. #ifdef    CHANGE_COLOR
  56. short    mode_rendition = MODE_RENDITION,    /* set standard colors */
  57.     text_rendition = TEXT_RENDITION,
  58.     text_fg = TEXT_FG + 30,
  59.     text_bg = TEXT_BG + 40,
  60.     mode_fg = MODE_FG + 30,
  61.     mode_bg = MODE_BG + 40;
  62. #else                /* colors are hard-coded        */
  63. #define mode_rendition MODE_RENDITION
  64. #define    text_rendition TEXT_RENDITION
  65. #define text_fg (TEXT_FG + 30)
  66. #define text_bg (TEXT_BG + 40)
  67. #define mode_fg (MODE_FG + 30)
  68. #define mode_bg (MODE_BG + 40)
  69. #endif
  70.  
  71. #ifdef    LATTICE
  72. VOID    asciiparm(int) ;
  73. #else
  74. VOID    asciiparm() ;
  75. #endif
  76. VOID    ttnowindow() ;
  77. VOID    ttwindow() ;
  78.  
  79. /*
  80.  * Initialize the terminal when the editor
  81.  * Initialize the virtual terminal.
  82.  * Set the console device's top edge below
  83.  * the front-to-back gadgets, to avoid
  84.  * garbage when scrolling.
  85.  */
  86. VOID
  87. ttinit()
  88. {
  89.     ttputc(CSI);
  90.     asciiparm(TOP_OFFSET);
  91.     ttputc('y');
  92. }
  93.  
  94. /*
  95.  * Clean up the terminal, in anticipation of
  96.  * a return to the command interpreter. This
  97.  * is a no-op on the Amiga, since the window
  98.  * is deleted anyway.
  99.  */
  100. VOID
  101. tttidy()
  102. {
  103. }
  104.  
  105. /*
  106.  * Move the cursor to the specified origin 0 row and column position. Try to
  107.  * optimize out extra moves; redisplay may have left the cursor in the right
  108.  * location last time!
  109.  */
  110. VOID
  111. ttmove(row, col)
  112. {
  113.     if (ttrow!=row || ttcol!=col) {
  114.         ttnflush(8);        /* flush if buffer too full     */
  115.         ttputc(CSI);
  116.         asciiparm(row+1);
  117.         ttputc(';');
  118.         asciiparm(col+1);
  119.         ttputc('H');
  120.         ttrow = row;
  121.         ttcol = col;
  122.     }
  123. }
  124.  
  125. /*
  126.  * Erase to end of line.
  127.  */
  128. VOID
  129. tteeol()
  130. {
  131.     ttnflush(2);        /* flush if not enough room to fit in buffer */
  132.     ttputc(CSI);
  133.     ttputc('K');
  134. }
  135.  
  136. /*
  137.  * Erase to end of page.
  138.  */
  139. VOID
  140. tteeop()
  141. {
  142.     ttnflush(12);        /* flush (but only if not enough room for seq */
  143.     ttputc(CSI);
  144.     asciiparm((tthue == CTEXT) ? text_rendition : mode_rendition);
  145.     ttputc(';');
  146.     asciiparm(text_fg);
  147.     ttputc(';');
  148.     asciiparm(text_bg);
  149.     ttputc('m');
  150.     ttputc(CSI);    /* clear to end of display */
  151.     ttputc('J');
  152. }
  153.  
  154. /*
  155.  * Make a noise.
  156.  */
  157. VOID
  158. ttbeep()
  159. {
  160.     ttputc(BEL);
  161.     ttflush();
  162. }
  163.  
  164. /*
  165.  * Convert a number to decimal
  166.  * ascii, and write it out. Used to
  167.  * deal with numeric arguments.
  168.  */
  169. VOID
  170. asciiparm(n)
  171. register int    n;
  172. {
  173.     if (n > 9)
  174.         asciiparm(n/10);
  175.     ttputc((n%10) + '0');
  176. }
  177.  
  178. /*
  179.  * Insert a block of blank lines onto the
  180.  * screen, using a scrolling region that starts at row
  181.  * "row" and extends down to row "bot".  Deal with the one
  182.  * line case, which is a little bit special, with special
  183.  * case code.
  184.  */
  185. VOID
  186. ttinsl(row, bot, nchunk)
  187. {
  188.     if (row == bot) {            /* Funny case.        */
  189.         if (nchunk != 1)
  190.             panic("ttinsl: nchunk != 1");
  191.         ttmove(row, 0);
  192.         tteeol();
  193.         return;
  194.     } 
  195.     ttmove(1+bot-nchunk, 0);
  196.     if (nchunk > 0) {
  197.         ttwindow(row, bot);
  198.         ttnflush(4);        /* don't break the sequence  */
  199.         ttputc(CSI);
  200.           asciiparm(nchunk);
  201.         ttputc('T');        /* Scroll scrolling region down    */
  202.         ttnowindow();
  203.     }
  204. }
  205.  
  206. /*
  207.  * Delete a block of lines, with the uppermost
  208.  * line at row "row", in a screen slice that extends to
  209.  * row "bot". The "nchunk" is the number of lines that have
  210.  * to be deleted.  It's really easy with the console
  211.  * device scrolling region.
  212.  */
  213. VOID
  214. ttdell(row, bot, nchunk)
  215. {
  216.     if (row == bot) {        /* One line special case    */
  217.         ttmove(row, 0);
  218.         tteeol();
  219.         return;
  220.     }
  221.     if (nchunk > 0) {
  222.         ttwindow(row, bot);
  223.         ttnflush(4);        /* don't break esc. sequence    */
  224.         ttputc(CSI);
  225.           asciiparm(nchunk);
  226.         ttputc('S');        /* Scroll scrolling region up    */
  227.         ttnowindow();
  228.     }
  229.     ttrow = HUGE;
  230.     ttcol = HUGE;
  231.     ttmove(bot-nchunk,0);
  232. }
  233.  
  234. /*
  235.  * This routine sets the scrolling window on the display to go from line
  236.  * "top" to line "bot" (origin 0, inclusive). The caller checks for the
  237.  * pathalogical 1 line scroll window that doesn't work right on all
  238.  * systems, and avoids it. The "ttrow" and "ttcol" variables are set
  239.  * to a crazy value to ensure that ttmove() actually does something.
  240.  */
  241.  
  242. extern    struct Window    *EmW;            /* The window MG uses */
  243.  
  244. VOID
  245. ttwindow(top,bot)
  246. {
  247.     if (tttop != top || ttbot != bot) {
  248.         ttnflush(10);            /* Flush if necessary    */
  249.         ttputc(CSI);            /* Home cursor        */
  250.         ttputc('H');
  251.  
  252.         ttputc(CSI);            /* Set top offset    */
  253.         asciiparm(TOP_OFFSET + top * FontHeight(EmW));
  254.         ttputc('y');
  255.  
  256.         ttputc(CSI);
  257.         asciiparm(bot - top + 1);    /* Set page length    */
  258.         ttputc('t');
  259.  
  260.         ttrow = HUGE;            /* Force cursor reset    */
  261.         ttcol = HUGE;
  262.         tttop = top;            /* Save region state    */
  263.         ttbot = bot;
  264.     }
  265. }
  266.  
  267. /*
  268.  * Switch to full screen scrolling
  269.  */
  270. VOID
  271. ttnowindow()
  272. {
  273.     ttnflush(10);            /* Flush if necessary        */
  274.     ttputc(CSI);            /* Home cursor            */
  275.     ttputc('H');
  276.  
  277.     ttputc(CSI);            /* Set top offset to normal    */
  278.     asciiparm(TOP_OFFSET);
  279.     ttputc('y');
  280.  
  281.     ttputc(CSI);            /* Set page length to nrow    */
  282.     asciiparm(nrow);
  283.     ttputc('t');
  284.  
  285.     ttrow = HUGE;            /* Make cursor unknown.        */
  286.     ttcol = HUGE;
  287.     tttop = HUGE;
  288.     ttbot = HUGE;
  289. }
  290.  
  291. #ifdef    CHANGE_COLOR
  292. /*
  293.  * Set the rendition of the mode line by
  294.  * selecting colors from the following:
  295.  *    0 -- plain text
  296.  *    1 -- bold-face
  297.  *    3 -- italic
  298.  *    4 -- underscore
  299.  *    7 -- inverse video
  300.  * Certain of these selections may be less than
  301.  * appealing :-)
  302.  */
  303.  
  304. ttmode(f, n)
  305. {
  306.     register int    s;
  307.     char        buf[2];
  308.  
  309.     if (!(f & FFARG)) {
  310.         if ((s = ereply("Set mode line rendition (0-7): ",
  311.                 buf, sizeof(buf))) != TRUE)
  312.             return (s);
  313.         n = atoi(buf);
  314.     }
  315.     if (n < 0 || n > 7)
  316.         return (FALSE);
  317.  
  318.     mode_rendition = n;        /* store the color    */
  319.     sgarbf = TRUE;
  320.     return (TRUE);
  321. }
  322.  
  323. /*
  324.  * Set the rendition of the text area.
  325.  * Most of these selections will be
  326.  * less than appealing :-]
  327.  */
  328.  
  329. tttext(f, n)
  330. {
  331.     register int    s;
  332.     char        buf[2];
  333.  
  334.     if (!(f & FFARG)) {
  335.         if ((s = ereply("Set text rendition (0-7): ",
  336.                 buf, sizeof(buf))) != TRUE)
  337.             return (s);
  338.         n = atoi(buf);
  339.     }
  340.     if (n < 0 || n > 7)
  341.         return (FALSE);
  342.  
  343.     text_rendition = n;        /* store the color    */
  344.     sgarbf = TRUE;
  345.     return (TRUE);
  346. }
  347.  
  348. /*
  349.  * Set foreground color for entire window
  350.  * to a value between 30 and 37, which
  351.  * corresponds to the arguments 0-7.
  352.  * This requires a total refresh, which
  353.  * sets up the screen.
  354.  */
  355.  
  356. textforeground(f, n)
  357. {
  358.     register int    s;
  359.     char        buf[2];
  360.  
  361.     if (!(f & FFARG)) {
  362.         if ((s = ereply("Text foreground color (0-7): ",
  363.                 buf, sizeof(buf))) != TRUE)
  364.             return (s);
  365.         n = atoi(buf);
  366.     }
  367.     if (n < 0 || n > 7)
  368.         return (FALSE);
  369.  
  370.     text_fg = n + 30;
  371.     sgarbf = TRUE;
  372.     return (TRUE);
  373. }
  374.  
  375. /*
  376.  * Set background color for entire window
  377.  * to a value between 40 and 47 inclusive.
  378.  */
  379.  
  380. textbackground(f, n)
  381. {
  382.     register int    s;
  383.     char        buf[2];
  384.  
  385.     if (!(f & FFARG)) {
  386.         if ((s = ereply("Text background color (0-7): ",
  387.                 buf, sizeof(buf))) != TRUE)
  388.             return (s);
  389.         n = atoi(buf);
  390.     }
  391.     if (n < 0 || n > 7)
  392.         return (FALSE);
  393.  
  394.     text_bg = n + 40;
  395.     sgarbf = TRUE;
  396.     return (TRUE);
  397. }
  398.  
  399. /*
  400.  * Set foreground color for entire the mode line
  401.  */
  402.  
  403. modeforeground(f, n)
  404. {
  405.     register int    s;
  406.     char        buf[2];
  407.  
  408.     if (!(f & FFARG)) {
  409.         if ((s = ereply("Mode line foreground color (0-7): ",
  410.                 buf, sizeof(buf))) != TRUE)
  411.             return (s);
  412.         n = atoi(buf);
  413.     }
  414.     if (n < 0 || n > 7)
  415.         return (FALSE);
  416.  
  417.     mode_fg = n + 30;
  418.     sgarbf = TRUE;
  419.     return (TRUE);
  420. }
  421.  
  422. /*
  423.  * Set background color for the mode line
  424.  */
  425.  
  426. modebackground(f, n)
  427. {
  428.     register int    s;
  429.     char        buf[2];
  430.  
  431.     if (!(f & FFARG)) {
  432.         if ((s = ereply("Mode line background color (0-7): ",
  433.                 buf, sizeof(buf))) != TRUE)
  434.             return (s);
  435.         n = atoi(buf);
  436.     }
  437.     if (n < 0 || n > 7)
  438.         return (FALSE);
  439.  
  440.     mode_bg = n + 40;
  441.     sgarbf = TRUE;
  442.     return (TRUE);
  443. }
  444. #endif
  445.  
  446. /*
  447.  * Set the current writing color to the
  448.  * specified color. Watch for color changes that are
  449.  * not going to do anything (the color is already right)
  450.  * and don't send anything to the display.
  451.  */
  452.  
  453. VOID
  454. ttcolor(color)
  455. register int    color;
  456. {
  457.     if (color != tthue) {
  458.         ttnflush(12);            /* Flush if necessary    */
  459.         if (color == CTEXT) {        /* Normal video.    */
  460.             ttputc(CSI);        /* Reset to 0        */
  461.             ttputc('m');
  462.             ttputc(CSI);        /* Set text style    */
  463.             asciiparm(text_rendition);
  464.             ttputc(';');
  465.             asciiparm(text_fg);
  466.             ttputc(';');
  467.             asciiparm(text_bg);
  468.             ttputc('m');
  469.         } else if (color == CMODE) {    /* Standout mode    */
  470.             ttputc(CSI);        /* Reset to 0        */
  471.             ttputc('m');
  472.             ttputc(CSI);        /* Set standout mode    */
  473.             asciiparm(mode_rendition);
  474.             ttputc(';');
  475.             asciiparm(mode_fg);    /* Use mode line colors    */
  476.             ttputc(';');
  477.             asciiparm(mode_bg);
  478.             ttputc('m');
  479.         }
  480.         tthue = color;            /* Save the color.    */
  481.     }
  482. }
  483.  
  484. /*
  485.  * This routine is called by the "refresh the screen" command to try and resize
  486.  * the display. The new size, which must be deadstopped to not exceed the NROW
  487.  * and NCOL limits, is stored back into "nrow" and "ncol". Display can always
  488.  * deal with a screen NROW by NCOL. Look in "window.c" to see how the caller
  489.  * deals with a change. On the Amiga, we make the Intuition terminal driver
  490.  * do all the work.
  491.  */
  492.  
  493. VOID
  494. ttresize()
  495. {
  496.      setttysize();
  497. }
  498.