|
|
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
This archive runs on limited infrastructure. Preserving old code on modern bandwidth. Automated agents are requested to crawl responsibly.