No empty .Rs/.Re
[netbsd-mini2440.git] / sys / arch / hp300 / dev / ite.c
blob511b194977c61e66d6a26e713936ebd348f92d0d
1 /* $NetBSD: ite.c,v 1.82 2008/06/13 09:41:15 cegger Exp $ */
3 /*-
4 * Copyright (c) 1996, 1997 The NetBSD Foundation, Inc.
5 * All rights reserved.
7 * This code is derived from software contributed to The NetBSD Foundation
8 * by Jason R. Thorpe.
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.
19 * THIS SOFTWARE IS PROVIDED BY THE NETBSD FOUNDATION, INC. AND CONTRIBUTORS
20 * ``AS IS'' AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED
21 * TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR
22 * PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE FOUNDATION OR CONTRIBUTORS
23 * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
24 * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
25 * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
26 * INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
27 * CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
28 * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
29 * POSSIBILITY OF SUCH DAMAGE.
33 * Copyright (c) 1990, 1993
34 * The Regents of the University of California. All rights reserved.
36 * This code is derived from software contributed to Berkeley by
37 * the Systems Programming Group of the University of Utah Computer
38 * Science Department.
40 * Redistribution and use in source and binary forms, with or without
41 * modification, are permitted provided that the following conditions
42 * are met:
43 * 1. Redistributions of source code must retain the above copyright
44 * notice, this list of conditions and the following disclaimer.
45 * 2. Redistributions in binary form must reproduce the above copyright
46 * notice, this list of conditions and the following disclaimer in the
47 * documentation and/or other materials provided with the distribution.
48 * 3. Neither the name of the University nor the names of its contributors
49 * may be used to endorse or promote products derived from this software
50 * without specific prior written permission.
52 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
53 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
54 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
55 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
56 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
57 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
58 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
59 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
60 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
61 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
62 * SUCH DAMAGE.
64 * from: Utah $Hdr: ite.c 1.28 92/12/20$
66 * @(#)ite.c 8.2 (Berkeley) 1/12/94
69 * Copyright (c) 1988 University of Utah.
71 * This code is derived from software contributed to Berkeley by
72 * the Systems Programming Group of the University of Utah Computer
73 * Science Department.
75 * Redistribution and use in source and binary forms, with or without
76 * modification, are permitted provided that the following conditions
77 * are met:
78 * 1. Redistributions of source code must retain the above copyright
79 * notice, this list of conditions and the following disclaimer.
80 * 2. Redistributions in binary form must reproduce the above copyright
81 * notice, this list of conditions and the following disclaimer in the
82 * documentation and/or other materials provided with the distribution.
83 * 3. All advertising materials mentioning features or use of this software
84 * must display the following acknowledgement:
85 * This product includes software developed by the University of
86 * California, Berkeley and its contributors.
87 * 4. Neither the name of the University nor the names of its contributors
88 * may be used to endorse or promote products derived from this software
89 * without specific prior written permission.
91 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
92 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
93 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
94 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
95 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
96 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
97 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
98 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
99 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
100 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
101 * SUCH DAMAGE.
103 * from: Utah $Hdr: ite.c 1.28 92/12/20$
105 * @(#)ite.c 8.2 (Berkeley) 1/12/94
109 * Bit-mapped display terminal emulator machine independent code.
110 * This is a very rudimentary. Much more can be abstracted out of
111 * the hardware dependent routines.
114 #include <sys/cdefs.h>
115 __KERNEL_RCSID(0, "$NetBSD: ite.c,v 1.82 2008/06/13 09:41:15 cegger Exp $");
117 #include "hil.h"
119 #include <sys/param.h>
120 #include <sys/conf.h>
121 #include <sys/proc.h>
122 #include <sys/ioctl.h>
123 #include <sys/tty.h>
124 #include <sys/systm.h>
125 #include <sys/malloc.h>
126 #include <sys/device.h>
127 #include <sys/kauth.h>
129 #include <machine/autoconf.h>
130 #include <machine/bus.h>
132 #include <dev/cons.h>
134 #include <hp300/dev/grfioctl.h>
135 #include <hp300/dev/grfvar.h>
136 #include <hp300/dev/hilioctl.h>
137 #include <hp300/dev/hilvar.h>
138 #include <hp300/dev/itevar.h>
139 #include <hp300/dev/kbdmap.h>
141 #include "ioconf.h"
143 #define set_attr(ip, attr) ((ip)->attribute |= (attr))
144 #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr))
147 * # of chars are output in a single itestart() call.
148 * If this is too big, user processes will be blocked out for
149 * long periods of time while we are emptying the queue in itestart().
150 * If it is too small, console output will be very ragged.
152 int iteburst = 64;
154 static int itematch(device_t, cfdata_t, void *);
155 static void iteattach(device_t, device_t, void *);
157 CFATTACH_DECL_NEW(ite, sizeof(struct ite_softc),
158 itematch, iteattach, NULL, NULL);
160 /* XXX this has always been global, but shouldn't be */
161 static struct kbdmap *ite_km;
163 static dev_type_open(iteopen);
164 static dev_type_close(iteclose);
165 static dev_type_read(iteread);
166 static dev_type_write(itewrite);
167 static dev_type_ioctl(iteioctl);
168 static dev_type_tty(itetty);
169 static dev_type_poll(itepoll);
171 const struct cdevsw ite_cdevsw = {
172 iteopen, iteclose, iteread, itewrite, iteioctl,
173 nostop, itetty, itepoll, nommap, ttykqfilter, D_TTY
177 * Terminal emulator state information, statically allocated
178 * for the benefit of the console.
180 static struct ite_data ite_cn;
183 * console stuff
185 static struct consdev ite_cons = {
186 NULL,
187 NULL,
188 itecngetc,
189 itecnputc,
190 nullcnpollc,
191 NULL,
192 NULL,
193 NULL,
194 NODEV,
195 CN_NORMAL
197 static int console_kbd_attached;
198 static int console_display_attached;
199 static struct ite_kbdops *console_kbdops;
200 static struct ite_kbdmap *console_kbdmap;
202 static void iteinit(struct ite_data *);
203 static void iteputchar(int, struct ite_data *);
204 static void itecheckwrap(struct ite_data *, struct itesw *);
205 static void ite_dchar(struct ite_data *, struct itesw *);
206 static void ite_ichar(struct ite_data *, struct itesw *);
207 static void ite_dline(struct ite_data *, struct itesw *);
208 static void ite_iline(struct ite_data *, struct itesw *);
209 static void ite_clrtoeol(struct ite_data *, struct itesw *, int, int);
210 static void ite_clrtoeos(struct ite_data *, struct itesw *);
211 static void itestart(struct tty *);
214 * Primary attribute buffer to be used by the first bitmapped console
215 * found. Secondary displays alloc the attribute buffer as needed.
216 * Size is based on a 68x128 display, which is currently our largest.
218 static u_char ite_console_attributes[0x2200];
220 #define ite_erasecursor(ip, sp) { \
221 if ((ip)->flags & ITE_CURSORON) \
222 (*(sp)->ite_cursor)((ip), ERASE_CURSOR); \
224 #define ite_drawcursor(ip, sp) { \
225 if ((ip)->flags & ITE_CURSORON) \
226 (*(sp)->ite_cursor)((ip), DRAW_CURSOR); \
228 #define ite_movecursor(ip, sp) { \
229 if ((ip)->flags & ITE_CURSORON) \
230 (*(sp)->ite_cursor)((ip), MOVE_CURSOR); \
233 static int
234 itematch(device_t parent, cfdata_t cf, void *aux)
237 return 1;
240 static void
241 iteattach(device_t parent, device_t self, void *aux)
243 struct ite_softc *ite = device_private(self);
244 struct grf_softc *grf = device_private(parent);
245 struct grfdev_attach_args *ga = aux;
247 ite->sc_dev = self;
249 /* Allocate the ite_data. */
250 if (ga->ga_isconsole) {
251 ite->sc_data = &ite_cn;
252 aprint_normal(": console");
255 * We didn't know which unit this would be during
256 * the console probe, so we have to fixup cn_dev here.
258 cn_tab->cn_dev = makedev(cdevsw_lookup_major(&ite_cdevsw),
259 device_unit(self));
260 } else {
261 ite->sc_data = malloc(sizeof(struct ite_data), M_DEVBUF,
262 M_NOWAIT | M_ZERO);
263 if (ite->sc_data == NULL) {
264 aprint_normal("\n");
265 aprint_error_dev(self, "malloc for ite_data failed\n");
266 return;
268 ite->sc_data->flags = ITE_ALIVE;
272 * Cross-reference the ite and the grf.
274 ite->sc_grf = grf;
275 grf->sc_ite = ite;
277 aprint_normal("\n");
280 void
281 iteinstallkeymap(void *v)
284 ite_km = (struct kbdmap *)v;
288 * Perform functions necessary to setup device as a terminal emulator.
291 iteon(struct ite_data *ip, int flag)
294 if ((ip->flags & ITE_ALIVE) == 0)
295 return ENXIO;
297 /* force ite active, overriding graphics mode */
298 if (flag & 1) {
299 ip->flags |= ITE_ACTIVE;
300 ip->flags &= ~(ITE_INGRF|ITE_INITED);
303 /* leave graphics mode */
304 if (flag & 2) {
305 ip->flags &= ~ITE_INGRF;
306 if ((ip->flags & ITE_ACTIVE) == 0)
307 return 0;
310 ip->flags |= ITE_ACTIVE;
311 if (ip->flags & ITE_INGRF)
312 return 0;
314 if (console_kbdops != NULL)
315 (*console_kbdops->enable)(console_kbdops->arg);
317 iteinit(ip);
318 return 0;
321 static void
322 iteinit(struct ite_data *ip)
325 if (ip->flags & ITE_INITED)
326 return;
328 ip->curx = 0;
329 ip->cury = 0;
330 ip->cursorx = 0;
331 ip->cursory = 0;
333 (*ip->isw->ite_init)(ip);
334 ip->flags |= ITE_CURSORON;
335 ite_drawcursor(ip, ip->isw);
337 ip->attribute = 0;
338 if (ip->attrbuf == NULL)
339 ip->attrbuf = malloc(ip->rows * ip->cols,
340 M_DEVBUF, M_WAITOK | M_ZERO);
342 ip->imode = 0;
343 ip->flags |= ITE_INITED;
347 * "Shut down" device as terminal emulator.
348 * Note that we do not deinit the console device unless forced.
349 * Deinit'ing the console every time leads to a very active
350 * screen when processing /etc/rc.
352 void
353 iteoff(struct ite_data *ip, int flag)
356 if (flag & 2) {
357 ip->flags |= ITE_INGRF;
358 ip->flags &= ~ITE_CURSORON;
360 if ((ip->flags & ITE_ACTIVE) == 0)
361 return;
362 if ((flag & 1) ||
363 (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
364 (*ip->isw->ite_deinit)(ip);
367 * XXX When the system is rebooted with "reboot", init(8)
368 * kills the last process to have the console open.
369 * If we don't prevent the ITE_ACTIVE bit from being
370 * cleared, we will never see messages printed during
371 * the process of rebooting.
373 if ((flag & 2) == 0 && (ip->flags & ITE_ISCONS) == 0)
374 ip->flags &= ~ITE_ACTIVE;
377 /* ARGSUSED */
378 static int
379 iteopen(dev_t dev, int mode, int devtype, struct lwp *l)
381 int unit = ITEUNIT(dev);
382 struct tty *tp;
383 struct ite_softc *sc;
384 struct ite_data *ip;
385 int error;
386 int first = 0;
388 sc = device_lookup_private(&ite_cd, unit);
389 if (sc == NULL)
390 return ENXIO;
391 ip = sc->sc_data;
393 if (ip->tty == NULL) {
394 tp = ip->tty = ttymalloc();
395 tty_attach(tp);
396 } else
397 tp = ip->tty;
398 if (kauth_authorize_device_tty(l->l_cred, KAUTH_DEVICE_TTY_OPEN, tp))
399 return (EBUSY);
400 if ((ip->flags & ITE_ACTIVE) == 0) {
401 error = iteon(ip, 0);
402 if (error)
403 return error;
404 first = 1;
406 tp->t_oproc = itestart;
407 tp->t_param = NULL;
408 tp->t_dev = dev;
409 if ((tp->t_state&TS_ISOPEN) == 0) {
410 ttychars(tp);
411 tp->t_iflag = TTYDEF_IFLAG;
412 tp->t_oflag = TTYDEF_OFLAG;
413 tp->t_cflag = CS8|CREAD;
414 tp->t_lflag = TTYDEF_LFLAG;
415 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
416 tp->t_state = TS_ISOPEN|TS_CARR_ON;
417 ttsetwater(tp);
419 error = (*tp->t_linesw->l_open)(dev, tp);
420 if (error == 0) {
421 tp->t_winsize.ws_row = ip->rows;
422 tp->t_winsize.ws_col = ip->cols;
423 } else if (first)
424 iteoff(ip, 0);
425 return error;
428 /*ARGSUSED*/
429 static int
430 iteclose(dev_t dev, int flag, int mode, struct lwp *l)
432 struct ite_softc *sc = device_lookup_private(&ite_cd, ITEUNIT(dev));
433 struct ite_data *ip = sc->sc_data;
434 struct tty *tp = ip->tty;
436 (*tp->t_linesw->l_close)(tp, flag);
437 ttyclose(tp);
438 iteoff(ip, 0);
439 #if 0
440 tty_detach(tp);
441 ttyfree(tp);
442 ip->tty = NULL;
443 #endif
444 return 0;
447 static int
448 iteread(dev_t dev, struct uio *uio, int flag)
450 struct ite_softc *sc = device_lookup_private(&ite_cd, ITEUNIT(dev));
451 struct tty *tp = sc->sc_data->tty;
453 return (*tp->t_linesw->l_read)(tp, uio, flag);
457 itewrite(dev_t dev, struct uio *uio, int flag)
459 struct ite_softc *sc = device_lookup_private(&ite_cd, ITEUNIT(dev));
460 struct tty *tp = sc->sc_data->tty;
462 return (*tp->t_linesw->l_write)(tp, uio, flag);
466 itepoll(dev_t dev, int events, struct lwp *l)
468 struct ite_softc *sc = device_lookup_private(&ite_cd, ITEUNIT(dev));
469 struct tty *tp = sc->sc_data->tty;
471 return (*tp->t_linesw->l_poll)(tp, events, l);
474 struct tty *
475 itetty(dev_t dev)
477 struct ite_softc *sc = device_lookup_private(&ite_cd, ITEUNIT(dev));
479 return sc->sc_data->tty;
483 iteioctl(dev_t dev, u_long cmd, void *addr, int flag, struct lwp *l)
485 struct ite_softc *sc = device_lookup_private(&ite_cd, ITEUNIT(dev));
486 struct ite_data *ip = sc->sc_data;
487 struct tty *tp = ip->tty;
488 int error;
490 error = (*tp->t_linesw->l_ioctl)(tp, cmd, addr, flag, l);
491 if (error != EPASSTHROUGH)
492 return error;
493 return ttioctl(tp, cmd, addr, flag, l);
496 static void
497 itestart(struct tty *tp)
499 int cc, s;
500 int hiwat = 0, hadcursor = 0;
501 struct ite_softc *sc;
502 struct ite_data *ip;
504 sc = device_lookup_private(&ite_cd, ITEUNIT(tp->t_dev));
505 ip = sc->sc_data;
507 s = splkbd();
508 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
509 splx(s);
510 return;
512 tp->t_state |= TS_BUSY;
513 cc = tp->t_outq.c_cc;
514 ttypull(tp);
516 * Handle common (?) case
518 if (cc == 1) {
519 iteputchar(getc(&tp->t_outq), ip);
520 } else if (cc) {
522 * Limit the amount of output we do in one burst
523 * to prevent hogging the CPU.
525 if (cc > iteburst) {
526 hiwat++;
527 cc = iteburst;
530 * Turn off cursor while we output multiple characters.
531 * Saves a lot of expensive window move operations.
533 if (ip->flags & ITE_CURSORON) {
534 ite_erasecursor(ip, ip->isw);
535 ip->flags &= ~ITE_CURSORON;
536 hadcursor = 1;
538 while (--cc >= 0)
539 iteputchar(getc(&tp->t_outq), ip);
540 if (hadcursor) {
541 ip->flags |= ITE_CURSORON;
542 ite_drawcursor(ip, ip->isw);
544 if (hiwat) {
545 tp->t_state |= TS_TIMEOUT;
546 callout_schedule(&tp->t_rstrt_ch, 1);
549 tp->t_state &= ~TS_BUSY;
550 splx(s);
553 void
554 itefilter(char stat, char c)
556 static int capsmode = 0;
557 static int metamode = 0;
558 char code;
559 const char *str;
560 struct tty *kbd_tty;
562 if (ite_cn.tty == NULL)
563 return;
565 kbd_tty = ite_cn.tty;
567 switch (c & 0xFF) {
568 case KBD_CAPSLOCK:
569 capsmode = !capsmode;
570 return;
572 case KBD_EXT_LEFT_DOWN:
573 case KBD_EXT_RIGHT_DOWN:
574 metamode = 1;
575 return;
577 case KBD_EXT_LEFT_UP:
578 case KBD_EXT_RIGHT_UP:
579 metamode = 0;
580 return;
583 c &= KBD_CHARMASK;
584 switch ((stat>>KBD_SSHIFT) & KBD_SMASK) {
585 default:
586 case KBD_KEY:
587 code = ite_km->kbd_keymap[(int)c];
588 if (capsmode)
589 code = toupper(code);
590 break;
592 case KBD_SHIFT:
593 code = ite_km->kbd_shiftmap[(int)c];
594 if (capsmode)
595 code = tolower(code);
596 break;
598 case KBD_CTRL:
599 code = ite_km->kbd_ctrlmap[(int)c];
600 break;
602 case KBD_CTRLSHIFT:
603 code = ite_km->kbd_ctrlshiftmap[(int)c];
604 break;
607 if (code == '\0' && (str = ite_km->kbd_stringmap[(int)c]) != NULL) {
608 while (*str)
609 (*kbd_tty->t_linesw->l_rint)(*str++, kbd_tty);
610 } else {
611 if (metamode)
612 code |= 0x80;
613 (*kbd_tty->t_linesw->l_rint)(code, kbd_tty);
617 static void
618 iteputchar(int c, struct ite_data *ip)
620 struct itesw *sp = ip->isw;
621 int n;
623 if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
624 return;
626 if (ip->escape) {
627 doesc:
628 switch (ip->escape) {
630 case '&': /* Next can be a,d, or s */
631 if (ip->fpd++) {
632 ip->escape = c;
633 ip->fpd = 0;
635 return;
637 case 'a': /* cursor change */
638 switch (c) {
640 case 'Y': /* Only y coord. */
641 ip->cury = min(ip->pos, ip->rows-1);
642 ip->pos = 0;
643 ip->escape = 0;
644 ite_movecursor(ip, sp);
645 clr_attr(ip, ATTR_INV);
646 break;
648 case 'y': /* y coord first */
649 ip->cury = min(ip->pos, ip->rows-1);
650 ip->pos = 0;
651 ip->fpd = 0;
652 break;
654 case 'C': /* x coord */
655 ip->curx = min(ip->pos, ip->cols-1);
656 ip->pos = 0;
657 ip->escape = 0;
658 ite_movecursor(ip, sp);
659 clr_attr(ip, ATTR_INV);
660 break;
662 default: /* Possibly a 3 digit number. */
663 if (c >= '0' && c <= '9' && ip->fpd < 3) {
664 ip->pos = ip->pos * 10 + (c - '0');
665 ip->fpd++;
666 } else {
667 ip->pos = 0;
668 ip->escape = 0;
670 break;
672 return;
674 case 'd': /* attribute change */
675 switch (c) {
677 case 'B':
678 set_attr(ip, ATTR_INV);
679 break;
680 case 'D':
681 /* XXX: we don't do anything for underline */
682 set_attr(ip, ATTR_UL);
683 break;
684 case '@':
685 clr_attr(ip, ATTR_ALL);
686 break;
688 ip->escape = 0;
689 return;
691 case 's': /* keypad control */
692 switch (ip->fpd) {
694 case 0:
695 ip->hold = c;
696 ip->fpd++;
697 return;
699 case 1:
700 if (c == 'A') {
701 switch (ip->hold) {
703 case '0':
704 clr_attr(ip, ATTR_KPAD);
705 break;
706 case '1':
707 set_attr(ip, ATTR_KPAD);
708 break;
711 ip->hold = 0;
713 ip->escape = 0;
714 return;
716 case 'i': /* back tab */
717 if (ip->curx > TABSIZE) {
718 n = ip->curx - (ip->curx & (TABSIZE - 1));
719 ip->curx -= n;
720 } else
721 ip->curx = 0;
722 ite_movecursor(ip, sp);
723 ip->escape = 0;
724 return;
726 case '3': /* clear all tabs */
727 goto ignore;
729 case 'K': /* clear_eol */
730 ite_clrtoeol(ip, sp, ip->cury, ip->curx);
731 ip->escape = 0;
732 return;
734 case 'J': /* clear_eos */
735 ite_clrtoeos(ip, sp);
736 ip->escape = 0;
737 return;
739 case 'B': /* cursor down 1 line */
740 if (++ip->cury == ip->rows) {
741 --ip->cury;
742 ite_erasecursor(ip, sp);
743 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
744 ite_clrtoeol(ip, sp, ip->cury, 0);
746 else
747 ite_movecursor(ip, sp);
748 clr_attr(ip, ATTR_INV);
749 ip->escape = 0;
750 return;
752 case 'C': /* cursor forward 1 char */
753 ip->escape = 0;
754 itecheckwrap(ip, sp);
755 return;
757 case 'A': /* cursor up 1 line */
758 if (ip->cury > 0) {
759 ip->cury--;
760 ite_movecursor(ip, sp);
762 ip->escape = 0;
763 clr_attr(ip, ATTR_INV);
764 return;
766 case 'P': /* delete character */
767 ite_dchar(ip, sp);
768 ip->escape = 0;
769 return;
771 case 'M': /* delete line */
772 ite_dline(ip, sp);
773 ip->escape = 0;
774 return;
776 case 'Q': /* enter insert mode */
777 ip->imode = 1;
778 ip->escape = 0;
779 return;
781 case 'R': /* exit insert mode */
782 ip->imode = 0;
783 ip->escape = 0;
784 return;
786 case 'L': /* insert blank line */
787 ite_iline(ip, sp);
788 ip->escape = 0;
789 return;
791 case 'h': /* home key */
792 ip->cury = ip->curx = 0;
793 ite_movecursor(ip, sp);
794 ip->escape = 0;
795 return;
797 case 'D': /* left arrow key */
798 if (ip->curx > 0) {
799 ip->curx--;
800 ite_movecursor(ip, sp);
802 ip->escape = 0;
803 return;
805 case '1': /* set tab in all rows */
806 goto ignore;
808 case ESC:
809 if ((ip->escape = c) == ESC)
810 break;
811 ip->fpd = 0;
812 goto doesc;
814 default:
815 ignore:
816 ip->escape = 0;
817 return;
822 switch (c &= 0x7F) {
824 case '\n':
826 if (++ip->cury == ip->rows) {
827 --ip->cury;
828 ite_erasecursor(ip, sp);
829 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
830 ite_clrtoeol(ip, sp, ip->cury, 0);
831 } else
832 ite_movecursor(ip, sp);
833 clr_attr(ip, ATTR_INV);
834 break;
836 case '\r':
837 if (ip->curx) {
838 ip->curx = 0;
839 ite_movecursor(ip, sp);
841 break;
843 case '\b':
844 if (--ip->curx < 0)
845 ip->curx = 0;
846 else
847 ite_movecursor(ip, sp);
848 break;
850 case '\t':
851 if (ip->curx < TABEND(ip)) {
852 n = TABSIZE - (ip->curx & (TABSIZE - 1));
853 ip->curx += n;
854 ite_movecursor(ip, sp);
855 } else
856 itecheckwrap(ip, sp);
857 break;
859 case CTRL('G'):
860 if (console_kbdops != NULL)
861 (*console_kbdops->bell)(console_kbdops->arg);
862 break;
864 case ESC:
865 ip->escape = ESC;
866 break;
868 default:
869 if (c < ' ' || c == DEL)
870 break;
871 if (ip->imode)
872 ite_ichar(ip, sp);
873 if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
874 attrset(ip, ATTR_INV);
875 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
876 } else
877 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
878 ite_drawcursor(ip, sp);
879 itecheckwrap(ip, sp);
880 break;
884 static void
885 itecheckwrap(struct ite_data *ip, struct itesw *sp)
888 if (++ip->curx == ip->cols) {
889 ip->curx = 0;
890 clr_attr(ip, ATTR_INV);
891 if (++ip->cury == ip->rows) {
892 --ip->cury;
893 ite_erasecursor(ip, sp);
894 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
895 ite_clrtoeol(ip, sp, ip->cury, 0);
896 return;
899 ite_movecursor(ip, sp);
902 static void
903 ite_dchar(struct ite_data *ip, struct itesw *sp)
906 if (ip->curx < ip->cols - 1) {
907 ite_erasecursor(ip, sp);
908 (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT);
909 attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx,
910 1, ip->cols - ip->curx - 1);
912 attrclr(ip, ip->cury, ip->cols - 1, 1, 1);
913 (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR);
914 ite_drawcursor(ip, sp);
917 static void
918 ite_ichar(struct ite_data *ip, struct itesw *sp)
921 if (ip->curx < ip->cols - 1) {
922 ite_erasecursor(ip, sp);
923 (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT);
924 attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1,
925 1, ip->cols - ip->curx - 1);
927 attrclr(ip, ip->cury, ip->curx, 1, 1);
928 (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR);
929 ite_drawcursor(ip, sp);
932 static void
933 ite_dline(struct ite_data *ip, struct itesw *sp)
936 if (ip->cury < ip->rows - 1) {
937 ite_erasecursor(ip, sp);
938 (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP);
939 attrmov(ip, ip->cury + 1, 0, ip->cury, 0,
940 ip->rows - ip->cury - 1, ip->cols);
942 ite_clrtoeol(ip, sp, ip->rows - 1, 0);
945 static void
946 ite_iline(struct ite_data *ip, struct itesw *sp)
949 if (ip->cury < ip->rows - 1) {
950 ite_erasecursor(ip, sp);
951 (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN);
952 attrmov(ip, ip->cury, 0, ip->cury + 1, 0,
953 ip->rows - ip->cury - 1, ip->cols);
955 ite_clrtoeol(ip, sp, ip->cury, 0);
958 static void
959 ite_clrtoeol(struct ite_data *ip, struct itesw *sp, int y, int x)
962 (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
963 attrclr(ip, y, x, 1, ip->cols - x);
964 ite_drawcursor(ip, sp);
967 void
968 ite_clrtoeos(struct ite_data *ip, struct itesw *sp)
971 (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
972 attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
973 ite_drawcursor(ip, sp);
979 * Console functions. Console probes are done by the individual
980 * framebuffer drivers.
983 void
984 itedisplaycnattach(struct grf_data *gp, struct itesw *isw)
986 struct ite_data *ip = &ite_cn;
989 * Set up required ite data and initialize ite.
991 ip->isw = isw;
992 ip->grf = gp;
993 ip->flags = ITE_ALIVE|ITE_CONSOLE|ITE_ACTIVE|ITE_ISCONS;
994 ip->attrbuf = ite_console_attributes;
995 iteinit(ip);
996 console_display_attached = 1;
998 if (console_kbd_attached && console_display_attached)
999 itecninit();
1002 void
1003 itekbdcnattach(struct ite_kbdops *ops, struct ite_kbdmap *map)
1006 console_kbdops = ops;
1007 console_kbdmap = map;
1008 console_kbd_attached = 1;
1010 if (console_kbd_attached && console_display_attached)
1011 itecninit();
1014 void
1015 itecninit(void)
1018 cn_tab = &ite_cons;
1019 cn_tab->cn_dev = makedev(cdevsw_lookup_major(&ite_cdevsw), 0);
1022 /*ARGSUSED*/
1024 itecngetc(dev_t dev)
1026 int c = 0;
1027 int stat;
1029 if (console_kbdops == NULL)
1030 return -1;
1032 c = (*console_kbdops->getc)(&stat);
1033 switch ((stat >> KBD_SSHIFT) & KBD_SMASK) {
1034 case KBD_SHIFT:
1035 c = console_kbdmap->shiftmap[c & KBD_CHARMASK];
1036 break;
1037 case KBD_CTRL:
1038 c = console_kbdmap->ctrlmap[c & KBD_CHARMASK];
1039 break;
1040 case KBD_KEY:
1041 c = console_kbdmap->keymap[c & KBD_CHARMASK];
1042 break;
1043 default:
1044 c = 0;
1045 break;
1047 return c;
1050 /* ARGSUSED */
1051 void
1052 itecnputc(dev_t dev, int c)
1054 static int paniced = 0;
1055 struct ite_data *ip = &ite_cn;
1057 if (panicstr && !paniced &&
1058 (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
1059 (void) iteon(ip, 3);
1060 paniced = 1;
1062 iteputchar(c, ip);