Annotation of Net2/arch/amiga/dev/ite.c, revision 1.1.1.1

1.1       root        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:  *     from: @(#)ite.c 7.6 (Berkeley) 5/16/91
                     41:  *     ite.c,v 1.1.1.1 1993/07/05 19:19:44 mw Exp
                     42:  */
                     43: 
                     44: /*
                     45:  * Bit-mapped display terminal emulator machine independent code.
                     46:  * This is a very rudimentary.  Much more can be abstracted out of
                     47:  * the hardware dependent routines.
                     48:  */
                     49: #include "ite.h"
                     50: #if NITE > 0
                     51: 
                     52: #include "grf.h"
                     53: 
                     54: #undef NITE
                     55: #define NITE   NGRF
                     56: 
                     57: #include "param.h"
                     58: #include "conf.h"
                     59: #include "proc.h"
                     60: #include "ioctl.h"
                     61: #include "tty.h"
                     62: #include "systm.h"
                     63: #include "malloc.h"
                     64: 
                     65: #include "itevar.h"
                     66: #include "iteioctl.h"
                     67: #include "kbdmap.h"
                     68: 
                     69: #include "machine/cpu.h"
                     70: 
                     71: #ifdef __STDC__
                     72: /* automatically generated, as you might guess:-) */
                     73: 
                     74: struct consdev;
                     75: struct itesw;
                     76: 
                     77: extern int iteon (dev_t dev, int flag);
                     78: extern int iteinit (dev_t dev);
                     79: extern int iteoff (dev_t dev, int flag);
                     80: extern int iteopen (dev_t dev, int mode, int devtype, struct proc *p);
                     81: extern int iteclose (dev_t dev, int flag, int mode, struct proc *p);
                     82: extern int iteread (dev_t dev, struct uio *uio, int flag);
                     83: extern int itewrite (dev_t dev, struct uio *uio, int flag);
                     84: extern int iteioctl (dev_t dev, int cmd, caddr_t addr, int flag);
                     85: extern int itestart (register struct tty *tp);
                     86: extern int itefilter (register u_char c, enum caller caller);
                     87: extern int iteputchar (register int c, dev_t dev);
                     88: extern int itecheckwrap (register struct ite_softc *ip, register struct itesw *sp);
                     89: extern int itecnprobe (struct consdev *cp);
                     90: extern int itecninit (struct consdev *cp);
                     91: extern int itecngetc (dev_t dev);
                     92: extern int itecnputc (dev_t dev, int c);
                     93: static void repeat_handler (int a0, int a1);
                     94: static void ite_dnchar (struct ite_softc *ip, struct itesw *sp, int n);
                     95: static void ite_inchar (struct ite_softc *ip, struct itesw *sp, int n);
                     96: static void ite_clrtoeol (struct ite_softc *ip, struct itesw *sp, int y, int x);
                     97: static void ite_clrtobol (struct ite_softc *ip, struct itesw *sp, int y, int x);
                     98: static void ite_clrline (struct ite_softc *ip, struct itesw *sp, int y, int x);
                     99: static void ite_clrtoeos (struct ite_softc *ip, struct itesw *sp);
                    100: static void ite_clrtobos (struct ite_softc *ip, struct itesw *sp);
                    101: static void ite_clrscreen (struct ite_softc *ip, struct itesw *sp);
                    102: static void ite_dnline (struct ite_softc *ip, struct itesw *sp, int n);
                    103: static void ite_inline (struct ite_softc *ip, struct itesw *sp, int n);
                    104: static void ite_lf (struct ite_softc *ip, struct itesw *sp);
                    105: static void ite_crlf (struct ite_softc *ip, struct itesw *sp);
                    106: static void ite_cr (struct ite_softc *ip, struct itesw *sp);
                    107: static void ite_rlf (struct ite_softc *ip, struct itesw *sp);
                    108: static int atoi (const char *cp);
                    109: static char *index (const char *cp, char ch);
                    110: static int ite_argnum (struct ite_softc *ip);
                    111: static int ite_zargnum (struct ite_softc *ip);
                    112: static void ite_sendstr (struct ite_softc *ip, char *str);
                    113: static int strncmp (const char *a, const char *b, int l);
                    114: #endif
                    115: 
                    116: 
                    117: #define set_attr(ip, attr)     ((ip)->attribute |= (attr))
                    118: #define clr_attr(ip, attr)     ((ip)->attribute &= ~(attr))
                    119: 
                    120: extern  int nodev();
                    121: 
                    122: int customc_scroll(),  customc_init(),         customc_deinit();
                    123: int customc_clear(),   customc_putc(),         customc_cursor();
                    124: 
                    125: int tiga_scroll(),     tiga_init(),            tiga_deinit();
                    126: int tiga_clear(),      tiga_putc(),            tiga_cursor();
                    127: 
                    128: 
                    129: struct itesw itesw[] =
                    130: {
                    131:        customc_init,           customc_deinit,         customc_clear,
                    132:        customc_putc,           customc_cursor,         customc_scroll,
                    133:        
                    134:        tiga_init,              tiga_deinit,            tiga_clear,
                    135:        tiga_putc,              tiga_cursor,            tiga_scroll,
                    136: };
                    137: 
                    138: /*
                    139:  * # of chars are output in a single itestart() call.
                    140:  * If this is too big, user processes will be blocked out for
                    141:  * long periods of time while we are emptying the queue in itestart().
                    142:  * If it is too small, console output will be very ragged.
                    143:  */
                    144: int    iteburst = 64;
                    145: 
                    146: int    nite = NITE;
                    147: struct  tty *kbd_tty = NULL;
                    148: struct tty ite_cons;
                    149: struct tty *ite_tty[NITE] = { &ite_cons };
                    150: struct  ite_softc ite_softc[NITE];
                    151: 
                    152: int    itestart();
                    153: extern int ttrstrt();
                    154: extern struct tty *constty;
                    155: 
                    156: /* These are (later..) settable via an ioctl */
                    157: int    start_repeat_timo = 30; /* /100: initial timeout till pressed key repeats */
                    158: int    next_repeat_timo  = 5;  /* /100: timeout when repeating for next char */
                    159: 
                    160: /*
                    161:  * Primary attribute buffer to be used by the first bitmapped console
                    162:  * found. Secondary displays alloc the attribute buffer as needed.
                    163:  * Size is based on a 68x128 display, which is currently our largest.
                    164:  */
                    165: u_char  console_attributes[0x2200];
                    166: 
                    167: /*
                    168:  * Perform functions necessary to setup device as a terminal emulator.
                    169:  */
                    170: iteon(dev, flag)
                    171:        dev_t dev;
                    172: {
                    173:        int unit = UNIT(dev);
                    174:        struct tty *tp = ite_tty[unit];
                    175:        struct ite_softc *ip = &ite_softc[unit];
                    176: 
                    177:        if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0)
                    178:                return(ENXIO);
                    179:        /* force ite active, overriding graphics mode */
                    180:        if (flag & 1) {
                    181:                ip->flags |= ITE_ACTIVE;
                    182:                ip->flags &= ~(ITE_INGRF|ITE_INITED);
                    183:        }
                    184:        /* leave graphics mode */
                    185:        if (flag & 2) {
                    186:                ip->flags &= ~ITE_INGRF;
                    187:                if ((ip->flags & ITE_ACTIVE) == 0)
                    188:                        return(0);
                    189:        }
                    190:        ip->flags |= ITE_ACTIVE;
                    191:        if (ip->flags & ITE_INGRF)
                    192:                return(0);
                    193:        if (kbd_tty == NULL || kbd_tty == tp) {
                    194:                kbd_tty = tp;
                    195:                kbdenable();
                    196:        }
                    197:        iteinit(dev);
                    198:        return(0);
                    199: }
                    200: 
                    201: /* used by the grf layer to reinitialize ite after changing fb parameters */
                    202: itereinit(dev)
                    203:      dev_t dev;
                    204: {
                    205:   int unit = UNIT(dev);
                    206:   struct ite_softc *ip = &ite_softc[unit];
                    207: 
                    208:   ip->flags &= ~ITE_INITED;
                    209:   iteinit (dev);
                    210: }
                    211: 
                    212: iteinit(dev)
                    213:      dev_t dev;
                    214: {
                    215:        int unit = UNIT(dev);
                    216:        struct ite_softc *ip = &ite_softc[unit];
                    217: 
                    218:        if (ip->flags & ITE_INITED)
                    219:                return;
                    220:        
                    221:        ip->curx = 0;
                    222:        ip->cury = 0;
                    223:        ip->cursorx = 0;
                    224:        ip->cursory = 0;
                    225:        ip->save_curx = 0;
                    226:        ip->save_cury = 0;
                    227:        ip->ap = ip->argbuf;
                    228:        ip->emul_level = EMUL_VT300_7;
                    229:        ip->eightbit_C1 = 0;
                    230:        ip->inside_margins = 0;
                    231:        ip->linefeed_newline = 0;
                    232: 
                    233:        (*itesw[ip->type].ite_init)(ip);
                    234:        (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
                    235: 
                    236:        /* ip->rows initialized by ite_init above */
                    237:        ip->top_margin = 0; ip->bottom_margin = ip->rows - 1;
                    238: 
                    239:        ip->attribute = 0;
                    240:        if (ip->attrbuf == NULL)
                    241:                ip->attrbuf = (u_char *)
                    242:                        malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK);
                    243:        bzero(ip->attrbuf, (ip->rows * ip->cols));
                    244: 
                    245:        ip->imode = 0;
                    246:        ip->flags |= ITE_INITED;
                    247: }
                    248: 
                    249: /*
                    250:  * "Shut down" device as terminal emulator.
                    251:  * Note that we do not deinit the console device unless forced.
                    252:  * Deinit'ing the console every time leads to a very active
                    253:  * screen when processing /etc/rc.
                    254:  */
                    255: iteoff(dev, flag)
                    256:        dev_t dev;
                    257: {
                    258:        register struct ite_softc *ip = &ite_softc[UNIT(dev)];
                    259: 
                    260:        if (flag & 2)
                    261:                ip->flags |= ITE_INGRF;
                    262:        if ((ip->flags & ITE_ACTIVE) == 0)
                    263:                return;
                    264:        if ((flag & 1) ||
                    265:            (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
                    266:                (*itesw[ip->type].ite_deinit)(ip);
                    267:        if ((flag & 2) == 0)
                    268:                ip->flags &= ~ITE_ACTIVE;
                    269: }
                    270: 
                    271: /* ARGSUSED */
                    272: #ifdef __STDC__
                    273: iteopen(dev_t dev, int mode, int devtype, struct proc *p)
                    274: #else
                    275: iteopen(dev, mode, devtype, p)
                    276:        dev_t dev;
                    277:        int mode, devtype;
                    278:        struct proc *p;
                    279: #endif
                    280: {
                    281:        int unit = UNIT(dev);
                    282:        register struct tty *tp;
                    283:        register struct ite_softc *ip = &ite_softc[unit];
                    284:        register int error;
                    285:        int first = 0;
                    286: 
                    287:        if(!ite_tty[unit]) {
                    288:                MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
                    289:                bzero(tp, sizeof(struct tty));
                    290:                ite_tty[unit] = tp;
                    291:        } else
                    292:                tp = ite_tty[unit];
                    293: 
                    294:        if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)
                    295:            && p->p_ucred->cr_uid != 0)
                    296:                return (EBUSY);
                    297:        if ((ip->flags & ITE_ACTIVE) == 0) {
                    298:                error = iteon(dev, 0);
                    299:                if (error)
                    300:                        return (error);
                    301:                first = 1;
                    302:        }
                    303:        tp->t_oproc = itestart;
                    304:        tp->t_param = NULL;
                    305:        tp->t_dev = dev;
                    306:        if ((tp->t_state&TS_ISOPEN) == 0) {
                    307:                ttychars(tp);
                    308:                tp->t_iflag = TTYDEF_IFLAG;
                    309:                tp->t_oflag = TTYDEF_OFLAG;
                    310:                tp->t_cflag = CS8|CREAD;
                    311:                tp->t_lflag = TTYDEF_LFLAG;
                    312:                tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
                    313:                /* don't set TS_ISOPEN  here, or the tty queues won't
                    314:                   be initialized in ttyopen()! */
                    315:                tp->t_state = TS_CARR_ON;
                    316:                ttsetwater(tp);
                    317:        } 
                    318:        error = (*linesw[tp->t_line].l_open)(dev, tp);
                    319:        if (error == 0) {
                    320:                tp->t_winsize.ws_row = ip->rows;
                    321:                tp->t_winsize.ws_col = ip->cols;
                    322:        } else if (first)
                    323:                iteoff(dev, 0);
                    324:        return (error);
                    325: }
                    326: 
                    327: /*ARGSUSED*/
                    328: iteclose(dev, flag, mode, p)
                    329:        dev_t dev;
                    330:        int flag, mode;
                    331:        struct proc *p;
                    332: {
                    333:        register struct tty *tp = ite_tty[UNIT(dev)];
                    334: 
                    335:        (*linesw[tp->t_line].l_close)(tp, flag);
                    336:        ttyclose(tp);
                    337:        iteoff(dev, 0);
                    338:        if (tp != &ite_cons)
                    339:          {
                    340:            FREE(tp, M_TTYS);
                    341:            ite_tty[UNIT(dev)] = (struct tty *)NULL;
                    342:          }
                    343:        return(0);
                    344: }
                    345: 
                    346: iteread(dev, uio, flag)
                    347:        dev_t dev;
                    348:        struct uio *uio;
                    349: {
                    350:        register struct tty *tp = ite_tty[UNIT(dev)];
                    351:        int rc;
                    352: 
                    353:        rc = ((*linesw[tp->t_line].l_read)(tp, uio, flag));
                    354:        return rc;
                    355: }
                    356: 
                    357: itewrite(dev, uio, flag)
                    358:        dev_t dev;
                    359:        struct uio *uio;
                    360: {
                    361:        int unit = UNIT(dev);
                    362:        register struct tty *tp = ite_tty[unit];
                    363: 
                    364:        if ((ite_softc[unit].flags & ITE_ISCONS) && constty &&
                    365:            (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))
                    366:                tp = constty;
                    367:        return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
                    368: }
                    369: 
                    370: iteioctl(dev, cmd, addr, flag)
                    371:        dev_t dev;
                    372:        caddr_t addr;
                    373: {
                    374:        register struct tty *tp = ite_tty[UNIT(dev)];
                    375:        int error;
                    376: 
                    377:        error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag);
                    378:        if (error >= 0)
                    379:                return (error);
                    380:        error = ttioctl(tp, cmd, addr, flag);
                    381:        if (error >= 0)
                    382:                return (error);
                    383:        return (ENOTTY);
                    384: }
                    385: 
                    386: itestart(tp)
                    387:        register struct tty *tp;
                    388: {
                    389:        register int cc, s;
                    390:        int hiwat = 0;
                    391: 
                    392:        s = spltty();
                    393:        if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
                    394:                splx(s);
                    395:                return;
                    396:        }
                    397:        tp->t_state |= TS_BUSY;
                    398:        cc = RB_LEN (&tp->t_out);
                    399:        if (cc <= tp->t_lowat) {
                    400:                if (tp->t_state & TS_ASLEEP) {
                    401:                        tp->t_state &= ~TS_ASLEEP;
                    402:                        wakeup(&tp->t_out);
                    403:                }
                    404:                selwakeup(&tp->t_wsel);
                    405:        }
                    406:        /*
                    407:         * Limit the amount of output we do in one burst
                    408:         * to prevent hogging the CPU.
                    409:         */
                    410:        if (cc > iteburst) {
                    411:                hiwat++;
                    412:                cc = iteburst;
                    413:        }
                    414:        while (--cc >= 0) {
                    415:                register int c;
                    416: 
                    417:                c = rbgetc(&tp->t_out);
                    418:                /*
                    419:                 * iteputchar() may take a long time and we don't want to
                    420:                 * block all interrupts for long periods of time.  Since
                    421:                 * there is no need to stay at high priority while outputing
                    422:                 * the character (since we don't have to worry about
                    423:                 * interrupts), we don't.  We just need to make sure that
                    424:                 * we don't reenter iteputchar, which is guarenteed by the
                    425:                 * earlier setting of TS_BUSY.
                    426:                 */
                    427:                splx(s);
                    428:                iteputchar(c, tp->t_dev);
                    429:                spltty();
                    430:        }
                    431:        if (hiwat) {
                    432:                tp->t_state |= TS_TIMEOUT;
                    433:                timeout(ttrstrt, tp, 1);
                    434:        }
                    435:        tp->t_state &= ~TS_BUSY;
                    436:        splx(s);
                    437: }
                    438: 
                    439: /* these are used to implement repeating keys.. */
                    440: static u_char last_char = 0;
                    441: static u_char tout_pending = 0;
                    442: 
                    443: static void
                    444: repeat_handler (a0, a1)
                    445:     int a0, a1;
                    446: {
                    447:   tout_pending = 0;
                    448:   /* leave it up to itefilter() to possible install a new callout entry
                    449:      to reinvoke repeat_handler() */
                    450:   itefilter (last_char, ITEFILT_REPEATER);
                    451: }
                    452: 
                    453: 
                    454: int
                    455: itefilter(c, caller)
                    456:      register u_char c;
                    457:      enum caller caller;
                    458: {
                    459:   static u_char mod = 0;
                    460:   static u_char last_dead = 0;
                    461:   register char code, *str;
                    462:   u_char up, mask, i;
                    463:   struct key key;
                    464:   
                    465:   if (caller != ITEFILT_CONSOLE && kbd_tty == NULL)
                    466:      return;
                    467: 
                    468:   up = c & 0x80 ? 1 : 0;
                    469:   c &= 0x7f;
                    470:   code = 0;
                    471:   
                    472:   mask = 0;
                    473:   if (c >= KBD_LEFT_SHIFT)
                    474:     {
                    475:       switch (c)
                    476:         {
                    477:         case KBD_LEFT_SHIFT:
                    478:           mask = KBD_MOD_LSHIFT;
                    479:           break;
                    480: 
                    481:         case KBD_RIGHT_SHIFT:
                    482:           mask = KBD_MOD_RSHIFT;
                    483:           break;
                    484: 
                    485:         case KBD_LEFT_ALT:
                    486:           mask = KBD_MOD_LALT;
                    487:           break;
                    488:     
                    489:         case KBD_RIGHT_ALT:
                    490:           mask = KBD_MOD_RALT;
                    491:           break;
                    492:       
                    493:         case KBD_LEFT_META:
                    494:           mask = KBD_MOD_LMETA;
                    495:           break;
                    496: 
                    497:         case KBD_RIGHT_META:
                    498:           mask = KBD_MOD_RMETA;
                    499:           break;
                    500: 
                    501:         case KBD_CAPS_LOCK:    
                    502:           /* capslock already behaves `right', don't need to keep track of the
                    503:              state in here. */
                    504:           mask = KBD_MOD_CAPS;
                    505:           break;
                    506:  
                    507:         case KBD_CTRL:
                    508:           mask = KBD_MOD_CTRL;
                    509:           break;
                    510:         }
                    511: 
                    512:       if (mask)
                    513:         {
                    514:           if (up)
                    515:             mod &= ~mask;
                    516:           else
                    517:             mod |= mask;
                    518:         }
                    519: 
                    520:       /* these keys should not repeat, so it's the Right Thing dealing with
                    521:          repeaters only after this block. */
                    522: 
                    523:       /* return even if it wasn't a modifier key, the other codes up here
                    524:          are either special (like reset warning), or not yet defined */
                    525:       return -1;
                    526:     }  
                    527: 
                    528:   /* no matter which character we're repeating, stop it if we get a key-up
                    529:      event. I think this is the same thing amigados does. */
                    530:   if (up)
                    531:     {
                    532:       if (tout_pending)
                    533:         {
                    534:           untimeout (repeat_handler, 0);
                    535:           tout_pending = 0;
                    536:         }
                    537:       return -1;
                    538:     }
                    539: 
                    540: 
                    541:   switch (mod & (KBD_MOD_ALT | KBD_MOD_SHIFT))
                    542:     {
                    543:     case 0:
                    544:        key = kbdmap.keys[c];
                    545:        if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS))
                    546:          break;
                    547:        /* FALL INTO */
                    548:        
                    549:     case KBD_MOD_LSHIFT:
                    550:     case KBD_MOD_RSHIFT:
                    551:     case KBD_MOD_SHIFT:
                    552:         key = kbdmap.shift_keys[c];
                    553:         break;
                    554:         
                    555:     case KBD_MOD_LALT:
                    556:     case KBD_MOD_RALT:
                    557:     case KBD_MOD_ALT:
                    558:        key = kbdmap.alt_keys[c];
                    559:        if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS))
                    560:          break;
                    561:        /* FALL INTO */
                    562: 
                    563:     case KBD_MOD_LALT|KBD_MOD_LSHIFT:
                    564:     case KBD_MOD_LALT|KBD_MOD_RSHIFT:
                    565:     case KBD_MOD_LALT|KBD_MOD_SHIFT:
                    566:     case KBD_MOD_RALT|KBD_MOD_RSHIFT:
                    567:     case KBD_MOD_RALT|KBD_MOD_SHIFT:
                    568:     case KBD_MOD_ALT|KBD_MOD_RSHIFT:
                    569:        key = kbdmap.alt_shift_keys[c];
                    570:        break;
                    571:     }
                    572: 
                    573:   code = key.code;
                    574: 
                    575:   /* arrange to repeat the keystroke. By doing this at the level of scan-codes,
                    576:      we can have function keys, and keys that send strings, repeat too. This
                    577:      also entitles an additional overhead, since we have to do the conversion
                    578:      each time, but I guess that's ok. */
                    579:   if (!tout_pending && caller == ITEFILT_TTY)
                    580:     {
                    581:       tout_pending = 1;
                    582:       last_char = c;
                    583:       timeout (repeat_handler, 0, start_repeat_timo);
                    584:     }
                    585:   else if (!tout_pending && caller == ITEFILT_REPEATER)
                    586:     {
                    587:       tout_pending = 1;
                    588:       last_char = c;
                    589:       timeout (repeat_handler, 0, next_repeat_timo);
                    590:     }
                    591:  
                    592:   /* handle dead keys */
                    593:   if (key.mode & KBD_MODE_DEAD)
                    594:     {
                    595:       /* if entered twice, send accent itself */
                    596:       if (last_dead == key.mode & KBD_MODE_ACCMASK)
                    597:         last_dead = 0;
                    598:       else
                    599:        {
                    600:          last_dead = key.mode & KBD_MODE_ACCMASK;
                    601:          return -1;
                    602:        }
                    603:     }
                    604:   if (last_dead)
                    605:     {
                    606:       /* can't apply dead flag to string-keys */
                    607:       if (! (key.mode & KBD_MODE_STRING) && code >= '@' && code < 0x7f)
                    608:         code = acctable[KBD_MODE_ACCENT (last_dead)][code - '@'];
                    609: 
                    610:       last_dead = 0;
                    611:     }
                    612:   
                    613:   /* if not string, apply META and CTRL modifiers */
                    614:   if (! (key.mode & KBD_MODE_STRING))
                    615:     {
                    616:       if (mod & KBD_MOD_CTRL)
                    617:         code &= 0x1f;
                    618: 
                    619:       if (mod & KBD_MOD_META)
                    620:         code |= 0x80;
                    621:     }
                    622:   else
                    623:     {
                    624:       /* strings are only supported in normal tty mode, not in console mode */
                    625:       if (caller != ITEFILT_CONSOLE)
                    626:         {
                    627:           str = kbdmap.strings + code;
                    628:           /* using a length-byte instead of 0-termination allows to embed \0 into
                    629:              strings, although this is not used in the default keymap */
                    630:           for (i = *str++; i; i--)
                    631:             (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);
                    632:         }
                    633:       return -1;
                    634:     }
                    635: 
                    636:   if (caller == ITEFILT_CONSOLE)
                    637:     return code;
                    638:   else
                    639:     (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
                    640: 
                    641:   return -1;
                    642: }
                    643: 
                    644: 
                    645: /* helper functions, makes the code below more readable */
                    646: static void inline
                    647: ite_dnchar(ip, sp, n)
                    648:      struct ite_softc *ip;
                    649:      struct itesw *sp;
                    650:      int n;
                    651: {
                    652:   (*sp->ite_scroll)(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT);
                    653:   attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx,
                    654:          1, ip->cols - ip->curx - n);
                    655:   attrclr(ip, ip->cury, ip->cols - n, 1, n);
                    656:   while (n--)
                    657:     (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR);
                    658:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    659: }
                    660: 
                    661: static void inline
                    662: ite_inchar(ip, sp, n)
                    663:      struct ite_softc *ip;
                    664:      struct itesw *sp;
                    665:      int n;
                    666: {
                    667:   (*sp->ite_scroll)(ip, ip->cury, ip->curx, n, SCROLL_RIGHT);
                    668:   attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n,
                    669:          1, ip->cols - ip->curx - n);
                    670:   attrclr(ip, ip->cury, ip->curx, 1, n);
                    671:   while (n--)
                    672:     (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
                    673:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    674: }
                    675: 
                    676: static void inline
                    677: ite_clrtoeol(ip, sp, y, x)
                    678:      struct ite_softc *ip;
                    679:      struct itesw *sp;
                    680:      int y, x;
                    681: {
                    682:   (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
                    683:   attrclr(ip, y, x, 1, ip->cols - x);
                    684:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    685: }
                    686: 
                    687: static void inline
                    688: ite_clrtobol(ip, sp, y, x)
                    689:      struct ite_softc *ip;
                    690:      struct itesw *sp;
                    691:      int y, x;
                    692: {
                    693:   (*sp->ite_clear)(ip, y, 0, 1, x);
                    694:   attrclr(ip, y, 0, 1, x);
                    695:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    696: }
                    697: 
                    698: static void inline
                    699: ite_clrline(ip, sp, y, x)
                    700:      struct ite_softc *ip;
                    701:      struct itesw *sp;
                    702:      int y, x;
                    703: {
                    704:   (*sp->ite_clear)(ip, y, 0, 1, ip->cols);
                    705:   attrclr(ip, y, 0, 1, ip->cols);
                    706:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    707: }
                    708: 
                    709: 
                    710: 
                    711: static void inline
                    712: ite_clrtoeos(ip, sp)
                    713:      struct ite_softc *ip;
                    714:      struct itesw *sp;
                    715: {
                    716:   (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
                    717:   attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
                    718:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    719: }
                    720: 
                    721: static void inline
                    722: ite_clrtobos(ip, sp)
                    723:      struct ite_softc *ip;
                    724:      struct itesw *sp;
                    725: {
                    726:   (*sp->ite_clear)(ip, 0, 0, ip->cury, ip->cols);
                    727:   attrclr(ip, 0, 0, ip->cury, ip->cols);
                    728:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    729: }
                    730: 
                    731: static void inline
                    732: ite_clrscreen(ip, sp)
                    733:      struct ite_softc *ip;
                    734:      struct itesw *sp;
                    735: {
                    736:   (*sp->ite_clear)(ip, 0, 0, ip->rows, ip->cols);
                    737:   attrclr(ip, 0, 0, ip->rows, ip->cols);
                    738:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    739: }
                    740: 
                    741: 
                    742: 
                    743: static void inline
                    744: ite_dnline(ip, sp, n)
                    745:      struct ite_softc *ip;
                    746:      struct itesw *sp;
                    747:      int n;
                    748: {
                    749:   (*sp->ite_scroll)(ip, ip->cury + n, 0, n, SCROLL_UP);
                    750:   attrmov(ip, ip->cury + n, 0, ip->cury, 0,
                    751:          ip->bottom_margin + 1 - ip->cury - n, ip->cols);
                    752:   (*sp->ite_clear)(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
                    753:   attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
                    754:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    755: }
                    756: 
                    757: static void inline
                    758: ite_inline(ip, sp, n)
                    759:      struct ite_softc *ip;
                    760:      struct itesw *sp;
                    761:      int n;
                    762: {
                    763:   (*sp->ite_scroll)(ip, ip->cury, 0, n, SCROLL_DOWN);
                    764:   attrmov(ip, ip->cury, 0, ip->cury + n, 0,
                    765:          ip->bottom_margin + 1 - ip->cury - n, ip->cols);
                    766:   (*sp->ite_clear)(ip, ip->cury, 0, n, ip->cols);
                    767:   attrclr(ip, ip->cury, 0, n, ip->cols);
                    768:   (*sp->ite_cursor)(ip, DRAW_CURSOR);
                    769: }
                    770: 
                    771: static void inline
                    772: ite_lf (ip, sp)
                    773:      struct ite_softc *ip;
                    774:      struct itesw *sp;
                    775: {
                    776: #if 0
                    777:   if (ip->inside_margins)
                    778:     {
                    779: #endif
                    780:       if (++ip->cury >= ip->bottom_margin + 1) 
                    781:         {
                    782:           ip->cury = ip->bottom_margin;
                    783:           (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
                    784:           ite_clrtoeol(ip, sp, ip->cury, 0);
                    785:         }
                    786:       else
                    787:         (*sp->ite_cursor)(ip, MOVE_CURSOR);
                    788: #if 0
                    789:     }
                    790:   else
                    791:     {
                    792:       if (++ip->cury == ip->rows) 
                    793:         {
                    794:           --ip->cury;
                    795:           (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
                    796:           ite_clrtoeol(ip, sp, ip->cury, 0);
                    797:         }
                    798:       else
                    799:         (*sp->ite_cursor)(ip, MOVE_CURSOR);
                    800:     }
                    801: #endif
                    802:   clr_attr(ip, ATTR_INV);
                    803: }
                    804: 
                    805: static void inline 
                    806: ite_crlf (ip, sp)
                    807:      struct ite_softc *ip;
                    808:      struct itesw *sp;
                    809: {
                    810:   ip->curx = 0;
                    811:   ite_lf (ip, sp);
                    812: }
                    813: 
                    814: static void inline
                    815: ite_cr (ip, sp)
                    816:      struct ite_softc *ip;
                    817:      struct itesw *sp;
                    818: {
                    819:   if (ip->curx) 
                    820:     {
                    821:       ip->curx = 0;
                    822:       (*sp->ite_cursor)(ip, MOVE_CURSOR);
                    823:     }
                    824: }
                    825: 
                    826: static void inline
                    827: ite_rlf (ip, sp)
                    828:      struct ite_softc *ip;
                    829:      struct itesw *sp;
                    830: {
                    831:   if (ip->cury > 0) 
                    832:     {
                    833:       ip->cury--;
                    834:       (*sp->ite_cursor)(ip, MOVE_CURSOR);
                    835:     }
                    836:   else
                    837:     ite_inline (ip, sp, 1);
                    838:   clr_attr(ip, ATTR_INV);
                    839: }
                    840: 
                    841: static int inline
                    842: atoi (cp)
                    843:     const char *cp;
                    844: {
                    845:   int n;
                    846: 
                    847:   for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++)
                    848:     n = n * 10 + *cp - '0';
                    849: 
                    850:   return n;
                    851: }
                    852: 
                    853: static char *
                    854: index (cp, ch)
                    855:     const char *cp;
                    856:     char ch;
                    857: {
                    858:   while (*cp && *cp != ch) cp++;
                    859:   return *cp ? cp : 0;
                    860: }
                    861: 
                    862: 
                    863: 
                    864: static int inline
                    865: ite_argnum (ip)
                    866:     struct ite_softc *ip;
                    867: {
                    868:   char ch;
                    869:   int n;
                    870: 
                    871:   /* convert argument string into number */
                    872:   if (ip->ap == ip->argbuf)
                    873:     return 1;
                    874:   ch = *ip->ap;
                    875:   *ip->ap = 0;
                    876:   n = atoi (ip->argbuf);
                    877:   *ip->ap = ch;
                    878:   
                    879:   return n;
                    880: }
                    881: 
                    882: static int inline
                    883: ite_zargnum (ip)
                    884:     struct ite_softc *ip;
                    885: {
                    886:   char ch, *cp;
                    887:   int n;
                    888: 
                    889:   /* convert argument string into number */
                    890:   if (ip->ap == ip->argbuf)
                    891:     return 0;
                    892:   ch = *ip->ap;
                    893:   *ip->ap = 0;
                    894:   n = atoi (ip->argbuf);
                    895:   *ip->ap = ch;
                    896:   
                    897:   return n;
                    898: }
                    899: 
                    900: static void inline
                    901: ite_sendstr (ip, str)
                    902:     struct ite_softc *ip;
                    903:     char *str;
                    904: {
                    905:   while (*str)
                    906:     (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty);
                    907: }
                    908: 
                    909: static int inline
                    910: strncmp (a, b, l)
                    911:     const char *a, *b;
                    912:     int l;
                    913: {
                    914:   for (;l--; a++, b++)
                    915:     if (*a != *b)
                    916:       return *a - *b;
                    917:   return 0;
                    918: }
                    919: 
                    920: static void inline
                    921: ite_reinit(ip)
                    922:     struct ite_softc *ip;
                    923: {
                    924:   ip->curx = 0;
                    925:   ip->cury = 0;
                    926:   ip->cursorx = 0;
                    927:   ip->cursory = 0;
                    928:   ip->save_curx = 0;
                    929:   ip->save_cury = 0;
                    930:   ip->ap = ip->argbuf;
                    931:   ip->emul_level = EMUL_VT300_7;
                    932:   ip->eightbit_C1 = 0;
                    933:   ip->top_margin = 0; ip->bottom_margin = 23;
                    934:   ip->inside_margins = 0;
                    935:   ip->linefeed_newline = 0;
                    936: 
                    937:   (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
                    938: 
                    939:   ip->attribute = 0;
                    940:   bzero(ip->attrbuf, (ip->rows * ip->cols));
                    941: 
                    942:   ip->imode = 0;
                    943: }
                    944: 
                    945: 
                    946: 
                    947: iteputchar(c, dev)
                    948:        register int c;
                    949:        dev_t dev;  
                    950: {
                    951:        int unit = UNIT(dev);
                    952:        register struct ite_softc *ip = &ite_softc[unit];
                    953:        register struct itesw *sp = &itesw[ip->type];
                    954:        register int n;
                    955:        int x, y;
                    956:        char *cp;
                    957: 
                    958:        if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
                    959:                return;
                    960: 
                    961:        if ((ite_tty[unit]->t_cflag & CSIZE) == CS7
                    962:            || (ite_tty[unit]->t_cflag & PARENB))
                    963:          c &= 0x7f;
                    964: 
                    965:        if (ip->escape) 
                    966:          {
                    967: doesc:
                    968:            switch (ip->escape) 
                    969:              {
                    970:              case ESC:
                    971:                switch (c)
                    972:                  {
                    973:                  /* first 7bit equivalents for the 8bit control characters */
                    974:                  
                    975:                  case 'D':
                    976:                    c = IND;
                    977:                    ip->escape = 0;
                    978:                    break;
                    979:                    
                    980:                  case 'E':
                    981:                    c = NEL;
                    982:                    ip->escape = 0;
                    983:                    break;
                    984:                    
                    985:                  case 'H':
                    986:                    c = HTS;
                    987:                    ip->escape = 0;
                    988:                    break;
                    989:                    
                    990:                  case 'M':
                    991:                    c = RI;
                    992:                    ip->escape = 0;
                    993:                    break;
                    994:                    
                    995:                  case 'N':
                    996:                    c = SS2;
                    997:                    ip->escape = 0;
                    998:                    break;
                    999:                  
                   1000:                  case 'O':
                   1001:                    c = SS3;
                   1002:                    ip->escape = 0;
                   1003:                    break;
                   1004:                    
                   1005:                  case 'P':
                   1006:                    c = DCS;
                   1007:                    ip->escape = 0;
                   1008:                    break;
                   1009:                    
                   1010:                  case '[':
                   1011:                    c = CSI;
                   1012:                    ip->escape = 0;
                   1013:                    break;
                   1014:                    
                   1015:                  case '\\':
                   1016:                    c = ST;
                   1017:                    ip->escape = 0;
                   1018:                    break;
                   1019:                    
                   1020:                  case ']':
                   1021:                    c = OSC;
                   1022:                    ip->escape = 0;
                   1023:                    break;
                   1024:                    
                   1025:                  case '^':
                   1026:                    c = PM;
                   1027:                    ip->escape = 0;
                   1028:                    break;
                   1029:                    
                   1030:                  case '_':
                   1031:                    c = APC;
                   1032:                    ip->escape = 0;
                   1033:                    break;
                   1034: 
                   1035: 
                   1036:                  /* introduces 7/8bit control */
                   1037:                  case ' ':
                   1038:                     /* can be followed by either F or G */
                   1039:                     ip->escape = ' ';
                   1040:                     break;
                   1041: 
                   1042:                  
                   1043:                  /* a lot of character set selections, not yet used... 
                   1044:                     94-character sets: */
                   1045:                  case '(':     /* G0 */
                   1046:                  case ')':     /* G1 */
                   1047:                  case '*':     /* G2 */
                   1048:                  case '+':     /* G3 */
                   1049:                  case 'B':     /* ASCII */
                   1050:                  case 'A':     /* ISO latin 1 */
                   1051:                  case '<':     /* user preferred suplemental */
                   1052:                  case '0':     /* dec special graphics */
                   1053:                  
                   1054:                  /* 96-character sets: */
                   1055:                  case '-':     /* G1 */
                   1056:                  case '.':     /* G2 */
                   1057:                  case '/':     /* G3 */
                   1058:                  
                   1059:                  /* national character sets: */
                   1060:                  case '4':     /* dutch */
                   1061:                  case '5':
                   1062:                  case 'C':     /* finnish */
                   1063:                  case 'R':     /* french */
                   1064:                  case 'Q':     /* french canadian */
                   1065:                  case 'K':     /* german */
                   1066:                  case 'Y':     /* italian */
                   1067:                  case '6':     /* norwegian/danish */
                   1068:                  case 'Z':     /* spanish */
                   1069:                  case '=':     /* swiss */
                   1070:                  /* note: %5 and %6 are not supported (two chars..) */
                   1071:                    
                   1072:                    ip->escape = 0;
                   1073:                    /* just ignore for now */
                   1074:                    return -1;
                   1075:                    
                   1076:                  
                   1077:                  /* locking shift modes (as you might guess, not yet supported..) */
                   1078:                  case '`':
                   1079:                    ip->GR = ip->G1;
                   1080:                    ip->escape = 0;
                   1081:                    return -1;
                   1082:                    
                   1083:                  case 'n':
                   1084:                    ip->GL = ip->G2;
                   1085:                    ip->escape = 0;
                   1086:                    return -1;
                   1087:                    
                   1088:                  case '}':
                   1089:                    ip->GR = ip->G2;
                   1090:                    ip->escape = 0;
                   1091:                    return -1;
                   1092:                    
                   1093:                  case 'o':
                   1094:                    ip->GL = ip->G3;
                   1095:                    ip->escape = 0;
                   1096:                    return -1;
                   1097:                    
                   1098:                  case '|':
                   1099:                    ip->GR = ip->G3;
                   1100:                    ip->escape = 0;
                   1101:                    return -1;
                   1102:                    
                   1103:                  
                   1104:                  /* font width/height control */
                   1105:                  case '#':
                   1106:                    ip->escape = '#';
                   1107:                    return -1;
                   1108:                    
                   1109:                    
                   1110:                  /* hard terminal reset .. */
                   1111:                  case 'c':
                   1112:                    ite_reinit (ip);
                   1113:                    ip->escape = 0;
                   1114:                    return -1;
                   1115: 
                   1116: 
                   1117:                  case '7':
                   1118:                    ip->save_curx = ip->curx;
                   1119:                    ip->save_cury = ip->cury;
                   1120:                    ip->escape = 0;
                   1121:                    return -1;
                   1122:                    
                   1123:                  case '8':
                   1124:                    ip->curx = ip->save_curx;
                   1125:                    ip->cury = ip->save_cury;
                   1126:                    (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1127:                    ip->escape = 0;
                   1128:                    return -1;
                   1129:                    
                   1130:                  
                   1131:                  /* default catch all for not recognized ESC sequences */
                   1132:                  default:
                   1133:                    ip->escape = 0;
                   1134:                    return -1;
                   1135:                  }
                   1136:                break;
                   1137: 
                   1138: 
                   1139:              case ' ':
                   1140:                switch (c)
                   1141:                  {
                   1142:                  case 'F':
                   1143:                    ip->eightbit_C1 = 0;
                   1144:                    ip->escape = 0;
                   1145:                    return -1;
                   1146:                    
                   1147:                  case 'G':
                   1148:                    ip->eightbit_C1 = 1;
                   1149:                    ip->escape = 0;
                   1150:                    return -1;
                   1151:                    
                   1152:                  default:
                   1153:                    /* not supported */
                   1154:                    ip->escape = 0;
                   1155:                    return -1;
                   1156:                  }
                   1157:                break;
                   1158:                
                   1159:                
                   1160:              case '#':
                   1161:                switch (c)
                   1162:                  {
                   1163:                  case '5':
                   1164:                    /* single height, single width */
                   1165:                    ip->escape = 0;
                   1166:                    return -1;
                   1167:                    
                   1168:                  case '6':
                   1169:                    /* double width, single height */
                   1170:                    ip->escape = 0;
                   1171:                    return -1;
                   1172:                    
                   1173:                  case '3':
                   1174:                    /* top half */
                   1175:                    ip->escape = 0;
                   1176:                    return -1;
                   1177:                    
                   1178:                  case '4':
                   1179:                    /* bottom half */
                   1180:                    ip->escape = 0;
                   1181:                    return -1;
                   1182:                    
                   1183:                  case '8':
                   1184:                    /* screen alignment pattern... */
                   1185:                    ip->escape = 0;
                   1186:                    return -1;
                   1187:                    
                   1188:                  default:
                   1189:                    ip->escape = 0;
                   1190:                    return -1;
                   1191:                  }
                   1192:                break;
                   1193:                  
                   1194: 
                   1195: 
                   1196: #if 0
                   1197:              case DCS:
                   1198:              case PM:
                   1199:              case APC:
                   1200:              case OSC:
                   1201:                switch (c)
                   1202:                  {
                   1203:                  case ST:
                   1204:                    ip->escape = 0;
                   1205:                    return -1;
                   1206:                    
                   1207:                  default:
                   1208:                    return -1;
                   1209:                  }
                   1210:                break;
                   1211: #endif
                   1212: 
                   1213: 
                   1214:              case CSI:
                   1215:                /* the biggie... */
                   1216:                switch (c)
                   1217:                  {
                   1218:                  case '0': case '1': case '2': case '3': case '4':
                   1219:                  case '5': case '6': case '7': case '8': case '9':
                   1220:                  case ';': case '\"': case '$': case '>':
                   1221:                    if (ip->ap < ip->argbuf + ARGBUF_SIZE)
                   1222:                      *ip->ap++ = c;
                   1223:                    return -1;
                   1224: 
                   1225:                  case CAN:
                   1226:                    ip->escape = 0;
                   1227:                    return -1;
                   1228: 
                   1229:                    
                   1230:                  case 'p':
                   1231:                    *ip->ap = 0;
                   1232:                    if (! strncmp (ip->argbuf, "61\"", 3))
                   1233:                      ip->emul_level = EMUL_VT100;
                   1234:                    else if (! strncmp (ip->argbuf, "63;1\"", 5)
                   1235:                             || ! strncmp (ip->argbuf, "62;1\"", 5))
                   1236:                      ip->emul_level = EMUL_VT300_7;
                   1237:                    else
                   1238:                      ip->emul_level = EMUL_VT300_8;
                   1239:                    ip->escape = 0;
                   1240:                    return -1;
                   1241:                    
                   1242:                  
                   1243:                  case '?':
                   1244:                    *ip->ap = 0;
                   1245:                    ip->escape = '?';
                   1246:                    ip->ap = ip->argbuf;
                   1247:                    return -1;
                   1248: 
                   1249: 
                   1250:                  case 'c':
                   1251:                    *ip->ap = 0;
                   1252:                    if (ip->ap == ip->argbuf
                   1253:                        || (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '0'))
                   1254:                      {
                   1255:                        /* primary DA request, send primary DA response */
                   1256:                        if (ip->emul_level == EMUL_VT100)
                   1257:                          ite_sendstr (ip, "\033[61;0c");
                   1258:                        else
                   1259:                          ite_sendstr (ip, "\033[63;0c");
                   1260:                      }
                   1261: 
                   1262:                    else if ((ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '>')
                   1263:                        || (ip->ap == &ip->argbuf[2] 
                   1264:                            && !strncmp (ip->argbuf, ">0", 2)))
                   1265:                      {
                   1266:                        ite_sendstr (ip, "\033[>24;0;0;0c");
                   1267:                      }
                   1268: 
                   1269:                    ip->escape = 0;
                   1270:                    return -1;
                   1271: 
                   1272: 
                   1273:                  case 'n':
                   1274:                    *ip->ap = 0;
                   1275:                    if (ip->ap == &ip->argbuf[1])
                   1276:                      {
                   1277:                        if (ip->argbuf[0] == '5')
                   1278:                          ite_sendstr (ip, "\033[0n");  /* no malfunction */
                   1279:                          
                   1280:                        else if (ip->argbuf[0] == '6')
                   1281:                          {
                   1282:                            sprintf (ip->argbuf, "\033[%d;%dR", 
                   1283:                                     ip->cury + 1, ip->curx + 1);
                   1284:                            /* cursor position report */
                   1285:                            ite_sendstr (ip, ip->argbuf);
                   1286:                          }
                   1287:                                
                   1288:                      }
                   1289:                    ip->escape = 0;
                   1290:                    return -1;
                   1291:                  
                   1292:                  
                   1293:                  case 'h': case 'l':
                   1294:                    *ip->ap = 0;
                   1295:                    if (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '4')
                   1296:                      ip->imode = (c == 'h');   /* insert/replace mode */
                   1297: 
                   1298:                    else if (ip->ap == &ip->argbuf[2] 
                   1299:                             && !strncmp (ip->argbuf, "20", 2))
                   1300:                      ip->linefeed_newline = (c == 'h');
                   1301: 
                   1302: 
                   1303:                    /* various not supported commands */
                   1304:                    ip->escape = 0;
                   1305:                    return -1;
                   1306: 
                   1307: 
                   1308:                  case 'M':
                   1309:                    *ip->ap = 0;
                   1310:                    ite_dnline (ip, sp, ite_argnum (ip));
                   1311:                    ip->escape = 0;
                   1312:                    return -1;
                   1313: 
                   1314:                  
                   1315:                  case 'L':
                   1316:                    *ip->ap = 0;
                   1317:                    ite_inline (ip, sp, ite_argnum (ip));
                   1318:                    ip->escape = 0;
                   1319:                    return -1;
                   1320: 
                   1321: 
                   1322:                  case 'P':
                   1323:                    *ip->ap = 0;
                   1324:                    ite_dnchar (ip, sp, ite_argnum (ip));
                   1325:                    ip->escape = 0;
                   1326:                    return -1;
                   1327:                    
                   1328: 
                   1329:                  case '@':
                   1330:                    *ip->ap = 0;
                   1331:                    ite_inchar (ip, sp, ite_argnum (ip));
                   1332:                    ip->escape = 0;
                   1333:                    return -1;
                   1334: 
                   1335: 
                   1336:                  case 'H':
                   1337:                  case 'f':
                   1338:                    *ip->ap = 0;
                   1339:                    y = atoi (ip->argbuf);
                   1340:                    x = 0;
                   1341:                    cp = index (ip->argbuf, ';');
                   1342:                    if (cp)
                   1343:                      x = atoi (cp + 1);
                   1344:                    if (x) x--;
                   1345:                    if (y) y--;
                   1346:                    if (ip->inside_margins)
                   1347:                      {
                   1348:                        y += ip->top_margin;
                   1349:                        ip->cury = MIN(y, ip->bottom_margin);
                   1350:                      }
                   1351:                    else
                   1352:                      {
                   1353:                        ip->cury = MIN(y, ip->rows - 1);
                   1354:                      }
                   1355:                    ip->curx = MIN(x, ip->cols - 1);
                   1356:                    ip->escape = 0;
                   1357:                    (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1358:                    clr_attr (ip, ATTR_INV);
                   1359:                    return -1;
                   1360:                    
                   1361:                  case 'A':                 
                   1362:                    *ip->ap = 0;
                   1363:                    n = ip->cury - ite_argnum (ip);
                   1364:                    ip->cury = n >= 0 ? n : 0;
                   1365:                    ip->escape = 0;
                   1366:                    (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1367:                    clr_attr (ip, ATTR_INV);
                   1368:                    return -1;
                   1369:                  
                   1370:                  case 'B':
                   1371:                    *ip->ap = 0;
                   1372:                    n = ite_argnum (ip) + ip->cury;
                   1373:                    ip->cury = MIN(n, ip->rows - 1);
                   1374:                    ip->escape = 0;
                   1375:                    (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1376:                    clr_attr (ip, ATTR_INV);
                   1377:                    return -1;
                   1378:                  
                   1379:                  case 'C':
                   1380:                    *ip->ap = 0;
                   1381:                    n = ite_argnum (ip) + ip->curx;
                   1382:                    ip->curx = MIN(n, ip->cols - 1);
                   1383:                    ip->escape = 0;
                   1384:                    (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1385:                    clr_attr (ip, ATTR_INV);
                   1386:                    return -1;
                   1387:                  
                   1388:                  case 'D':
                   1389:                    *ip->ap = 0;
                   1390:                    n = ip->curx - ite_argnum (ip);
                   1391:                    ip->curx = n >= 0 ? n : 0;
                   1392:                    ip->escape = 0;
                   1393:                    (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1394:                    clr_attr (ip, ATTR_INV);
                   1395:                    return -1;
                   1396:                  
                   1397:                    
                   1398: 
                   1399: 
                   1400:                  case 'J':
                   1401:                    *ip->ap = 0;
                   1402:                    n = ite_zargnum (ip);
                   1403:                    if (n == 0)
                   1404:                      ite_clrtoeos(ip, sp);
                   1405:                    else if (n == 1)
                   1406:                      ite_clrtobos(ip, sp);
                   1407:                    else if (n == 2)
                   1408:                      ite_clrscreen(ip, sp);
                   1409:                    ip->escape = 0;
                   1410:                    return -1;
                   1411: 
                   1412: 
                   1413:                  case 'K':
                   1414:                    *ip->ap = 0;
                   1415:                    n = ite_zargnum (ip);
                   1416:                    if (n == 0)
                   1417:                      ite_clrtoeol(ip, sp, ip->cury, ip->curx);
                   1418:                    else if (n == 1)
                   1419:                      ite_clrtobol(ip, sp, ip->cury, ip->curx);
                   1420:                    else if (n == 2)
                   1421:                      ite_clrline(ip, sp, ip->cury, ip->curx);
                   1422:                    ip->escape = 0;
                   1423:                    return -1;
                   1424: 
                   1425: 
                   1426:                  case 'X':
                   1427:                    *ip->ap = 0;
                   1428:                    for (n = ite_argnum (ip); n > 0; n--)
                   1429:                      {
                   1430:                        attrclr(ip, ip->cury, ip->curx + n - 1, 1, 1);
                   1431:                        (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n - 1, ATTR_NOR);
                   1432:                      }
                   1433:                    ip->escape = 0;
                   1434:                    return -1;
                   1435: 
                   1436:                  
                   1437:                  case '}': case '`':
                   1438:                    /* status line control */
                   1439:                    ip->escape = 0;
                   1440:                    return -1;
                   1441: 
                   1442: 
                   1443:                  case 'r':
                   1444:                    *ip->ap = 0;
                   1445:                    x = atoi (ip->argbuf);
                   1446:                    y = 0;
                   1447:                    cp = index (ip->argbuf, ';');
                   1448:                    if (cp)
                   1449:                      y = atoi (cp + 1);
                   1450:                    if (x) x--;
                   1451:                    if (y) y--;
                   1452:                    ip->top_margin = MIN(x, ip->rows - 1);
                   1453:                    ip->bottom_margin = MIN(y, ip->rows - 1);
                   1454:                    ip->escape = 0;
                   1455:                    return -1;
                   1456:                    
                   1457:                  
                   1458:                  case 'm':
                   1459:                    /* big attribute setter/resetter */
                   1460:                    {
                   1461:                      char *cp;
                   1462:                      *ip->ap = 0;
                   1463:                      for (cp = ip->argbuf; cp < ip->ap; )
                   1464:                        {
                   1465:                          switch (*cp)
                   1466:                            {
                   1467:                            case '0':
                   1468:                              clr_attr (ip, ATTR_ALL);
                   1469:                              cp++;
                   1470:                              break;
                   1471:                              
                   1472:                            case '1':
                   1473:                              set_attr (ip, ATTR_BOLD);
                   1474:                              cp++;
                   1475:                              break;
                   1476:                              
                   1477:                            case '2':
                   1478:                              switch (cp[1])
                   1479:                                {
                   1480:                                case '2':
                   1481:                                  clr_attr (ip, ATTR_BOLD);
                   1482:                                  cp += 2;
                   1483:                                  break;
                   1484:                                
                   1485:                                case '4':
                   1486:                                  clr_attr (ip, ATTR_UL);
                   1487:                                  cp += 2;
                   1488:                                  break;
                   1489:                                  
                   1490:                                case '5':
                   1491:                                  clr_attr (ip, ATTR_BLINK);
                   1492:                                  cp += 2;
                   1493:                                  break;
                   1494:                                  
                   1495:                                case '7':
                   1496:                                  clr_attr (ip, ATTR_INV);
                   1497:                                  cp += 2;
                   1498:                                  break;
                   1499:                                
                   1500:                                default:
                   1501:                                  cp++;
                   1502:                                  break;
                   1503:                                }
                   1504:                              break;
                   1505:                              
                   1506:                            case '4':
                   1507:                              set_attr (ip, ATTR_UL);
                   1508:                              cp++;
                   1509:                              break;
                   1510:                              
                   1511:                            case '5':
                   1512:                              set_attr (ip, ATTR_BLINK);
                   1513:                              cp++;
                   1514:                              break;
                   1515:                              
                   1516:                            case '7':
                   1517:                              set_attr (ip, ATTR_INV);
                   1518:                              cp++;
                   1519:                              break;
                   1520:                            
                   1521:                            default:
                   1522:                              cp++;
                   1523:                              break;
                   1524:                            }
                   1525:                        }
                   1526:                    
                   1527:                    }
                   1528:                    ip->escape = 0;
                   1529:                    return -1;
                   1530: 
                   1531: 
                   1532:                  case 'u':
                   1533:                    /* DECRQTSR */
                   1534:                    ite_sendstr (ip, "\033P\033\\");
                   1535:                    ip->escape = 0;
                   1536:                    return -1;
                   1537: 
                   1538:                  
                   1539:                  
                   1540:                  default:
                   1541:                    ip->escape = 0;
                   1542:                    return -1;
                   1543:                  }
                   1544:                break;
                   1545: 
                   1546: 
                   1547: 
                   1548:              case '?': /* CSI ? */
                   1549:                switch (c)
                   1550:                  {
                   1551:                  case '0': case '1': case '2': case '3': case '4':
                   1552:                  case '5': case '6': case '7': case '8': case '9':
                   1553:                  case ';': case '\"': case '$':
                   1554:                    if (ip->ap < ip->argbuf + ARGBUF_SIZE)
                   1555:                      *ip->ap++ = c;
                   1556:                    return -1;
                   1557: 
                   1558: 
                   1559:                  case CAN:
                   1560:                    ip->escape = 0;
                   1561:                    return -1;
                   1562: 
                   1563:                    
                   1564:                  case 'n':
                   1565:                    *ip->ap = 0;
                   1566:                    if (ip->ap == &ip->argbuf[2])
                   1567:                      {
                   1568:                        if (! strncmp (ip->argbuf, "15", 2))
                   1569:                          /* printer status: no printer */
                   1570:                          ite_sendstr (ip, "\033[13n");
                   1571:                          
                   1572:                        else if (! strncmp (ip->argbuf, "25", 2))
                   1573:                          /* udk status */
                   1574:                          ite_sendstr (ip, "\033[20n");
                   1575:                          
                   1576:                        else if (! strncmp (ip->argbuf, "26", 2))
                   1577:                          /* keyboard dialect: US */
                   1578:                          ite_sendstr (ip, "\033[27;1n");
                   1579:                      }
                   1580:                    ip->escape = 0;
                   1581:                    return -1;
                   1582: 
                   1583: 
                   1584:                  case 'h': case 'l':
                   1585:                    *ip->ap = 0;
                   1586:                    if (ip->ap[0] == '6')
                   1587:                      ip->inside_margins = (c == 'h');
                   1588: 
                   1589:                    else if (! strncmp (ip->ap, "25", 2))
                   1590:                      (*itesw[ip->type].ite_cursor)(ip, 
                   1591:                                                    (c == 'h') ? DRAW_CURSOR : ERASE_CURSOR);
                   1592: 
                   1593:                    /* others.. */
                   1594:                    
                   1595:                  default:
                   1596:                    ip->escape = 0;
                   1597:                    return -1;
                   1598:                  }
                   1599:                break;
                   1600: 
                   1601:              
                   1602:              default:
                   1603:                ip->escape = 0;
                   1604:                return -1;
                   1605:              }
                   1606:           }
                   1607: 
                   1608: 
                   1609:        switch (c) {
                   1610: 
                   1611:        case VT:        /* VT is treated like LF */
                   1612:        case FF:        /* so is FF */
                   1613:        case LF:
                   1614:                if (ip->linefeed_newline)
                   1615:                  ite_crlf (ip, sp);
                   1616:                else
                   1617:                  ite_lf (ip, sp);
                   1618:                break;
                   1619: 
                   1620:        case CR:
                   1621:                ite_cr (ip, sp);
                   1622:                break;
                   1623:        
                   1624:        case BS:
                   1625:                if (--ip->curx < 0)
                   1626:                        ip->curx = 0;
                   1627:                else
                   1628:                        (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1629:                break;
                   1630: 
                   1631:        case HT:
                   1632:                if (ip->curx < TABEND(unit)) {
                   1633:                        n = TABSIZE - (ip->curx & (TABSIZE - 1));
                   1634:                        ip->curx += n;
                   1635:                        (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1636:                } else
                   1637:                        itecheckwrap(ip, sp);
                   1638:                break;
                   1639: 
                   1640:        case BEL:
                   1641:                if (ite_tty[unit] == kbd_tty)
                   1642:                        kbdbell();
                   1643:                break;
                   1644: 
                   1645:        case SO:
                   1646:                ip->GL = ip->G1;
                   1647:                break;
                   1648:                
                   1649:        case SI:
                   1650:                ip->GL = ip->G0;
                   1651:                break;
                   1652: 
                   1653:        case ENQ:
                   1654:                /* send answer-back message !! */
                   1655:                break;
                   1656: 
                   1657:        case CAN:
                   1658:                ip->escape = 0; /* cancel any escape sequence in progress */
                   1659:                break;
                   1660:                
                   1661:        case SUB:
                   1662:                ip->escape = 0; /* dito, but see below */
                   1663:                /* should also display a reverse question mark!! */
                   1664:                break;
                   1665: 
                   1666:        case ESC:
                   1667:                ip->escape = ESC;
                   1668:                break;
                   1669: 
                   1670: 
                   1671:        /* now it gets weird.. 8bit control sequences.. */
                   1672:        case IND:       /* index: move cursor down, scroll */
                   1673:                ite_lf (ip, sp);
                   1674:                break;
                   1675:                
                   1676:        case NEL:       /* next line. next line, first pos. */
                   1677:                ite_crlf (ip, sp);
                   1678:                break;
                   1679: 
                   1680:        case HTS:       /* set horizontal tab */
                   1681:                /* not yet supported */
                   1682:                break;
                   1683:                
                   1684:        case RI:        /* reverse index */
                   1685:                ite_rlf (ip, sp);
                   1686:                break;
                   1687: 
                   1688:        case SS2:       /* go into G2 for one character */
                   1689:                /* not yet supported */
                   1690:                break;
                   1691:                
                   1692:        case SS3:       /* go into G3 for one character */
                   1693:                break;
                   1694:                
                   1695:        case DCS:       /* device control string introducer */
                   1696:                ip->escape = DCS;
                   1697:                ip->ap = ip->argbuf;
                   1698:                break;
                   1699:                
                   1700:        case CSI:       /* control sequence introducer */
                   1701:                ip->escape = CSI;
                   1702:                ip->ap = ip->argbuf;
                   1703:                break;
                   1704:                
                   1705:        case ST:        /* string terminator */
                   1706:                /* ignore, if not used as terminator */
                   1707:                break;
                   1708:                
                   1709:        case OSC:       /* introduces OS command. Ignore everything upto ST */
                   1710:                ip->escape = OSC;
                   1711:                break;
                   1712: 
                   1713:        case PM:        /* privacy message, ignore everything upto ST */
                   1714:                ip->escape = PM;
                   1715:                break;
                   1716:                
                   1717:        case APC:       /* application program command, ignore everything upto ST */
                   1718:                ip->escape = APC;
                   1719:                break;
                   1720: 
                   1721:        default:
                   1722:                if (c < ' ' || c == DEL)
                   1723:                        break;
                   1724:                if (ip->imode)
                   1725:                        ite_inchar(ip, sp, 1);
                   1726:                if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
                   1727:                        attrset(ip, ATTR_INV);
                   1728:                        (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
                   1729:                }                       
                   1730:                else
                   1731:                        (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
                   1732:                (*sp->ite_cursor)(ip, DRAW_CURSOR);
                   1733:                itecheckwrap(ip, sp);
                   1734:                break;
                   1735:        }
                   1736: }
                   1737: 
                   1738: itecheckwrap(ip, sp)
                   1739:      register struct ite_softc *ip;
                   1740:      register struct itesw *sp;
                   1741: {
                   1742:        if (++ip->curx == ip->cols) {
                   1743:                ip->curx = 0;
                   1744:                clr_attr(ip, ATTR_INV);
                   1745:                if (++ip->cury >= ip->bottom_margin + 1) {
                   1746:                        ip->cury = ip->bottom_margin;
                   1747:                        (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
                   1748:                        ite_clrtoeol(ip, sp, ip->cury, 0);
                   1749:                        return;
                   1750:                }
                   1751:        }
                   1752:        (*sp->ite_cursor)(ip, MOVE_CURSOR);
                   1753: }
                   1754: 
                   1755: /*
                   1756:  * Console functions
                   1757:  */
                   1758: #include "../amiga/cons.h"
                   1759: #include "grfioctl.h"
                   1760: #include "grfvar.h"
                   1761: 
                   1762: #ifdef DEBUG
                   1763: /*
                   1764:  * Minimum ITE number at which to start looking for a console.
                   1765:  * Setting to 0 will do normal search, 1 will skip first ITE device,
                   1766:  * NITE will skip ITEs and use serial port.
                   1767:  */
                   1768: int    whichconsole = 0;
                   1769: #endif
                   1770: 
                   1771: itecnprobe(cp)
                   1772:        struct consdev *cp;
                   1773: {
                   1774:        register struct ite_softc *ip;
                   1775:        int i, maj, unit, pri;
                   1776: 
                   1777:        /* locate the major number */
                   1778:        for (maj = 0; maj < nchrdev; maj++)
                   1779:                if (cdevsw[maj].d_open == iteopen)
                   1780:                        break;
                   1781: 
                   1782:        /* urk! */
                   1783:        grfconfig();
                   1784: 
                   1785:        /* check all the individual displays and find the best */
                   1786:        unit = -1;
                   1787:        pri = CN_DEAD;
                   1788:        for (i = 0; i < NITE; i++) {
                   1789:                struct grf_softc *gp = &grf_softc[i];
                   1790: 
                   1791:                ip = &ite_softc[i];
                   1792:                if ((gp->g_flags & GF_ALIVE) == 0)
                   1793:                        continue;
                   1794:                ip->flags = (ITE_ALIVE|ITE_CONSOLE);
                   1795: 
                   1796:                /* XXX - we need to do something about mapping these */
                   1797:                switch (gp->g_type) {
                   1798:                case GT_CUSTOMCHIPS:
                   1799:                        ip->type = ITE_CUSTOMCHIPS;
                   1800:                        break;
                   1801:                        
                   1802:                case GT_TIGA_A2410:
                   1803:                        ip->type = ITE_TIGA_A2410;
                   1804:                        break;
                   1805:                }
                   1806: #ifdef DEBUG
                   1807:                if (i < whichconsole)
                   1808:                        continue;
                   1809: #endif
                   1810:                if ((int)gp->g_type == GT_CUSTOMCHIPS) {
                   1811:                        pri = CN_INTERNAL;
                   1812:                        unit = i;
                   1813:                } else if (unit < 0) {
                   1814:                        pri = CN_NORMAL;
                   1815:                        unit = i;
                   1816:                }
                   1817:        }
                   1818: 
                   1819:        /* initialize required fields */
                   1820:        cp->cn_dev = makedev(maj, unit);
                   1821:        cp->cn_tp = ite_tty[unit];
                   1822:        cp->cn_pri = pri;
                   1823: }
                   1824: 
                   1825: itecninit(cp)
                   1826:        struct consdev *cp;
                   1827: {
                   1828:        int unit = UNIT(cp->cn_dev);
                   1829:        struct ite_softc *ip = &ite_softc[unit];
                   1830:        ip->attrbuf = console_attributes;
                   1831:        iteinit(cp->cn_dev);
                   1832:        ip->flags |= (ITE_ACTIVE|ITE_ISCONS);
                   1833:        kbd_tty = ite_tty[unit];
                   1834:        kbdenable();
                   1835: }
                   1836: 
                   1837: /*ARGSUSED*/
                   1838: itecngetc(dev)
                   1839:        dev_t dev;
                   1840: {
                   1841:        register int c;
                   1842: 
                   1843:         do
                   1844:           {
                   1845:             c = kbdgetcn ();
                   1846:             c = itefilter (c, ITEFILT_CONSOLE);
                   1847:           }
                   1848:         while (c == -1);
                   1849: 
                   1850:        return(c);
                   1851: }
                   1852: 
                   1853: itecnputc(dev, c)
                   1854:        dev_t dev;
                   1855:        int c;
                   1856: {
                   1857:        static int paniced = 0;
                   1858:        struct ite_softc *ip = &ite_softc[UNIT(dev)];
                   1859:        extern char *panicstr;
                   1860: 
                   1861:        if (panicstr && !paniced &&
                   1862:            (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
                   1863:                (void) iteon(dev, 3);
                   1864:                paniced = 1;
                   1865:        }
                   1866:        iteputchar(c, dev);
                   1867: }
                   1868: #endif

unix.superglobalmegacorp.com

This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.