home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Source Code 1993 July / THE_SOURCE_CODE_CD_ROM.iso / bsd_srcs / sys / hp300 / dev / ite.c < prev    next >
Encoding:
C/C++ Source or Header  |  1991-05-16  |  19.5 KB  |  903 lines

  1. /*
  2.  * Copyright (c) 1988 University of Utah.
  3.  * Copyright (c) 1990 The Regents of the University of California.
  4.  * All rights reserved.
  5.  *
  6.  * This code is derived from software contributed to Berkeley by
  7.  * the Systems Programming Group of the University of Utah Computer
  8.  * Science Department.
  9.  *
  10.  * Redistribution and use in source and binary forms, with or without
  11.  * modification, are permitted provided that the following conditions
  12.  * are met:
  13.  * 1. Redistributions of source code must retain the above copyright
  14.  *    notice, this list of conditions and the following disclaimer.
  15.  * 2. Redistributions in binary form must reproduce the above copyright
  16.  *    notice, this list of conditions and the following disclaimer in the
  17.  *    documentation and/or other materials provided with the distribution.
  18.  * 3. All advertising materials mentioning features or use of this software
  19.  *    must display the following acknowledgement:
  20.  *    This product includes software developed by the University of
  21.  *    California, Berkeley and its contributors.
  22.  * 4. Neither the name of the University nor the names of its contributors
  23.  *    may be used to endorse or promote products derived from this software
  24.  *    without specific prior written permission.
  25.  *
  26.  * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
  27.  * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  28.  * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  29.  * ARE DISCLAIMED.  IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
  30.  * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  31.  * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  32.  * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  33.  * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  34.  * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  35.  * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  36.  * SUCH DAMAGE.
  37.  *
  38.  * from: Utah $Hdr: ite.c 1.1 90/07/09$
  39.  *
  40.  *    @(#)ite.c    7.6 (Berkeley) 5/16/91
  41.  */
  42.  
  43. /*
  44.  * Bit-mapped display terminal emulator machine independent code.
  45.  * This is a very rudimentary.  Much more can be abstracted out of
  46.  * the hardware dependent routines.
  47.  */
  48. #include "ite.h"
  49. #if NITE > 0
  50.  
  51. #include "grf.h"
  52.  
  53. #undef NITE
  54. #define NITE    NGRF
  55.  
  56. #include "param.h"
  57. #include "conf.h"
  58. #include "proc.h"
  59. #include "ioctl.h"
  60. #include "tty.h"
  61. #include "systm.h"
  62. #include "malloc.h"
  63.  
  64. #include "itevar.h"
  65. #include "iteioctl.h"
  66. #include "kbdmap.h"
  67.  
  68. #include "machine/cpu.h"
  69.  
  70. #define set_attr(ip, attr)    ((ip)->attribute |= (attr))
  71. #define clr_attr(ip, attr)    ((ip)->attribute &= ~(attr))
  72.  
  73. extern  int nodev();
  74.  
  75. int topcat_scroll(),    topcat_init(),        topcat_deinit();
  76. int topcat_clear(),    topcat_putc(),         topcat_cursor();
  77. int gatorbox_scroll(),    gatorbox_init(),    gatorbox_deinit();
  78. int gatorbox_clear(),    gatorbox_putc(),     gatorbox_cursor();
  79. int rbox_scroll(),    rbox_init(),        rbox_deinit();
  80. int rbox_clear(),    rbox_putc(),         rbox_cursor();
  81. int dvbox_scroll(),    dvbox_init(),        dvbox_deinit();
  82. int dvbox_clear(),    dvbox_putc(),         dvbox_cursor();
  83.  
  84. struct itesw itesw[] =
  85. {
  86.     topcat_init,        topcat_deinit,        topcat_clear,
  87.     topcat_putc,        topcat_cursor,        topcat_scroll,
  88.  
  89.     gatorbox_init,        gatorbox_deinit,    gatorbox_clear,
  90.     gatorbox_putc,        gatorbox_cursor,    gatorbox_scroll,
  91.  
  92.     rbox_init,        rbox_deinit,        rbox_clear,
  93.     rbox_putc,        rbox_cursor,        rbox_scroll,
  94.  
  95.     dvbox_init,        dvbox_deinit,        dvbox_clear,
  96.     dvbox_putc,        dvbox_cursor,        dvbox_scroll,
  97. };
  98.  
  99. /*
  100.  * # of chars are output in a single itestart() call.
  101.  * If this is too big, user processes will be blocked out for
  102.  * long periods of time while we are emptying the queue in itestart().
  103.  * If it is too small, console output will be very ragged.
  104.  */
  105. int    iteburst = 64;
  106.  
  107. int    nite = NITE;
  108. struct  tty *kbd_tty = NULL;
  109. struct    tty ite_tty[NITE];
  110. struct  ite_softc ite_softc[NITE];
  111.  
  112. int    itestart();
  113. extern    int ttrstrt();
  114. extern    struct tty *constty;
  115.  
  116. /*
  117.  * Primary attribute buffer to be used by the first bitmapped console
  118.  * found. Secondary displays alloc the attribute buffer as needed.
  119.  * Size is based on a 68x128 display, which is currently our largest.
  120.  */
  121. u_char  console_attributes[0x2200];
  122.  
  123. /*
  124.  * Perform functions necessary to setup device as a terminal emulator.
  125.  */
  126. iteon(dev, flag)
  127.     dev_t dev;
  128. {
  129.     int unit = UNIT(dev);
  130.     struct tty *tp = &ite_tty[unit];
  131.     struct ite_softc *ip = &ite_softc[unit];
  132.  
  133.     if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0)
  134.         return(ENXIO);
  135.     /* force ite active, overriding graphics mode */
  136.     if (flag & 1) {
  137.         ip->flags |= ITE_ACTIVE;
  138.         ip->flags &= ~(ITE_INGRF|ITE_INITED);
  139.     }
  140.     /* leave graphics mode */
  141.     if (flag & 2) {
  142.         ip->flags &= ~ITE_INGRF;
  143.         if ((ip->flags & ITE_ACTIVE) == 0)
  144.             return(0);
  145.     }
  146.     ip->flags |= ITE_ACTIVE;
  147.     if (ip->flags & ITE_INGRF)
  148.         return(0);
  149.     if (kbd_tty == NULL || kbd_tty == tp) {
  150.         kbd_tty = tp;
  151.         kbdenable();
  152.     }
  153.     iteinit(dev);
  154.     return(0);
  155. }
  156.  
  157. iteinit(dev)
  158.      dev_t dev;
  159. {
  160.     int unit = UNIT(dev);
  161.     struct ite_softc *ip = &ite_softc[unit];
  162.  
  163.     if (ip->flags & ITE_INITED)
  164.         return;
  165.     
  166.     ip->curx = 0;
  167.     ip->cury = 0;
  168.     ip->cursorx = 0;
  169.     ip->cursory = 0;
  170.  
  171.     (*itesw[ip->type].ite_init)(ip);
  172.     (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
  173.  
  174.     ip->attribute = 0;
  175.     if (ip->attrbuf == NULL)
  176.         ip->attrbuf = (u_char *)
  177.             malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK);
  178.     bzero(ip->attrbuf, (ip->rows * ip->cols));
  179.  
  180.     ip->imode = 0;
  181.     ip->flags |= ITE_INITED;
  182. }
  183.  
  184. /*
  185.  * "Shut down" device as terminal emulator.
  186.  * Note that we do not deinit the console device unless forced.
  187.  * Deinit'ing the console every time leads to a very active
  188.  * screen when processing /etc/rc.
  189.  */
  190. iteoff(dev, flag)
  191.     dev_t dev;
  192. {
  193.     register struct ite_softc *ip = &ite_softc[UNIT(dev)];
  194.  
  195.     if (flag & 2)
  196.         ip->flags |= ITE_INGRF;
  197.     if ((ip->flags & ITE_ACTIVE) == 0)
  198.         return;
  199.     if ((flag & 1) ||
  200.         (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
  201.         (*itesw[ip->type].ite_deinit)(ip);
  202.     if ((flag & 2) == 0)
  203.         ip->flags &= ~ITE_ACTIVE;
  204. }
  205.  
  206. /* ARGSUSED */
  207. #ifdef __STDC__
  208. iteopen(dev_t dev, int mode, int devtype, struct proc *p)
  209. #else
  210. iteopen(dev, mode, devtype, p)
  211.     dev_t dev;
  212.     int mode, devtype;
  213.     struct proc *p;
  214. #endif
  215. {
  216.     int unit = UNIT(dev);
  217.     register struct tty *tp = &ite_tty[unit];
  218.     register struct ite_softc *ip = &ite_softc[unit];
  219.     register int error;
  220.     int first = 0;
  221.  
  222.     if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)
  223.         && p->p_ucred->cr_uid != 0)
  224.         return (EBUSY);
  225.     if ((ip->flags & ITE_ACTIVE) == 0) {
  226.         error = iteon(dev, 0);
  227.         if (error)
  228.             return (error);
  229.         first = 1;
  230.     }
  231.     tp->t_oproc = itestart;
  232.     tp->t_param = NULL;
  233.     tp->t_dev = dev;
  234.     if ((tp->t_state&TS_ISOPEN) == 0) {
  235.         ttychars(tp);
  236.         tp->t_iflag = TTYDEF_IFLAG;
  237.         tp->t_oflag = TTYDEF_OFLAG;
  238.         tp->t_cflag = CS8|CREAD;
  239.         tp->t_lflag = TTYDEF_LFLAG;
  240.         tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
  241.         tp->t_state = TS_ISOPEN|TS_CARR_ON;
  242.         ttsetwater(tp);
  243.     }
  244.     error = (*linesw[tp->t_line].l_open)(dev, tp);
  245.     if (error == 0) {
  246.         tp->t_winsize.ws_row = ip->rows;
  247.         tp->t_winsize.ws_col = ip->cols;
  248.     } else if (first)
  249.         iteoff(dev, 0);
  250.     return (error);
  251. }
  252.  
  253. /*ARGSUSED*/
  254. iteclose(dev, flag, mode, p)
  255.     dev_t dev;
  256.     int flag, mode;
  257.     struct proc *p;
  258. {
  259.     register struct tty *tp = &ite_tty[UNIT(dev)];
  260.  
  261.     (*linesw[tp->t_line].l_close)(tp, flag);
  262.     ttyclose(tp);
  263.     iteoff(dev, 0);
  264.     return(0);
  265. }
  266.  
  267. iteread(dev, uio, flag)
  268.     dev_t dev;
  269.     struct uio *uio;
  270. {
  271.     register struct tty *tp = &ite_tty[UNIT(dev)];
  272.  
  273.     return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
  274. }
  275.  
  276. itewrite(dev, uio, flag)
  277.     dev_t dev;
  278.     struct uio *uio;
  279. {
  280.     int unit = UNIT(dev);
  281.     register struct tty *tp = &ite_tty[unit];
  282.  
  283.     if ((ite_softc[unit].flags & ITE_ISCONS) && constty &&
  284.         (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))
  285.         tp = constty;
  286.     return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
  287. }
  288.  
  289. iteioctl(dev, cmd, addr, flag)
  290.     dev_t dev;
  291.     caddr_t addr;
  292. {
  293.     register struct tty *tp = &ite_tty[UNIT(dev)];
  294.     int error;
  295.  
  296.     error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag);
  297.     if (error >= 0)
  298.         return (error);
  299.     error = ttioctl(tp, cmd, addr, flag);
  300.     if (error >= 0)
  301.         return (error);
  302.     return (ENOTTY);
  303. }
  304.  
  305. itestart(tp)
  306.     register struct tty *tp;
  307. {
  308.     register int cc, s;
  309.     int hiwat = 0;
  310.  
  311.     s = spltty();
  312.     if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
  313.         splx(s);
  314.         return;
  315.     }
  316.     tp->t_state |= TS_BUSY;
  317.     cc = tp->t_outq.c_cc;
  318.     if (cc <= tp->t_lowat) {
  319.         if (tp->t_state & TS_ASLEEP) {
  320.             tp->t_state &= ~TS_ASLEEP;
  321.             wakeup(&tp->t_outq);
  322.         }
  323.         if (tp->t_wsel) {
  324.             selwakeup(tp->t_wsel, tp->t_state & TS_WCOLL);
  325.             tp->t_wsel = 0;
  326.             tp->t_state &= ~TS_WCOLL;
  327.         }
  328.     }
  329.     /*
  330.      * Limit the amount of output we do in one burst
  331.      * to prevent hogging the CPU.
  332.      */
  333.     if (cc > iteburst) {
  334.         hiwat++;
  335.         cc = iteburst;
  336.     }
  337.     while (--cc >= 0) {
  338.         register int c;
  339.  
  340.         c = getc(&tp->t_outq);
  341.         /*
  342.          * iteputchar() may take a long time and we don't want to
  343.          * block all interrupts for long periods of time.  Since
  344.          * there is no need to stay at high priority while outputing
  345.          * the character (since we don't have to worry about
  346.          * interrupts), we don't.  We just need to make sure that
  347.          * we don't reenter iteputchar, which is guarenteed by the
  348.          * earlier setting of TS_BUSY.
  349.          */
  350.         splx(s);
  351.         iteputchar(c, tp->t_dev);
  352.         spltty();
  353.     }
  354.     if (hiwat) {
  355.         tp->t_state |= TS_TIMEOUT;
  356.         timeout(ttrstrt, tp, 1);
  357.     }
  358.     tp->t_state &= ~TS_BUSY;
  359.     splx(s);
  360. }
  361.  
  362. itefilter(stat, c)
  363.      register char stat, c;
  364. {
  365.     static int capsmode = 0;
  366.     static int metamode = 0;
  367.       register char code, *str;
  368.  
  369.     if (kbd_tty == NULL)
  370.         return;
  371.  
  372.     switch (c & 0xFF) {
  373.     case KBD_CAPSLOCK:
  374.         capsmode = !capsmode;
  375.         return;
  376.  
  377.     case KBD_EXT_LEFT_DOWN:
  378.     case KBD_EXT_RIGHT_DOWN:
  379.         metamode = 1;
  380.         return;
  381.         
  382.     case KBD_EXT_LEFT_UP:
  383.     case KBD_EXT_RIGHT_UP:
  384.         metamode = 0;
  385.         return;
  386.     }
  387.  
  388.     c &= KBD_CHARMASK;
  389.     switch ((stat>>KBD_SSHIFT) & KBD_SMASK) {
  390.  
  391.     case KBD_KEY:
  392.             if (!capsmode) {
  393.             code = kbd_keymap[c];
  394.             break;
  395.         }
  396.         /* fall into... */
  397.  
  398.     case KBD_SHIFT:
  399.         code = kbd_shiftmap[c];
  400.         break;
  401.  
  402.     case KBD_CTRL:
  403.         code = kbd_ctrlmap[c];
  404.         break;
  405.         
  406.     case KBD_CTRLSHIFT:    
  407.         code = kbd_ctrlshiftmap[c];
  408.         break;
  409.         }
  410.  
  411.     if (code == NULL && (str = kbd_stringmap[c]) != NULL) {
  412.         while (*str)
  413.             (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);
  414.     } else {
  415.         if (metamode)
  416.             code |= 0x80;
  417.         (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
  418.     }
  419. }
  420.  
  421. iteputchar(c, dev)
  422.     register int c;
  423.     dev_t dev;  
  424. {
  425.     int unit = UNIT(dev);
  426.     register struct ite_softc *ip = &ite_softc[unit];
  427.     register struct itesw *sp = &itesw[ip->type];
  428.     register int n;
  429.  
  430.     if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
  431.           return;
  432.  
  433.     if (ip->escape) {
  434. doesc:
  435.         switch (ip->escape) {
  436.  
  437.         case '&':            /* Next can be a,d, or s */
  438.             if (ip->fpd++) {
  439.                 ip->escape = c;
  440.                 ip->fpd = 0;
  441.             }
  442.             return;
  443.  
  444.         case 'a':                /* cursor change */
  445.             switch (c) {
  446.  
  447.             case 'Y':            /* Only y coord. */
  448.                 ip->cury = MIN(ip->pos, ip->rows-1);
  449.                 ip->pos = 0;
  450.                 ip->escape = 0;
  451.                 (*sp->ite_cursor)(ip, MOVE_CURSOR);
  452.                 clr_attr(ip, ATTR_INV);
  453.                 break;
  454.  
  455.             case 'y':            /* y coord first */
  456.                 ip->cury = MIN(ip->pos, ip->rows-1);
  457.                 ip->pos = 0;
  458.                 ip->fpd = 0;
  459.                 break;
  460.  
  461.             case 'C':            /* x coord */
  462.                 ip->curx = MIN(ip->pos, ip->cols-1);
  463.                 ip->pos = 0;
  464.                 ip->escape = 0;
  465.                 (*sp->ite_cursor)(ip, MOVE_CURSOR);
  466.                 clr_attr(ip, ATTR_INV);
  467.                 break;
  468.  
  469.             default:         /* Possibly a 3 digit number. */
  470.                 if (c >= '0' && c <= '9' && ip->fpd < 3) {
  471.                     ip->pos = ip->pos * 10 + (c - '0');
  472.                     ip->fpd++;
  473.                 } else {
  474.                     ip->pos = 0;
  475.                     ip->escape = 0;
  476.                 }
  477.                 break;
  478.             }
  479.             return;
  480.  
  481.         case 'd':                /* attribute change */
  482.             switch (c) {
  483.  
  484.             case 'B':
  485.                 set_attr(ip, ATTR_INV);
  486.                 break;
  487.                 case 'D':
  488.                 /* XXX: we don't do anything for underline */
  489.                 set_attr(ip, ATTR_UL);
  490.                 break;
  491.                 case '@':
  492.                 clr_attr(ip, ATTR_ALL);
  493.                 break;
  494.             }
  495.             ip->escape = 0;
  496.             return;
  497.  
  498.         case 's':                /* keypad control */
  499.             switch (ip->fpd) {
  500.  
  501.             case 0:
  502.                 ip->hold = c;
  503.                 ip->fpd++;
  504.                 return;
  505.  
  506.             case 1:
  507.                 if (c == 'A') {
  508.                     switch (ip->hold) {
  509.     
  510.                     case '0':
  511.                         clr_attr(ip, ATTR_KPAD);
  512.                         break;
  513.                     case '1':
  514.                         set_attr(ip, ATTR_KPAD);
  515.                         break;
  516.                     }
  517.                 }
  518.                 ip->hold = 0;
  519.             }
  520.             ip->escape = 0;
  521.             return;
  522.  
  523.         case 'i':            /* back tab */
  524.             if (ip->curx > TABSIZE) {
  525.                 n = ip->curx - (ip->curx & (TABSIZE - 1));
  526.                 ip->curx -= n;
  527.             } else
  528.                 ip->curx = 0;
  529.             (*sp->ite_cursor)(ip, MOVE_CURSOR);
  530.             ip->escape = 0;
  531.             return;
  532.  
  533.         case '3':            /* clear all tabs */
  534.             goto ignore;
  535.  
  536.         case 'K':            /* clear_eol */
  537.             ite_clrtoeol(ip, sp, ip->cury, ip->curx);
  538.             ip->escape = 0;
  539.             return;
  540.  
  541.         case 'J':            /* clear_eos */
  542.             ite_clrtoeos(ip, sp);
  543.             ip->escape = 0;
  544.             return;
  545.  
  546.         case 'B':            /* cursor down 1 line */
  547.             if (++ip->cury == ip->rows) {
  548.                 --ip->cury;
  549.                 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
  550.                 ite_clrtoeol(ip, sp, ip->cury, 0);
  551.             }
  552.             else
  553.                 (*sp->ite_cursor)(ip, MOVE_CURSOR);
  554.             clr_attr(ip, ATTR_INV);
  555.             ip->escape = 0;
  556.             return;
  557.  
  558.         case 'C':            /* cursor forward 1 char */
  559.             ip->escape = 0;
  560.             itecheckwrap(ip, sp);
  561.             return;
  562.  
  563.         case 'A':            /* cursor up 1 line */
  564.             if (ip->cury > 0) {
  565.                 ip->cury--;
  566.                 (*sp->ite_cursor)(ip, MOVE_CURSOR);
  567.             }
  568.             ip->escape = 0;
  569.             clr_attr(ip, ATTR_INV);
  570.             return;
  571.  
  572.         case 'P':            /* delete character */
  573.             ite_dchar(ip, sp);
  574.             ip->escape = 0;
  575.             return;
  576.  
  577.         case 'M':            /* delete line */
  578.             ite_dline(ip, sp);
  579.             ip->escape = 0;
  580.             return;
  581.  
  582.         case 'Q':            /* enter insert mode */
  583.             ip->imode = 1;
  584.             ip->escape = 0;
  585.             return;
  586.  
  587.         case 'R':            /* exit insert mode */
  588.             ip->imode = 0;
  589.             ip->escape = 0;
  590.             return;
  591.  
  592.         case 'L':            /* insert blank line */
  593.             ite_iline(ip, sp);
  594.             ip->escape = 0;
  595.             return;
  596.  
  597.         case 'h':            /* home key */
  598.             ip->cury = ip->curx = 0;
  599.             (*sp->ite_cursor)(ip, MOVE_CURSOR);
  600.             ip->escape = 0;
  601.             return;
  602.  
  603.         case 'D':            /* left arrow key */
  604.             if (ip->curx > 0) {
  605.                 ip->curx--;
  606.                 (*sp->ite_cursor)(ip, MOVE_CURSOR);
  607.             }
  608.             ip->escape = 0;
  609.             return;
  610.  
  611.         case '1':            /* set tab in all rows */
  612.             goto ignore;
  613.  
  614.         case ESC:
  615.             if ((ip->escape = c) == ESC)
  616.                 break;
  617.             ip->fpd = 0;
  618.             goto doesc;
  619.  
  620.         default:
  621. ignore:
  622.             ip->escape = 0;
  623.             return;
  624.  
  625.         }
  626.     }
  627.  
  628.     switch (c &= 0x7F) {
  629.  
  630.     case '\n':
  631.  
  632.         if (++ip->cury == ip->rows) {
  633.             --ip->cury;
  634.             (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
  635.             ite_clrtoeol(ip, sp, ip->cury, 0);
  636.         }
  637.         else
  638.             (*sp->ite_cursor)(ip, MOVE_CURSOR);
  639.         clr_attr(ip, ATTR_INV);
  640.         break;
  641.  
  642.     case '\r':
  643.         if (ip->curx) {
  644.             ip->curx = 0;
  645.             (*sp->ite_cursor)(ip, MOVE_CURSOR);
  646.         }
  647.         break;
  648.     
  649.     case '\b':
  650.         if (--ip->curx < 0)
  651.             ip->curx = 0;
  652.         else
  653.             (*sp->ite_cursor)(ip, MOVE_CURSOR);
  654.         break;
  655.  
  656.     case '\t':
  657.         if (ip->curx < TABEND(unit)) {
  658.             n = TABSIZE - (ip->curx & (TABSIZE - 1));
  659.             ip->curx += n;
  660.             (*sp->ite_cursor)(ip, MOVE_CURSOR);
  661.         } else
  662.             itecheckwrap(ip, sp);
  663.         break;
  664.  
  665.     case CTRL('G'):
  666.         if (&ite_tty[unit] == kbd_tty)
  667.             kbdbell();
  668.         break;
  669.  
  670.     case ESC:
  671.         ip->escape = ESC;
  672.         break;
  673.  
  674.     default:
  675.         if (c < ' ' || c == DEL)
  676.             break;
  677.         if (ip->imode)
  678.             ite_ichar(ip, sp);
  679.         if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
  680.             attrset(ip, ATTR_INV);
  681.             (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
  682.         }            
  683.         else
  684.             (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
  685.         (*sp->ite_cursor)(ip, DRAW_CURSOR);
  686.         itecheckwrap(ip, sp);
  687.         break;
  688.     }
  689. }
  690.  
  691. itecheckwrap(ip, sp)
  692.      register struct ite_softc *ip;
  693.      register struct itesw *sp;
  694. {
  695.     if (++ip->curx == ip->cols) {
  696.         ip->curx = 0;
  697.         clr_attr(ip, ATTR_INV);
  698.         if (++ip->cury == ip->rows) {
  699.             --ip->cury;
  700.             (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
  701.             ite_clrtoeol(ip, sp, ip->cury, 0);
  702.             return;
  703.         }
  704.     }
  705.     (*sp->ite_cursor)(ip, MOVE_CURSOR);
  706. }
  707.  
  708. ite_dchar(ip, sp)
  709.      register struct ite_softc *ip;
  710.      register struct itesw *sp;
  711. {
  712.     (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT);
  713.     attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx,
  714.         1, ip->cols - ip->curx - 1);
  715.     attrclr(ip, ip->cury, ip->cols - 1, 1, 1);
  716.     (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR);
  717.     (*sp->ite_cursor)(ip, DRAW_CURSOR);
  718. }
  719.  
  720. ite_ichar(ip, sp)
  721.      register struct ite_softc *ip;
  722.      register struct itesw *sp;
  723. {
  724.     (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT);
  725.     attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1,
  726.         1, ip->cols - ip->curx - 1);
  727.     attrclr(ip, ip->cury, ip->curx, 1, 1);
  728.     (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR);
  729.     (*sp->ite_cursor)(ip, DRAW_CURSOR);
  730. }
  731.  
  732. ite_dline(ip, sp)
  733.      register struct ite_softc *ip;
  734.      register struct itesw *sp;
  735. {
  736.     (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP);
  737.     attrmov(ip, ip->cury + 1, 0, ip->cury, 0,
  738.         ip->rows - ip->cury - 1, ip->cols);
  739.     ite_clrtoeol(ip, sp, ip->rows - 1, 0);
  740. }
  741.  
  742. ite_iline(ip, sp)
  743.      register struct ite_softc *ip;
  744.      register struct itesw *sp;
  745. {
  746.     (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN);
  747.     attrmov(ip, ip->cury, 0, ip->cury + 1, 0,
  748.         ip->rows - ip->cury - 1, ip->cols);
  749.     ite_clrtoeol(ip, sp, ip->cury, 0);
  750. }
  751.  
  752. ite_clrtoeol(ip, sp, y, x)
  753.      register struct ite_softc *ip;
  754.      register struct itesw *sp;
  755.      register int y, x;
  756. {
  757.     (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
  758.     attrclr(ip, y, x, 1, ip->cols - x);
  759.     (*sp->ite_cursor)(ip, DRAW_CURSOR);
  760. }
  761.  
  762. ite_clrtoeos(ip, sp)
  763.      register struct ite_softc *ip;
  764.      register struct itesw *sp;
  765. {
  766.     (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
  767.     attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
  768.     (*sp->ite_cursor)(ip, DRAW_CURSOR);
  769. }
  770.  
  771. /*
  772.  * Console functions
  773.  */
  774. #include "../hp300/cons.h"
  775. #include "grfioctl.h"
  776. #include "grfvar.h"
  777.  
  778. #ifdef DEBUG
  779. /*
  780.  * Minimum ITE number at which to start looking for a console.
  781.  * Setting to 0 will do normal search, 1 will skip first ITE device,
  782.  * NITE will skip ITEs and use serial port.
  783.  */
  784. int    whichconsole = 0;
  785. #endif
  786.  
  787. itecnprobe(cp)
  788.     struct consdev *cp;
  789. {
  790.     register struct ite_softc *ip;
  791.     int i, maj, unit, pri;
  792.  
  793.     /* locate the major number */
  794.     for (maj = 0; maj < nchrdev; maj++)
  795.         if (cdevsw[maj].d_open == iteopen)
  796.             break;
  797.  
  798.     /* urk! */
  799.     grfconfig();
  800.  
  801.     /* check all the individual displays and find the best */
  802.     unit = -1;
  803.     pri = CN_DEAD;
  804.     for (i = 0; i < NITE; i++) {
  805.         struct grf_softc *gp = &grf_softc[i];
  806.  
  807.         ip = &ite_softc[i];
  808.         if ((gp->g_flags & GF_ALIVE) == 0)
  809.             continue;
  810.         ip->flags = (ITE_ALIVE|ITE_CONSOLE);
  811.  
  812.         /* XXX - we need to do something about mapping these */
  813.         switch (gp->g_type) {
  814.  
  815.         case GT_TOPCAT:
  816.         case GT_LRCATSEYE:
  817.         case GT_HRCCATSEYE:
  818.         case GT_HRMCATSEYE:
  819.             ip->type = ITE_TOPCAT;
  820.             break;
  821.         case GT_GATORBOX:
  822.             ip->type = ITE_GATORBOX;
  823.             break;
  824.         case GT_RENAISSANCE:
  825.             ip->type = ITE_RENAISSANCE;
  826.             break;
  827.         case GT_DAVINCI:
  828.             ip->type = ITE_DAVINCI;
  829.             break;
  830.         }
  831. #ifdef DEBUG
  832.         if (i < whichconsole)
  833.             continue;
  834. #endif
  835.         if ((int)gp->g_display.gd_regaddr == GRFIADDR) {
  836.             pri = CN_INTERNAL;
  837.             unit = i;
  838.         } else if (unit < 0) {
  839.             pri = CN_NORMAL;
  840.             unit = i;
  841.         }
  842.     }
  843.  
  844.     /* initialize required fields */
  845.     cp->cn_dev = makedev(maj, unit);
  846.     cp->cn_tp = &ite_tty[unit];
  847.     cp->cn_pri = pri;
  848. }
  849.  
  850. itecninit(cp)
  851.     struct consdev *cp;
  852. {
  853.     int unit = UNIT(cp->cn_dev);
  854.     struct ite_softc *ip = &ite_softc[unit];
  855.  
  856.     ip->attrbuf = console_attributes;
  857.     iteinit(cp->cn_dev);
  858.     ip->flags |= (ITE_ACTIVE|ITE_ISCONS);
  859.     kbd_tty = &ite_tty[unit];
  860. }
  861.  
  862. /*ARGSUSED*/
  863. itecngetc(dev)
  864.     dev_t dev;
  865. {
  866.     register int c;
  867.     int stat;
  868.  
  869.     c = kbdgetc(&stat);
  870.     switch ((stat >> KBD_SSHIFT) & KBD_SMASK) {
  871.     case KBD_SHIFT:
  872.         c = kbd_shiftmap[c & KBD_CHARMASK];
  873.         break;
  874.     case KBD_CTRL:
  875.         c = kbd_ctrlmap[c & KBD_CHARMASK];
  876.         break;
  877.     case KBD_KEY:
  878.         c = kbd_keymap[c & KBD_CHARMASK];
  879.         break;
  880.     default:
  881.         c = 0;
  882.         break;
  883.     }
  884.     return(c);
  885. }
  886.  
  887. itecnputc(dev, c)
  888.     dev_t dev;
  889.     int c;
  890. {
  891.     static int paniced = 0;
  892.     struct ite_softc *ip = &ite_softc[UNIT(dev)];
  893.     extern char *panicstr;
  894.  
  895.     if (panicstr && !paniced &&
  896.         (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
  897.         (void) iteon(dev, 3);
  898.         paniced = 1;
  899.     }
  900.     iteputchar(c, dev);
  901. }
  902. #endif
  903.