ite.c revision 1.16 1 /* $NetBSD: ite.c,v 1.16 1999/03/24 14:11:47 minoura Exp $ */
2
3 /*
4 * Copyright (c) 1988 University of Utah.
5 * Copyright (c) 1990 The Regents of the University of California.
6 * All rights reserved.
7 *
8 * This code is derived from software contributed to Berkeley by
9 * the Systems Programming Group of the University of Utah Computer
10 * Science Department.
11 *
12 * Redistribution and use in source and binary forms, with or without
13 * modification, are permitted provided that the following conditions
14 * are met:
15 * 1. Redistributions of source code must retain the above copyright
16 * notice, this list of conditions and the following disclaimer.
17 * 2. Redistributions in binary form must reproduce the above copyright
18 * notice, this list of conditions and the following disclaimer in the
19 * documentation and/or other materials provided with the distribution.
20 * 3. All advertising materials mentioning features or use of this software
21 * must display the following acknowledgement:
22 * This product includes software developed by the University of
23 * California, Berkeley and its contributors.
24 * 4. Neither the name of the University nor the names of its contributors
25 * may be used to endorse or promote products derived from this software
26 * without specific prior written permission.
27 *
28 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
29 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
30 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
31 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
32 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
33 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
34 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
35 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
36 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
37 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
38 * SUCH DAMAGE.
39 *
40 * from: Utah $Hdr: ite.c 1.1 90/07/09$
41 *
42 * @(#)ite.c 7.6 (Berkeley) 5/16/91
43 */
44
45 /*
46 * ite - bitmaped terminal.
47 * Supports VT200, a few terminal features will be unavailable until
48 * the system actually probes the device (i.e. not after consinit())
49 */
50
51 #include "ite.h"
52 #if NITE > 0
53
54 #include "bell.h"
55 #include "kbd.h"
56
57 #include <sys/param.h>
58 #include <sys/conf.h>
59 #include <sys/proc.h>
60 #include <sys/ioctl.h>
61 #include <sys/tty.h>
62 #include <sys/systm.h>
63 #include <sys/device.h>
64 #include <sys/malloc.h>
65
66 #include <machine/cpu.h>
67 #include <machine/kbio.h>
68 #include <machine/bus.h>
69 #include <machine/grfioctl.h>
70 #include <machine/iteioctl.h>
71
72 #include <arch/x68k/dev/grfvar.h>
73 #include <arch/x68k/dev/itevar.h>
74 #include <arch/x68k/dev/kbdmap.h>
75 #include <arch/x68k/dev/mfp.h>
76 #if NBELL > 0
77 void opm_bell __P((void));
78 #endif
79
80 #define SUBR_CNPROBE(min) itesw[min].ite_cnprobe(min)
81 #define SUBR_INIT(ip) ip->isw->ite_init(ip)
82 #define SUBR_DEINIT(ip) ip->isw->ite_deinit(ip)
83 #define SUBR_PUTC(ip,c,dy,dx,m) ip->isw->ite_putc(ip,c,dy,dx,m)
84 #define SUBR_CURSOR(ip,flg) ip->isw->ite_cursor(ip,flg)
85 #define SUBR_CLEAR(ip,sy,sx,h,w) ip->isw->ite_clear(ip,sy,sx,h,w)
86 #define SUBR_SCROLL(ip,sy,sx,count,dir) \
87 ip->isw->ite_scroll(ip,sy,sx,count,dir)
88
89 struct consdev;
90
91 __inline static void itesendch __P((int));
92 __inline static void alignment_display __P((struct ite_softc *));
93 __inline static void snap_cury __P((struct ite_softc *));
94 __inline static void ite_dnchar __P((struct ite_softc *, int));
95 static void ite_inchar __P((struct ite_softc *, int));
96 __inline static void ite_clrtoeol __P((struct ite_softc *));
97 __inline static void ite_clrtobol __P((struct ite_softc *));
98 __inline static void ite_clrline __P((struct ite_softc *));
99 __inline static void ite_clrtoeos __P((struct ite_softc *));
100 __inline static void ite_clrtobos __P((struct ite_softc *));
101 __inline static void ite_clrscreen __P((struct ite_softc *));
102 __inline static void ite_dnline __P((struct ite_softc *, int));
103 __inline static void ite_inline __P((struct ite_softc *, int));
104 __inline static void ite_index __P((struct ite_softc *));
105 __inline static void ite_lf __P((struct ite_softc *));
106 __inline static void ite_crlf __P((struct ite_softc *));
107 __inline static void ite_cr __P((struct ite_softc *));
108 __inline static void ite_rlf __P((struct ite_softc *));
109 static void iteprecheckwrap __P((struct ite_softc *ip));
110 static void itecheckwrap __P((struct ite_softc *ip));
111 static void repeat_handler __P((void *arg));
112 static int ite_argnum __P((struct ite_softc *ip));
113 static int ite_zargnum __P((struct ite_softc *ip));
114 static void ite_sendstr __P((struct ite_softc *ip, char *str));
115 __inline static int atoi __P((const char *cp));
116 __inline static char *index __P((const char *cp, char ch));
117 void ite_reset __P((struct ite_softc *ip));
118 struct ite_softc *getitesp __P((dev_t));
119 int iteon __P((dev_t, int));
120 void iteoff __P((dev_t, int));
121
122 struct itesw itesw[] = {
123 {0, tv_init, tv_deinit, 0,
124 0, 0, 0}
125 };
126 int nitesw = sizeof(itesw) / sizeof(itesw[0]);
127
128 /*
129 * # of chars are output in a single itestart() call.
130 * If this is too big, user processes will be blocked out for
131 * long periods of time while we are emptying the queue in itestart().
132 * If it is too small, console output will be very ragged.
133 */
134 #define ITEBURST 64
135
136 int nite = NITE;
137 struct tty *ite_tty[NITE];
138 struct ite_softc *kbd_ite = NULL;
139 struct ite_softc con_itesoftc;
140
141 struct tty *kbd_tty = NULL;
142
143 int start_repeat_timeo = 20; /* /100: initial timeout till pressed key repeats */
144 int next_repeat_timeo = 3; /* /100: timeout when repeating for next char */
145
146 u_char cons_tabs[MAX_TABS];
147
148 cdev_decl(ite);
149
150 void itestart __P((struct tty *tp));
151
152 void iteputchar __P((int c, struct ite_softc *ip));
153 void ite_putstr __P((const u_char * s, int len, dev_t dev));
154
155 void iteattach __P((struct device *, struct device *, void *));
156 int itematch __P((struct device *, struct cfdata *, void *));
157
158 struct cfattach ite_ca = {
159 sizeof(struct ite_softc), itematch, iteattach
160 };
161
162 extern struct cfdriver ite_cd;
163
164 int
165 itematch(pdp, cdp, auxp)
166 struct device *pdp;
167 struct cfdata *cdp;
168 void *auxp;
169 {
170 struct grf_softc *gp;
171 #if 0
172 int maj;
173 #endif
174
175 gp = auxp;
176
177 /* ite0 should be at grf0 XXX */
178 if(cdp->cf_unit != gp->g_device.dv_unit)
179 return(0);
180
181 #if 0
182 /*
183 * all that our mask allows (more than enough no one
184 * has > 32 monitors for text consoles on one machine)
185 */
186 if (cdp->cf_unit >= sizeof(ite_confunits) * NBBY)
187 return(0);
188 /*
189 * XXX
190 * normally this would be done in attach, however
191 * during early init we do not have a device pointer
192 * and thus no unit number.
193 */
194 for(maj = 0; maj < nchrdev; maj++)
195 if (cdevsw[maj].d_open == iteopen)
196 break;
197 gp->g_itedev = makedev(maj, cdp->cf_unit);
198 #endif
199 return(1);
200 }
201
202 /*
203 * iteinit() is the standard entry point for initialization of
204 * an ite device, it is also called from ite_cninit().
205 */
206 void
207 iteattach(pdp, dp, auxp)
208 struct device *pdp, *dp;
209 void *auxp;
210 {
211 struct ite_softc *ip;
212 struct grf_softc *gp;
213
214 gp = (struct grf_softc *)auxp;
215 if (dp) {
216 ip = (struct ite_softc *)dp;
217 if(con_itesoftc.grf != NULL
218 /*&& con_itesoftc.grf->g_unit == gp->g_unit*/) {
219 /*
220 * console reinit copy params over.
221 * and console always gets keyboard
222 */
223 bcopy(&con_itesoftc.grf, &ip->grf,
224 (char *)&ip[1] - (char *)&ip->grf);
225 con_itesoftc.grf = NULL;
226 kbd_ite = ip;
227 }
228 ip->grf = gp;
229 iteinit(ip->device.dv_unit); /* XXX */
230 printf(": rows %d cols %d", ip->rows, ip->cols);
231 if (kbd_ite == NULL)
232 kbd_ite = ip;
233 printf("\n");
234 } else {
235 if (con_itesoftc.grf != NULL)
236 return;
237 con_itesoftc.grf = gp;
238 con_itesoftc.tabs = cons_tabs;
239 }
240 }
241
242 struct ite_softc *
243 getitesp(dev)
244 dev_t dev;
245 {
246 extern int x68k_realconfig;
247
248 if (x68k_realconfig && con_itesoftc.grf == NULL)
249 return(ite_cd.cd_devs[UNIT(dev)]);
250
251 if (con_itesoftc.grf == NULL)
252 panic("no ite_softc for console");
253 return(&con_itesoftc);
254 }
255
256 void
257 iteinit(dev)
258 dev_t dev;
259 {
260 struct ite_softc *ip;
261
262 ip = getitesp(dev);
263
264 if (ip->flags & ITE_INITED)
265 return;
266 bcopy(&ascii_kbdmap, &kbdmap, sizeof(struct kbdmap));
267
268 ip->curx = 0;
269 ip->cury = 0;
270 ip->cursorx = 0;
271 ip->cursory = 0;
272
273 ip->isw = &itesw[ip->device.dv_unit]; /* XXX */
274 SUBR_INIT(ip);
275 SUBR_CURSOR(ip, DRAW_CURSOR);
276 if (!ip->tabs)
277 ip->tabs = malloc(MAX_TABS*sizeof(u_char), M_DEVBUF, M_WAITOK);
278 ite_reset(ip);
279 ip->flags |= ITE_INITED;
280 }
281
282 /*
283 * Perform functions necessary to setup device as a terminal emulator.
284 */
285 int
286 iteon(dev, flag)
287 dev_t dev;
288 int flag;
289 {
290 int unit = UNIT(dev);
291 struct ite_softc *ip;
292
293 if (unit < 0 || unit >= ite_cd.cd_ndevs ||
294 (ip = getitesp(unit)) == NULL || (ip->flags&ITE_ALIVE) == 0)
295 return(ENXIO);
296 /* force ite active, overriding graphics mode */
297 if (flag & 1) {
298 ip->flags |= ITE_ACTIVE;
299 ip->flags &= ~(ITE_INGRF|ITE_INITED);
300 }
301 /* leave graphics mode */
302 if (flag & 2) {
303 ip->flags &= ~ITE_INGRF;
304 if ((ip->flags & ITE_ACTIVE) == 0)
305 return(0);
306 }
307 ip->flags |= ITE_ACTIVE;
308 if (ip->flags & ITE_INGRF)
309 return(0);
310 iteinit(dev);
311 #if NKBD > 0
312 mfp_send_usart (0x49); /* XXX */
313 #endif
314 return(0);
315 }
316
317 /*
318 * "Shut down" device as terminal emulator.
319 * Note that we do not deinit the console device unless forced.
320 * Deinit'ing the console every time leads to a very active
321 * screen when processing /etc/rc.
322 */
323 void
324 iteoff(dev, flag)
325 dev_t dev;
326 int flag;
327 {
328 int unit = UNIT(dev);
329 register struct ite_softc *ip;
330
331 /* XXX check whether when call from grf.c */
332 if (unit < 0 || unit >= ite_cd.cd_ndevs ||
333 (ip = getitesp(unit)) == NULL || (ip->flags&ITE_ALIVE) == 0)
334 return;
335 if (flag & 2)
336 ip->flags |= ITE_INGRF;
337
338 if ((ip->flags & ITE_ACTIVE) == 0)
339 return;
340 if ((flag & 1) ||
341 (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
342 SUBR_DEINIT(ip);
343
344 /*
345 * XXX When the system is rebooted with "reboot", init(8)
346 * kills the last process to have the console open.
347 * If we don't revent the the ITE_ACTIVE bit from being
348 * cleared, we will never see messages printed during
349 * the process of rebooting.
350 */
351 if ((flag & 2) == 0 && (ip->flags & ITE_ISCONS) == 0) {
352 ip->flags &= ~ITE_ACTIVE;
353 #if NKBD > 0
354 mfp_send_usart (0x48); /* XXX */
355 #endif
356 }
357 }
358
359 /*
360 * standard entry points to the device.
361 */
362
363 /* ARGSUSED */
364 int
365 iteopen(dev, mode, devtype, p)
366 dev_t dev;
367 int mode, devtype;
368 struct proc *p;
369 {
370 int unit = UNIT(dev);
371 register struct tty *tp;
372 register struct ite_softc *ip;
373 register int error;
374 int first = 0;
375
376 if (unit >= ite_cd.cd_ndevs || (ip = getitesp(dev)) == NULL)
377 return (ENXIO);
378 if (!ite_tty[unit]) {
379 tp = ite_tty[unit] = ttymalloc();
380 tty_attach(tp);
381 } else
382 tp = ite_tty[unit];
383 if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)
384 && p->p_ucred->cr_uid != 0)
385 return (EBUSY);
386 if ((ip->flags & ITE_ACTIVE) == 0) {
387 error = iteon(dev, 0);
388 if (error)
389 return (error);
390 first = 1;
391 }
392 tp->t_oproc = itestart;
393 tp->t_param = NULL;
394 tp->t_dev = dev;
395 if ((tp->t_state&TS_ISOPEN) == 0) {
396 ttychars(tp);
397 tp->t_iflag = TTYDEF_IFLAG;
398 tp->t_oflag = TTYDEF_OFLAG;
399 tp->t_cflag = TTYDEF_CFLAG;
400 tp->t_lflag = TTYDEF_LFLAG;
401 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
402 tp->t_state = TS_ISOPEN|TS_CARR_ON;
403 ttsetwater(tp);
404 }
405 error = (*linesw[tp->t_line].l_open)(dev, tp);
406 if (error == 0) {
407 tp->t_winsize.ws_row = ip->rows;
408 tp->t_winsize.ws_col = ip->cols;
409 } else if (first)
410 iteoff(dev, 0);
411 return (error);
412 }
413
414 /*ARGSUSED*/
415 int
416 iteclose(dev, flag, mode, p)
417 dev_t dev;
418 int flag, mode;
419 struct proc *p;
420 {
421 register struct tty *tp = ite_tty[UNIT(dev)];
422
423 (*linesw[tp->t_line].l_close)(tp, flag);
424 ttyclose(tp);
425 iteoff(dev, 0);
426 #if 0
427 ttyfree(tp);
428 ite_tty[UNIT(dev)] = (struct tty *)0;
429 #endif
430 return(0);
431 }
432
433 int
434 iteread(dev, uio, flag)
435 dev_t dev;
436 struct uio *uio;
437 int flag;
438 {
439 register struct tty *tp = ite_tty[UNIT(dev)];
440
441 return ((*linesw[tp->t_line].l_read)(tp, uio, flag));
442 }
443
444 int
445 itewrite(dev, uio, flag)
446 dev_t dev;
447 struct uio *uio;
448 int flag;
449 {
450 register struct tty *tp = ite_tty[UNIT(dev)];
451
452 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
453 }
454
455 struct tty *
456 itetty(dev)
457 dev_t dev;
458 {
459
460 return (ite_tty[UNIT(dev)]);
461 }
462
463 int
464 iteioctl(dev, cmd, addr, flag, p)
465 dev_t dev;
466 u_long cmd;
467 caddr_t addr;
468 int flag;
469 struct proc *p;
470 {
471 struct iterepeat *irp;
472 register struct tty *tp = ite_tty[UNIT(dev)];
473 int error;
474
475 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag, p);
476 if (error >= 0)
477 return (error);
478 error = ttioctl(tp, cmd, addr, flag, p);
479 if (error >= 0)
480 return (error);
481
482 switch (cmd) {
483 case ITEIOCSKMAP:
484 if (addr == 0)
485 return(EFAULT);
486 bcopy(addr, &kbdmap, sizeof(struct kbdmap));
487 return(0);
488
489 case ITEIOCGKMAP:
490 if (addr == NULL)
491 return(EFAULT);
492 bcopy(&kbdmap, addr, sizeof(struct kbdmap));
493 return(0);
494
495 case ITEIOCGREPT:
496 irp = (struct iterepeat *)addr;
497 irp->start = start_repeat_timeo;
498 irp->next = next_repeat_timeo;
499
500 case ITEIOCSREPT:
501 irp = (struct iterepeat *)addr;
502 if (irp->start < ITEMINREPEAT && irp->next < ITEMINREPEAT)
503 return(EINVAL);
504 start_repeat_timeo = irp->start;
505 next_repeat_timeo = irp->next;
506 #if x68k
507 case ITELOADFONT:
508 if (addr) {
509 bcopy(addr, kern_font, 4096 /*sizeof (kernel_font)*/);
510 return 0;
511 } else
512 return EFAULT;
513
514 case ITETVCTRL:
515 if (addr && *(u_int8_t *)addr < 0x40) {
516 return mfp_send_usart (* (u_int8_t *)addr);
517 } else {
518 return EFAULT;
519 }
520 #endif
521 }
522 return (ENOTTY);
523 }
524
525 void
526 itestart(tp)
527 register struct tty *tp;
528 {
529 struct clist *rbp;
530 struct ite_softc *ip;
531 u_char buf[ITEBURST];
532 int s, len;
533
534 ip = getitesp(tp->t_dev);
535 /*
536 * (Potentially) lower priority. We only need to protect ourselves
537 * from keyboard interrupts since that is all that can affect the
538 * state of our tty (kernel printf doesn't go through this routine).
539 */
540 s = spltty();
541 if (tp->t_state & (TS_TIMEOUT | TS_BUSY | TS_TTSTOP))
542 goto out;
543 tp->t_state |= TS_BUSY;
544 rbp = &tp->t_outq;
545 len = q_to_b(rbp, buf, ITEBURST);
546 /*splx(s);*/
547
548 /* Here is a really good place to implement pre/jumpscroll() */
549 ite_putstr(buf, len, tp->t_dev);
550
551 /*s = spltty();*/
552 tp->t_state &= ~TS_BUSY;
553 /* we have characters remaining. */
554 if (rbp->c_cc) {
555 tp->t_state |= TS_TIMEOUT;
556 timeout(ttrstrt, (caddr_t)tp, 1);
557 }
558 /* wakeup we are below */
559 if (rbp->c_cc <= tp->t_lowat) {
560 if (tp->t_state & TS_ASLEEP) {
561 tp->t_state &= ~TS_ASLEEP;
562 wakeup((caddr_t)rbp);
563 }
564 selwakeup(&tp->t_wsel);
565 }
566 out:
567 splx(s);
568 }
569
570 /* XXX called after changes made in underlying grf layer. */
571 /* I want to nuke this */
572 void
573 ite_reinit(dev)
574 dev_t dev;
575 {
576 struct ite_softc *ip;
577 int unit = UNIT(dev);
578
579 /* XXX check whether when call from grf.c */
580 if (unit < 0 || unit >= ite_cd.cd_ndevs ||
581 (ip = getitesp(unit)) == NULL)
582 return;
583
584 ip->flags &= ~ITE_INITED;
585 iteinit(dev);
586 }
587
588 void
589 ite_reset(ip)
590 struct ite_softc *ip;
591 {
592 int i;
593
594 ip->curx = 0;
595 ip->cury = 0;
596 ip->attribute = 0;
597 ip->save_curx = 0;
598 ip->save_cury = 0;
599 ip->save_attribute = 0;
600 ip->ap = ip->argbuf;
601 ip->emul_level = EMUL_VT300_8;
602 ip->eightbit_C1 = 0;
603 ip->top_margin = 0;
604 ip->bottom_margin = ip->rows - 1;
605 ip->inside_margins = 0; /* origin mode == absolute */
606 ip->linefeed_newline = 0;
607 ip->auto_wrap = 1;
608 ip->cursor_appmode = 0;
609 ip->keypad_appmode = 0;
610 ip->imode = 0;
611 ip->key_repeat = 1;
612 ip->G0 = CSET_ASCII;
613 ip->G1 = CSET_JIS1983;
614 ip->G2 = CSET_JISKANA;
615 ip->G3 = CSET_JIS1990;
616 ip->GL = &ip->G0;
617 ip->GR = &ip->G1;
618 ip->save_GL = 0;
619 ip->save_char = 0;
620 ip->fgcolor = 7;
621 ip->bgcolor = 0;
622 for (i = 0; i < ip->cols; i++)
623 ip->tabs[i] = ((i & 7) == 0);
624 /* XXX clear screen */
625 SUBR_CLEAR(ip, 0, 0, ip->rows, ip->cols);
626 attrclr(ip, 0, 0, ip->rows, ip->cols);
627 }
628
629 /* Used in console at startup only */
630 int
631 ite_cnfilter(c)
632 u_char c;
633 {
634 static u_char mod = 0;
635 struct key key;
636 u_char code, up, mask;
637 int s;
638
639 up = c & 0x80 ? 1 : 0;
640 c &= 0x7f;
641 code = 0;
642
643 s = spltty();
644
645 mask = 0;
646 if (c >= KBD_LEFT_ALT && !(c >= 0x63 && c <= 0x6c)) { /* 0x63: F1, 0x6c:F10 */
647 switch (c) {
648 case KBD_LEFT_SHIFT:
649 mask = KBD_MOD_SHIFT;
650 break;
651
652 case KBD_LEFT_ALT:
653 mask = KBD_MOD_LALT;
654 break;
655
656 case KBD_RIGHT_ALT:
657 mask = KBD_MOD_RALT;
658 break;
659
660 case KBD_LEFT_META:
661 mask = KBD_MOD_LMETA;
662 break;
663
664 case KBD_RIGHT_META:
665 mask = KBD_MOD_RMETA;
666 break;
667
668 case KBD_CAPS_LOCK:
669 /*
670 * capslock already behaves `right', don't need to
671 * keep track of the state in here.
672 */
673 mask = KBD_MOD_CAPS;
674 break;
675
676 case KBD_CTRL:
677 mask = KBD_MOD_CTRL;
678 break;
679
680 case KBD_RECONNECT:
681 /* ite got 0xff */
682 if (up)
683 kbd_setLED();
684 break;
685 }
686 if (mask & KBD_MOD_CAPS) {
687 if (!up) {
688 mod ^= KBD_MOD_CAPS;
689 kbdled ^= LED_CAPS_LOCK;
690 kbd_setLED();
691 }
692 } else if (up)
693 mod &= ~mask;
694 else mod |= mask;
695 splx (s);
696 return -1;
697 }
698
699 if (up) {
700 splx(s);
701 return -1;
702 }
703
704 /* translate modifiers */
705 if (mod & KBD_MOD_SHIFT) {
706 if (mod & KBD_MOD_ALT)
707 key = kbdmap.alt_shift_keys[c];
708 else
709 key = kbdmap.shift_keys[c];
710 } else if (mod & KBD_MOD_ALT)
711 key = kbdmap.alt_keys[c];
712 else {
713 key = kbdmap.keys[c];
714 /* if CAPS and key is CAPable (no pun intended) */
715 if ((mod & KBD_MOD_CAPS) && (key.mode & KBD_MODE_CAPS))
716 key = kbdmap.shift_keys[c];
717 }
718 code = key.code;
719
720 /* if string return */
721 if (key.mode & (KBD_MODE_STRING | KBD_MODE_KPAD)) {
722 splx(s);
723 return -1;
724 }
725 /* handle dead keys */
726 if (key.mode & KBD_MODE_DEAD) {
727 splx(s);
728 return -1;
729 }
730 if (mod & KBD_MOD_CTRL)
731 code &= 0x1f;
732 if (mod & KBD_MOD_META)
733 code |= 0x80;
734
735 /* do console mapping. */
736 code = code == '\r' ? '\n' : code;
737
738 splx(s);
739 return (code);
740 }
741
742 /* And now the old stuff. */
743 __inline static void
744 itesendch (ch)
745 int ch;
746 {
747 (*linesw[kbd_tty->t_line].l_rint)(ch, kbd_tty);
748 }
749
750
751 void
752 ite_filter(c)
753 u_char c;
754 {
755 static u_short mod = 0;
756 register unsigned char code, *str;
757 u_short up, mask;
758 struct key key;
759 int s, i;
760
761 if (!kbd_ite)
762 return;
763 kbd_tty = ite_tty[kbd_ite->device.dv_unit];
764
765 /* have to make sure we're at spltty in here */
766 s = spltty ();
767
768 up = c & 0x80 ? 1 : 0;
769 c &= 0x7f;
770 code = 0;
771
772 mask = 0;
773 if (c >= KBD_LEFT_ALT &&
774 !(c >= 0x63 && c <= 0x6c)) { /* 0x63: F1, 0x6c:F10 */
775 switch (c) {
776 case KBD_LEFT_SHIFT:
777 mask = KBD_MOD_SHIFT;
778 break;
779
780 case KBD_LEFT_ALT:
781 mask = KBD_MOD_LALT;
782 break;
783
784 case KBD_RIGHT_ALT:
785 mask = KBD_MOD_RALT;
786 break;
787
788 case KBD_LEFT_META:
789 mask = KBD_MOD_LMETA;
790 break;
791
792 case KBD_RIGHT_META:
793 mask = KBD_MOD_RMETA;
794 break;
795
796 case KBD_CAPS_LOCK:
797 /*
798 * capslock already behaves `right', don't need to keep
799 * track of the state in here.
800 */
801 mask = KBD_MOD_CAPS;
802 break;
803
804 case KBD_CTRL:
805 mask = KBD_MOD_CTRL;
806 break;
807
808 case KBD_OPT1:
809 mask = KBD_MOD_OPT1;
810 break;
811
812 case KBD_OPT2:
813 mask = KBD_MOD_OPT2;
814 break;
815
816 case KBD_RECONNECT:
817 if (up) { /* ite got 0xff */
818 kbd_setLED();
819 }
820 break;
821 }
822
823 if (mask & KBD_MOD_CAPS) {
824 if (!up) {
825 mod ^= KBD_MOD_CAPS;
826 kbdled ^= LED_CAPS_LOCK;
827 kbd_setLED();
828 }
829 } else if (up) {
830 mod &= ~mask;
831 } else mod |= mask;
832
833 /*
834 * return even if it wasn't a modifier key, the other
835 * codes up here are either special (like reset warning),
836 * or not yet defined
837 */
838 splx (s);
839 return;
840 }
841
842 if (up) {
843 splx (s);
844 return;
845 }
846
847 /*
848 * intercept LAlt-LMeta-F1 here to switch back to original ascii-keymap.
849 * this should probably be configurable..
850 */
851 if (mod == (KBD_MOD_LALT|KBD_MOD_LMETA) && c == 0x63) {
852 bcopy (&ascii_kbdmap, &kbdmap, sizeof (struct kbdmap));
853 splx (s);
854 return;
855 }
856
857 /* translate modifiers */
858 if (mod & KBD_MOD_SHIFT) {
859 if (mod & KBD_MOD_ALT)
860 key = kbdmap.alt_shift_keys[c];
861 else
862 key = kbdmap.shift_keys[c];
863 } else if (mod & KBD_MOD_ALT)
864 key = kbdmap.alt_keys[c];
865 else {
866 key = kbdmap.keys[c];
867 /* if CAPS and key is CAPable (no pun intended) */
868 if ((mod & KBD_MOD_CAPS) && (key.mode & KBD_MODE_CAPS))
869 key = kbdmap.shift_keys[c];
870 else if ((mod & KBD_MOD_OPT2) && (key.mode & KBD_MODE_KPAD))
871 key = kbdmap.shift_keys[c];
872 }
873 code = key.code;
874
875 /* handle dead keys */
876 if (key.mode & KBD_MODE_DEAD) {
877 splx (s);
878 return;
879 }
880 /* if not string, apply META and CTRL modifiers */
881 if (! (key.mode & KBD_MODE_STRING)
882 && (!(key.mode & KBD_MODE_KPAD) ||
883 (kbd_ite && !kbd_ite->keypad_appmode))) {
884 if ((mod & KBD_MOD_CTRL) &&
885 (code == ' ' || (code >= '@' && code <= 'z')))
886 code &= 0x1f;
887 if (mod & KBD_MOD_META)
888 code |= 0x80;
889 } else if ((key.mode & KBD_MODE_KPAD) &&
890 (kbd_ite && kbd_ite->keypad_appmode)) {
891 static char *in = "0123456789-+.\r()/*";
892 static char *out = "pqrstuvwxymlnMPQRS";
893 char *cp = index (in, code);
894
895 /*
896 * keypad-appmode sends SS3 followed by the above
897 * translated character
898 */
899 (*linesw[kbd_tty->t_line].l_rint) (27, kbd_tty);
900 (*linesw[kbd_tty->t_line].l_rint) ('O', kbd_tty);
901 (*linesw[kbd_tty->t_line].l_rint) (out[cp - in], kbd_tty);
902 splx(s);
903 return;
904 } else {
905 /* *NO* I don't like this.... */
906 static u_char app_cursor[] =
907 {
908 3, 27, 'O', 'A',
909 3, 27, 'O', 'B',
910 3, 27, 'O', 'C',
911 3, 27, 'O', 'D'};
912
913 str = kbdmap.strings + code;
914 /*
915 * if this is a cursor key, AND it has the default
916 * keymap setting, AND we're in app-cursor mode, switch
917 * to the above table. This is *nasty* !
918 */
919 if (c >= 0x3b && c <= 0x3e && kbd_ite->cursor_appmode
920 && !bcmp(str, "\x03\x1b[", 3) &&
921 index("ABCD", str[3]))
922 str = app_cursor + 4 * (str[3] - 'A');
923
924 /*
925 * using a length-byte instead of 0-termination allows
926 * to embed \0 into strings, although this is not used
927 * in the default keymap
928 */
929 for (i = *str++; i; i--)
930 (*linesw[kbd_tty->t_line].l_rint) (*str++, kbd_tty);
931 splx(s);
932 return;
933 }
934 (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
935
936 splx(s);
937 return;
938 }
939
940 /* helper functions, makes the code below more readable */
941 __inline static void
942 ite_sendstr (ip, str)
943 struct ite_softc *ip;
944 char *str;
945 {
946 while (*str)
947 itesendch (*str++);
948 }
949
950 __inline static void
951 alignment_display(ip)
952 struct ite_softc *ip;
953 {
954 int i, j;
955
956 for (j = 0; j < ip->rows; j++)
957 for (i = 0; i < ip->cols; i++)
958 SUBR_PUTC(ip, 'E', j, i, ATTR_NOR);
959 attrclr(ip, 0, 0, ip->rows, ip->cols);
960 }
961
962 __inline static void
963 snap_cury(ip)
964 struct ite_softc *ip;
965 {
966 if (ip->inside_margins) {
967 if (ip->cury < ip->top_margin)
968 ip->cury = ip->top_margin;
969 if (ip->cury > ip->bottom_margin)
970 ip->cury = ip->bottom_margin;
971 }
972 }
973
974 __inline static void
975 ite_dnchar(ip, n)
976 struct ite_softc *ip;
977 int n;
978 {
979 n = min(n, ip->cols - ip->curx);
980 if (n < ip->cols - ip->curx) {
981 SUBR_SCROLL(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT);
982 attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx,
983 1, ip->cols - ip->curx - n);
984 attrclr(ip, ip->cury, ip->cols - n, 1, n);
985 }
986 while (n-- > 0)
987 SUBR_PUTC(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR);
988 }
989
990 static void
991 ite_inchar(ip, n)
992 struct ite_softc *ip;
993 int n;
994 {
995 int c = ip->save_char;
996 ip->save_char = 0;
997 n = min(n, ip->cols - ip->curx);
998 if (n < ip->cols - ip->curx) {
999 SUBR_SCROLL(ip, ip->cury, ip->curx, n, SCROLL_RIGHT);
1000 attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n,
1001 1, ip->cols - ip->curx - n);
1002 attrclr(ip, ip->cury, ip->curx, 1, n);
1003 }
1004 while (n--)
1005 SUBR_PUTC(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
1006 ip->save_char = c;
1007 }
1008
1009 __inline static void
1010 ite_clrtoeol(ip)
1011 struct ite_softc *ip;
1012 {
1013 int y = ip->cury, x = ip->curx;
1014 if (ip->cols - x > 0) {
1015 SUBR_CLEAR(ip, y, x, 1, ip->cols - x);
1016 attrclr(ip, y, x, 1, ip->cols - x);
1017 }
1018 }
1019
1020 __inline static void
1021 ite_clrtobol(ip)
1022 struct ite_softc *ip;
1023 {
1024 int y = ip->cury, x = min(ip->curx + 1, ip->cols);
1025 SUBR_CLEAR(ip, y, 0, 1, x);
1026 attrclr(ip, y, 0, 1, x);
1027 }
1028
1029 __inline static void
1030 ite_clrline(ip)
1031 struct ite_softc *ip;
1032 {
1033 int y = ip->cury;
1034 SUBR_CLEAR(ip, y, 0, 1, ip->cols);
1035 attrclr(ip, y, 0, 1, ip->cols);
1036 }
1037
1038 __inline static void
1039 ite_clrtoeos(ip)
1040 struct ite_softc *ip;
1041 {
1042 ite_clrtoeol(ip);
1043 if (ip->cury < ip->rows - 1) {
1044 SUBR_CLEAR(ip, ip->cury + 1, 0, ip->rows - 1 - ip->cury, ip->cols);
1045 attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
1046 }
1047 }
1048
1049 __inline static void
1050 ite_clrtobos(ip)
1051 struct ite_softc *ip;
1052 {
1053 ite_clrtobol(ip);
1054 if (ip->cury > 0) {
1055 SUBR_CLEAR(ip, 0, 0, ip->cury, ip->cols);
1056 attrclr(ip, 0, 0, ip->cury, ip->cols);
1057 }
1058 }
1059
1060 __inline static void
1061 ite_clrscreen(ip)
1062 struct ite_softc *ip;
1063 {
1064 SUBR_CLEAR(ip, 0, 0, ip->rows, ip->cols);
1065 attrclr(ip, 0, 0, ip->rows, ip->cols);
1066 }
1067
1068
1069
1070 __inline static void
1071 ite_dnline(ip, n)
1072 struct ite_softc *ip;
1073 int n;
1074 {
1075 /*
1076 * interesting.. if the cursor is outside the scrolling
1077 * region, this command is simply ignored..
1078 */
1079 if (ip->cury < ip->top_margin || ip->cury > ip->bottom_margin)
1080 return;
1081
1082 n = min(n, ip->bottom_margin + 1 - ip->cury);
1083 if (n <= ip->bottom_margin - ip->cury) {
1084 SUBR_SCROLL(ip, ip->cury + n, 0, n, SCROLL_UP);
1085 attrmov(ip, ip->cury + n, 0, ip->cury, 0,
1086 ip->bottom_margin + 1 - ip->cury - n, ip->cols);
1087 }
1088 SUBR_CLEAR(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
1089 attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
1090 }
1091
1092 __inline static void
1093 ite_inline(ip, n)
1094 struct ite_softc *ip;
1095 int n;
1096 {
1097 /*
1098 * interesting.. if the cursor is outside the scrolling
1099 * region, this command is simply ignored..
1100 */
1101 if (ip->cury < ip->top_margin || ip->cury > ip->bottom_margin)
1102 return;
1103
1104 if (n <= 0)
1105 n = 1;
1106 else n = min(n, ip->bottom_margin + 1 - ip->cury);
1107 if (n <= ip->bottom_margin - ip->cury) {
1108 SUBR_SCROLL(ip, ip->cury, 0, n, SCROLL_DOWN);
1109 attrmov(ip, ip->cury, 0, ip->cury + n, 0,
1110 ip->bottom_margin + 1 - ip->cury - n, ip->cols);
1111 }
1112 SUBR_CLEAR(ip, ip->cury, 0, n, ip->cols);
1113 attrclr(ip, ip->cury, 0, n, ip->cols);
1114 ip->curx = 0;
1115 }
1116
1117 __inline static void
1118 ite_index (ip)
1119 struct ite_softc *ip;
1120 {
1121 ++ip->cury;
1122 if ((ip->cury == ip->bottom_margin+1) || (ip->cury == ip->rows)) {
1123 ip->cury--;
1124 SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
1125 ite_clrline(ip);
1126 }
1127 /*clr_attr(ip, ATTR_INV);*/
1128 }
1129
1130 __inline static void
1131 ite_lf (ip)
1132 struct ite_softc *ip;
1133 {
1134 ++ip->cury;
1135 if (ip->cury > ip->bottom_margin) {
1136 ip->cury--;
1137 SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
1138 ite_clrline(ip);
1139 }
1140 /* SUBR_CURSOR(ip, MOVE_CURSOR);*/
1141 /*clr_attr(ip, ATTR_INV);*/
1142 /* reset character set ... thanks for mohta. */
1143 ip->G0 = CSET_ASCII;
1144 ip->G1 = CSET_JIS1983;
1145 ip->G2 = CSET_JISKANA;
1146 ip->G3 = CSET_JIS1990;
1147 ip->GL = &ip->G0;
1148 ip->GR = &ip->G1;
1149 ip->save_GL = 0;
1150 ip->save_char = 0;
1151 }
1152
1153 __inline static void
1154 ite_crlf (ip)
1155 struct ite_softc *ip;
1156 {
1157 ip->curx = 0;
1158 ite_lf (ip);
1159 }
1160
1161 __inline static void
1162 ite_cr (ip)
1163 struct ite_softc *ip;
1164 {
1165 if (ip->curx) {
1166 ip->curx = 0;
1167 }
1168 }
1169
1170 __inline static void
1171 ite_rlf (ip)
1172 struct ite_softc *ip;
1173 {
1174 ip->cury--;
1175 if ((ip->cury < 0) || (ip->cury == ip->top_margin - 1)) {
1176 ip->cury++;
1177 SUBR_SCROLL(ip, ip->top_margin, 0, 1, SCROLL_DOWN);
1178 ite_clrline(ip);
1179 }
1180 clr_attr(ip, ATTR_INV);
1181 }
1182
1183 __inline static int
1184 atoi (cp)
1185 const char *cp;
1186 {
1187 int n;
1188
1189 for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++)
1190 n = n * 10 + *cp - '0';
1191 return n;
1192 }
1193
1194 __inline static char *
1195 index(cp, ch)
1196 const char *cp;
1197 char ch;
1198 {
1199 while (*cp && *cp != ch)
1200 cp++;
1201 return *cp ? (char *) cp : 0;
1202 }
1203
1204 __inline static int
1205 ite_argnum (ip)
1206 struct ite_softc *ip;
1207 {
1208 char ch;
1209 int n;
1210
1211 /* convert argument string into number */
1212 if (ip->ap == ip->argbuf)
1213 return 1;
1214 ch = *ip->ap;
1215 *ip->ap = 0;
1216 n = atoi (ip->argbuf);
1217 *ip->ap = ch;
1218
1219 return n;
1220 }
1221
1222 __inline static int
1223 ite_zargnum (ip)
1224 struct ite_softc *ip;
1225 {
1226 char ch;
1227 int n;
1228
1229 /* convert argument string into number */
1230 if (ip->ap == ip->argbuf)
1231 return 0;
1232 ch = *ip->ap;
1233 *ip->ap = 0; /* terminate string */
1234 n = atoi (ip->argbuf);
1235 *ip->ap = ch;
1236
1237 return n; /* don't "n ? n : 1" here, <CSI>0m != <CSI>1m ! */
1238 }
1239
1240 void
1241 ite_putstr(s, len, dev)
1242 const u_char *s;
1243 int len;
1244 dev_t dev;
1245 {
1246 struct ite_softc *ip;
1247 int i;
1248
1249 ip = getitesp(dev);
1250
1251 /* XXX avoid problems */
1252 if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
1253 return;
1254
1255 SUBR_CURSOR(ip, START_CURSOROPT);
1256 for (i = 0; i < len; i++)
1257 if (s[i])
1258 iteputchar(s[i], ip);
1259 SUBR_CURSOR(ip, END_CURSOROPT);
1260 }
1261
1262 void
1263 iteputchar(c, ip)
1264 register int c;
1265 struct ite_softc *ip;
1266 {
1267 int n, x, y;
1268 char *cp;
1269
1270 if (c >= 0x20 && ip->escape) {
1271 switch (ip->escape) {
1272
1273 case ESC:
1274 switch (c) {
1275 /* first 7bit equivalents for the 8bit control characters */
1276
1277 case 'D':
1278 c = IND;
1279 ip->escape = 0;
1280 break; /* and fall into the next switch below (same for all `break') */
1281
1282 case 'E':
1283 /* next line */
1284 c = NEL;
1285 ip->escape = 0;
1286 break;
1287
1288 case 'H':
1289 /* set TAB at current col */
1290 c = HTS;
1291 ip->escape = 0;
1292 break;
1293
1294 case 'M':
1295 /* reverse index */
1296 c = RI;
1297 ip->escape = 0;
1298 break;
1299
1300 case 'N':
1301 /* single shift G2 */
1302 c = SS2;
1303 ip->escape = 0;
1304 break;
1305
1306 case 'O':
1307 /* single shift G3 */
1308 c = SS3;
1309 ip->escape = 0;
1310 break;
1311
1312 case 'P':
1313 /* DCS detected */
1314 c = DCS;
1315 ip->escape = 0;
1316 break;
1317
1318 case '[':
1319 c = CSI;
1320 ip->escape = 0;
1321 break;
1322
1323 case '\\':
1324 /* String Terminator */
1325 c = ST;
1326 ip->escape = 0;
1327 break;
1328
1329 case ']':
1330 c = OSC;
1331 ip->escape = 0;
1332 break;
1333
1334 case '^':
1335 c = PM;
1336 ip->escape = 0;
1337 break;
1338
1339 case '_':
1340 c = APC;
1341 ip->escape = 0;
1342 break;
1343
1344
1345 /* introduces 7/8bit control */
1346 case ' ':
1347 /* can be followed by either F or G */
1348 ip->escape = ' ';
1349 break;
1350
1351
1352 /* a lot of character set selections, not yet used...
1353 94-character sets: */
1354 case '(': /* G0 */
1355 case ')': /* G1 */
1356 ip->escape = c;
1357 return;
1358
1359 case '*': /* G2 */
1360 case '+': /* G3 */
1361 case 'B': /* ASCII */
1362 case 'A': /* ISO latin 1 */
1363 case '<': /* user preferred suplemental */
1364 case '0': /* dec special graphics */
1365
1366 /* 96-character sets: */
1367 case '-': /* G1 */
1368 case '.': /* G2 */
1369 case '/': /* G3 */
1370
1371 /* national character sets: */
1372 case '4': /* dutch */
1373 case '5':
1374 case 'C': /* finnish */
1375 case 'R': /* french */
1376 case 'Q': /* french canadian */
1377 case 'K': /* german */
1378 case 'Y': /* italian */
1379 case '6': /* norwegian/danish */
1380 /* note: %5 and %6 are not supported (two chars..) */
1381
1382 ip->escape = 0;
1383 /* just ignore for now */
1384 return;
1385
1386 /* 94-multibyte character sets designate */
1387 case '$':
1388 ip->escape = '$';
1389 return;
1390
1391 /* locking shift modes */
1392 case '`':
1393 ip->GR = &ip->G1;
1394 ip->escape = 0;
1395 return;
1396
1397 case 'n':
1398 ip->GL = &ip->G2;
1399 ip->escape = 0;
1400 return;
1401
1402 case '}':
1403 ip->GR = &ip->G2;
1404 ip->escape = 0;
1405 return;
1406
1407 case 'o':
1408 ip->GL = &ip->G3;
1409 ip->escape = 0;
1410 return;
1411
1412 case '|':
1413 ip->GR = &ip->G3;
1414 ip->escape = 0;
1415 return;
1416
1417 case '~':
1418 ip->GR = &ip->G1;
1419 ip->escape = 0;
1420 return;
1421
1422 /* font width/height control */
1423 case '#':
1424 ip->escape = '#';
1425 return;
1426
1427 case 'c':
1428 /* hard terminal reset .. */
1429 ite_reset (ip);
1430 SUBR_CURSOR(ip, MOVE_CURSOR);
1431 ip->escape = 0;
1432 return;
1433
1434
1435 case '7':
1436 /* save cursor */
1437 ip->save_curx = ip->curx;
1438 ip->save_cury = ip->cury;
1439 ip->save_attribute = ip->attribute;
1440 ip->sc_om = ip->inside_margins;
1441 ip->sc_G0 = ip->G0;
1442 ip->sc_G1 = ip->G1;
1443 ip->sc_G2 = ip->G2;
1444 ip->sc_G3 = ip->G3;
1445 ip->sc_GL = ip->GL;
1446 ip->sc_GR = ip->GR;
1447 ip->escape = 0;
1448 return;
1449
1450 case '8':
1451 /* restore cursor */
1452 ip->curx = ip->save_curx;
1453 ip->cury = ip->save_cury;
1454 ip->attribute = ip->save_attribute;
1455 ip->inside_margins = ip->sc_om;
1456 ip->G0 = ip->sc_G0;
1457 ip->G1 = ip->sc_G1;
1458 ip->G2 = ip->sc_G2;
1459 ip->G3 = ip->sc_G3;
1460 ip->GL = ip->sc_GL;
1461 ip->GR = ip->sc_GR;
1462 SUBR_CURSOR(ip, MOVE_CURSOR);
1463 ip->escape = 0;
1464 return;
1465
1466 case '=':
1467 /* keypad application mode */
1468 ip->keypad_appmode = 1;
1469 ip->escape = 0;
1470 return;
1471
1472 case '>':
1473 /* keypad numeric mode */
1474 ip->keypad_appmode = 0;
1475 ip->escape = 0;
1476 return;
1477
1478 case 'Z': /* request ID */
1479 if (ip->emul_level == EMUL_VT100)
1480 ite_sendstr (ip, "\033[61;0c"); /* XXX not clean */
1481 else
1482 ite_sendstr (ip, "\033[63;0c"); /* XXX not clean */
1483 ip->escape = 0;
1484 return;
1485
1486 /* default catch all for not recognized ESC sequences */
1487 default:
1488 ip->escape = 0;
1489 return;
1490 }
1491 break;
1492
1493
1494 case '(': /* designate G0 */
1495 switch (c) {
1496 case 'B': /* USASCII */
1497 ip->G0 = CSET_ASCII;
1498 ip->escape = 0;
1499 return;
1500 case 'I':
1501 ip->G0 = CSET_JISKANA;
1502 ip->escape = 0;
1503 return;
1504 case 'J':
1505 ip->G0 = CSET_JISROMA;
1506 ip->escape = 0;
1507 return;
1508 case 'A': /* British or ISO-Latin-1 */
1509 case 'H': /* Swedish */
1510 case 'K': /* German */
1511 case 'R': /* French */
1512 case 'Y': /* Italian */
1513 case 'Z': /* Spanish */
1514 default:
1515 /* not supported */
1516 ip->escape = 0;
1517 return;
1518 }
1519
1520 case ')': /* designate G1 */
1521 ip->escape = 0;
1522 return;
1523
1524 case '$': /* 94-multibyte character set */
1525 switch (c) {
1526 case '@':
1527 ip->G0 = CSET_JIS1978;
1528 ip->escape = 0;
1529 return;
1530 case 'B':
1531 ip->G0 = CSET_JIS1983;
1532 ip->escape = 0;
1533 return;
1534 case 'D':
1535 ip->G0 = CSET_JIS1990;
1536 ip->escape = 0;
1537 return;
1538 default:
1539 /* not supported */
1540 ip->escape = 0;
1541 return;
1542 }
1543
1544 case ' ':
1545 switch (c) {
1546 case 'F':
1547 ip->eightbit_C1 = 0;
1548 ip->escape = 0;
1549 return;
1550
1551 case 'G':
1552 ip->eightbit_C1 = 1;
1553 ip->escape = 0;
1554 return;
1555
1556 default:
1557 /* not supported */
1558 ip->escape = 0;
1559 return;
1560 }
1561 break;
1562
1563 case '#':
1564 switch (c) {
1565 case '5':
1566 /* single height, single width */
1567 ip->escape = 0;
1568 return;
1569
1570 case '6':
1571 /* double width, single height */
1572 ip->escape = 0;
1573 return;
1574
1575 case '3':
1576 /* top half */
1577 ip->escape = 0;
1578 return;
1579
1580 case '4':
1581 /* bottom half */
1582 ip->escape = 0;
1583 return;
1584
1585 case '8':
1586 /* screen alignment pattern... */
1587 alignment_display (ip);
1588 ip->escape = 0;
1589 return;
1590
1591 default:
1592 ip->escape = 0;
1593 return;
1594 }
1595 break;
1596
1597
1598
1599 case CSI:
1600 /* the biggie... */
1601 switch (c) {
1602 case '0': case '1': case '2': case '3': case '4':
1603 case '5': case '6': case '7': case '8': case '9':
1604 case ';': case '\"': case '$': case '>':
1605 if (ip->ap < ip->argbuf + MAX_ARGSIZE)
1606 *ip->ap++ = c;
1607 return;
1608
1609 case 'p':
1610 *ip->ap = 0;
1611 if (!strncmp(ip->argbuf, "61\"", 3))
1612 ip->emul_level = EMUL_VT100;
1613 else if (!strncmp(ip->argbuf, "63;1\"", 5)
1614 || !strncmp(ip->argbuf, "62;1\"", 5))
1615 ip->emul_level = EMUL_VT300_7;
1616 else
1617 ip->emul_level = EMUL_VT300_8;
1618 ip->escape = 0;
1619 return;
1620
1621
1622 case '?':
1623 *ip->ap = 0;
1624 ip->escape = '?';
1625 ip->ap = ip->argbuf;
1626 return;
1627
1628
1629 case 'c':
1630 /* device attributes */
1631 *ip->ap = 0;
1632 if (ip->argbuf[0] == '>') {
1633 ite_sendstr (ip, "\033[>24;0;0;0c");
1634 } else
1635 switch (ite_zargnum(ip)) {
1636 case 0:
1637 /* primary DA request, send primary DA response */
1638 if (ip->emul_level == EMUL_VT100)
1639 ite_sendstr (ip, "\033[?1;1c");
1640 else
1641 ite_sendstr (ip, "\033[63;0c");
1642 break;
1643 }
1644 ip->escape = 0;
1645 return;
1646
1647 case 'n':
1648 switch (ite_zargnum(ip)) {
1649 case 5:
1650 ite_sendstr (ip, "\033[0n"); /* no malfunction */
1651 break;
1652 case 6:
1653 /* cursor position report */
1654 sprintf (ip->argbuf, "\033[%d;%dR",
1655 ip->cury + 1, ip->curx + 1);
1656 ite_sendstr (ip, ip->argbuf);
1657 break;
1658 }
1659 ip->escape = 0;
1660 return;
1661
1662
1663 case 'x':
1664 switch (ite_zargnum(ip)) {
1665 case 0:
1666 /* Fake some terminal parameters. */
1667 ite_sendstr (ip, "\033[2;1;1;112;112;1;0x");
1668 break;
1669 case 1:
1670 ite_sendstr (ip, "\033[3;1;1;112;112;1;0x");
1671 break;
1672 }
1673 ip->escape = 0;
1674 return;
1675
1676
1677 case 'g':
1678 /* clear tabs */
1679 switch (ite_zargnum(ip)) {
1680 case 0:
1681 if (ip->curx < ip->cols)
1682 ip->tabs[ip->curx] = 0;
1683 break;
1684 case 3:
1685 for (n = 0; n < ip->cols; n++)
1686 ip->tabs[n] = 0;
1687 break;
1688
1689 default:
1690 /* ignore */
1691 break;
1692 }
1693 ip->escape = 0;
1694 return;
1695
1696
1697 case 'h': /* set mode */
1698 case 'l': /* reset mode */
1699 n = ite_zargnum (ip);
1700 switch (n) {
1701 case 4:
1702 ip->imode = (c == 'h'); /* insert/replace mode */
1703 break;
1704 case 20:
1705 ip->linefeed_newline = (c == 'h');
1706 break;
1707 }
1708 ip->escape = 0;
1709 return;
1710
1711
1712 case 'M':
1713 /* delete line */
1714 ite_dnline (ip, ite_argnum (ip));
1715 ip->escape = 0;
1716 return;
1717
1718
1719 case 'L':
1720 /* insert line */
1721 ite_inline (ip, ite_argnum (ip));
1722 ip->escape = 0;
1723 return;
1724
1725
1726 case 'P':
1727 /* delete char */
1728 ite_dnchar (ip, ite_argnum (ip));
1729 ip->escape = 0;
1730 return;
1731
1732
1733 case '@':
1734 /* insert char(s) */
1735 ite_inchar (ip, ite_argnum (ip));
1736 ip->escape = 0;
1737 return;
1738
1739 case '!':
1740 /* soft terminal reset */
1741 ip->escape = 0; /* XXX */
1742 return;
1743
1744 case 'G':
1745 /* this one was *not* in my vt320 manual but in
1746 a vt320 termcap entry.. who is right?
1747 It's supposed to set the horizontal cursor position. */
1748 *ip->ap = 0;
1749 x = atoi (ip->argbuf);
1750 if (x) x--;
1751 ip->curx = min(x, ip->cols - 1);
1752 ip->escape = 0;
1753 SUBR_CURSOR(ip, MOVE_CURSOR);
1754 clr_attr (ip, ATTR_INV);
1755 return;
1756
1757
1758 case 'd':
1759 /* same thing here, this one's for setting the absolute
1760 vertical cursor position. Not documented... */
1761 *ip->ap = 0;
1762 y = atoi (ip->argbuf);
1763 if (y) y--;
1764 if (ip->inside_margins)
1765 y += ip->top_margin;
1766 ip->cury = min(y, ip->rows - 1);
1767 ip->escape = 0;
1768 snap_cury(ip);
1769 SUBR_CURSOR(ip, MOVE_CURSOR);
1770 clr_attr (ip, ATTR_INV);
1771 return;
1772
1773
1774 case 'H':
1775 case 'f':
1776 *ip->ap = 0;
1777 y = atoi (ip->argbuf);
1778 x = 0;
1779 cp = index (ip->argbuf, ';');
1780 if (cp)
1781 x = atoi (cp + 1);
1782 if (x) x--;
1783 if (y) y--;
1784 if (ip->inside_margins)
1785 y += ip->top_margin;
1786 ip->cury = min(y, ip->rows - 1);
1787 ip->curx = min(x, ip->cols - 1);
1788 ip->escape = 0;
1789 snap_cury(ip);
1790 SUBR_CURSOR(ip, MOVE_CURSOR);
1791 /*clr_attr (ip, ATTR_INV);*/
1792 return;
1793
1794 case 'A':
1795 /* cursor up */
1796 n = ite_argnum (ip);
1797 n = ip->cury - (n ? n : 1);
1798 if (n < 0) n = 0;
1799 if (ip->inside_margins)
1800 n = max(ip->top_margin, n);
1801 else if (n == ip->top_margin - 1)
1802 /* allow scrolling outside region, but don't scroll out
1803 of active region without explicit CUP */
1804 n = ip->top_margin;
1805 ip->cury = n;
1806 ip->escape = 0;
1807 SUBR_CURSOR(ip, MOVE_CURSOR);
1808 clr_attr (ip, ATTR_INV);
1809 return;
1810
1811 case 'B':
1812 /* cursor down */
1813 n = ite_argnum (ip);
1814 n = ip->cury + (n ? n : 1);
1815 n = min(ip->rows - 1, n);
1816 #if 0
1817 if (ip->inside_margins)
1818 #endif
1819 n = min(ip->bottom_margin, n);
1820 #if 0
1821 else if (n == ip->bottom_margin + 1)
1822 /* allow scrolling outside region, but don't scroll out
1823 of active region without explicit CUP */
1824 n = ip->bottom_margin;
1825 #endif
1826 ip->cury = n;
1827 ip->escape = 0;
1828 SUBR_CURSOR(ip, MOVE_CURSOR);
1829 clr_attr (ip, ATTR_INV);
1830 return;
1831
1832 case 'C':
1833 /* cursor forward */
1834 n = ite_argnum (ip);
1835 n = n ? n : 1;
1836 ip->curx = min(ip->curx + n, ip->cols - 1);
1837 ip->escape = 0;
1838 SUBR_CURSOR(ip, MOVE_CURSOR);
1839 clr_attr (ip, ATTR_INV);
1840 return;
1841
1842 case 'D':
1843 /* cursor backward */
1844 n = ite_argnum (ip);
1845 n = n ? n : 1;
1846 n = ip->curx - n;
1847 ip->curx = n >= 0 ? n : 0;
1848 ip->escape = 0;
1849 SUBR_CURSOR(ip, MOVE_CURSOR);
1850 clr_attr (ip, ATTR_INV);
1851 return;
1852
1853
1854 case 'J':
1855 /* erase screen */
1856 *ip->ap = 0;
1857 n = ite_zargnum (ip);
1858 if (n == 0)
1859 ite_clrtoeos(ip);
1860 else if (n == 1)
1861 ite_clrtobos(ip);
1862 else if (n == 2)
1863 ite_clrscreen(ip);
1864 ip->escape = 0;
1865 return;
1866
1867
1868 case 'K':
1869 /* erase line */
1870 n = ite_zargnum (ip);
1871 if (n == 0)
1872 ite_clrtoeol(ip);
1873 else if (n == 1)
1874 ite_clrtobol(ip);
1875 else if (n == 2)
1876 ite_clrline(ip);
1877 ip->escape = 0;
1878 return;
1879
1880 case 'S':
1881 /* scroll up */
1882 n = ite_zargnum (ip);
1883 if (n <= 0)
1884 n = 1;
1885 else if (n > ip->rows-1)
1886 n = ip->rows-1;
1887 SUBR_SCROLL(ip, ip->rows-1, 0, n, SCROLL_UP);
1888 ip->escape = 0;
1889 return;
1890
1891 case 'T':
1892 /* scroll down */
1893 n = ite_zargnum (ip);
1894 if (n <= 0)
1895 n = 1;
1896 else if (n > ip->rows-1)
1897 n = ip->rows-1;
1898 SUBR_SCROLL(ip, 0, 0, n, SCROLL_DOWN);
1899 ip->escape = 0;
1900 return;
1901
1902 case 'X':
1903 /* erase character */
1904 n = ite_argnum(ip) - 1;
1905 n = min(n, ip->cols - 1 - ip->curx);
1906 for (; n >= 0; n--) {
1907 attrclr(ip, ip->cury, ip->curx + n, 1, 1);
1908 SUBR_PUTC(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
1909 }
1910 ip->escape = 0;
1911 return;
1912
1913
1914 case '}': case '`':
1915 /* status line control */
1916 ip->escape = 0;
1917 return;
1918
1919 case 'r':
1920 /* set scrolling region */
1921 ip->escape = 0;
1922 *ip->ap = 0;
1923 x = atoi (ip->argbuf);
1924 x = x ? x : 1;
1925 y = ip->rows;
1926 cp = index (ip->argbuf, ';');
1927 if (cp) {
1928 y = atoi (cp + 1);
1929 y = y ? y : ip->rows;
1930 }
1931 if (y <= x)
1932 return;
1933 x--;
1934 y--;
1935 ip->top_margin = min(x, ip->rows - 2);
1936 ip->bottom_margin = min(y, ip->rows - 1);
1937 if (ip->inside_margins) {
1938 ip->cury = ip->top_margin;
1939 } else
1940 ip->cury = 0;
1941 ip->curx = 0;
1942 return;
1943
1944
1945 case 'm':
1946 /* big attribute setter/resetter */
1947 {
1948 char *cp;
1949 *ip->ap = 0;
1950 /* kludge to make CSIm work (== CSI0m) */
1951 if (ip->ap == ip->argbuf)
1952 ip->ap++;
1953 for (cp = ip->argbuf; cp < ip->ap; ) {
1954 switch (*cp) {
1955 case 0:
1956 case '0':
1957 clr_attr (ip, ATTR_ALL);
1958 ip->fgcolor = 7;
1959 ip->bgcolor = 0;
1960 cp++;
1961 break;
1962
1963 case '1':
1964 set_attr (ip, ATTR_BOLD);
1965 cp++;
1966 break;
1967
1968 case '2':
1969 switch (cp[1]) {
1970 case '2':
1971 clr_attr (ip, ATTR_BOLD);
1972 cp += 2;
1973 break;
1974
1975 case '4':
1976 clr_attr (ip, ATTR_UL);
1977 cp += 2;
1978 break;
1979
1980 case '5':
1981 clr_attr (ip, ATTR_BLINK);
1982 cp += 2;
1983 break;
1984
1985 case '7':
1986 clr_attr (ip, ATTR_INV);
1987 cp += 2;
1988 break;
1989
1990 default:
1991 cp++;
1992 break;
1993 }
1994 break;
1995
1996 case '3':
1997 switch (cp[1]) {
1998 case '0': case '1': case '2': case '3':
1999 case '4': case '5': case '6': case '7':
2000 /* foreground colors */
2001 ip->fgcolor = cp[1] - '0';
2002 cp += 2;
2003 break;
2004 default:
2005 cp++;
2006 break;
2007 }
2008 break;
2009
2010 case '4':
2011 switch (cp[1]) {
2012 case '0': case '1': case '2': case '3':
2013 case '4': case '5': case '6': case '7':
2014 /* background colors */
2015 ip->bgcolor = cp[1] - '0';
2016 cp += 2;
2017 break;
2018 default:
2019 set_attr (ip, ATTR_UL);
2020 cp++;
2021 break;
2022 }
2023 break;
2024
2025 case '5':
2026 set_attr (ip, ATTR_BLINK);
2027 cp++;
2028 break;
2029
2030 case '7':
2031 set_attr (ip, ATTR_INV);
2032 cp++;
2033 break;
2034
2035 default:
2036 cp++;
2037 break;
2038 }
2039 }
2040
2041 }
2042 ip->escape = 0;
2043 return;
2044
2045
2046 case 'u':
2047 /* DECRQTSR */
2048 ite_sendstr (ip, "\033P\033\\");
2049 ip->escape = 0;
2050 return;
2051
2052 default:
2053 ip->escape = 0;
2054 return;
2055 }
2056 break;
2057
2058
2059
2060 case '?': /* CSI ? */
2061 switch (c) {
2062 case '0': case '1': case '2': case '3': case '4':
2063 case '5': case '6': case '7': case '8': case '9':
2064 case ';': case '\"': case '$':
2065 /* Don't fill the last character; it's needed. */
2066 /* XXX yeah, where ?? */
2067 if (ip->ap < ip->argbuf + MAX_ARGSIZE - 1)
2068 *ip->ap++ = c;
2069 return;
2070
2071
2072 case 'n':
2073 /* Terminal Reports */
2074 *ip->ap = 0;
2075 if (ip->ap == &ip->argbuf[2]) {
2076 if (!strncmp(ip->argbuf, "15", 2))
2077 /* printer status: no printer */
2078 ite_sendstr (ip, "\033[13n");
2079
2080 else if (!strncmp(ip->argbuf, "25", 2))
2081 /* udk status */
2082 ite_sendstr (ip, "\033[20n");
2083
2084 else if (!strncmp(ip->argbuf, "26", 2))
2085 /* keyboard dialect: US */
2086 ite_sendstr (ip, "\033[27;1n");
2087 }
2088 ip->escape = 0;
2089 return;
2090
2091
2092 case 'h': /* set dec private modes */
2093 case 'l': /* reset dec private modes */
2094 n = ite_zargnum (ip);
2095 switch (n) {
2096 case 1:
2097 /* CKM - cursor key mode */
2098 ip->cursor_appmode = (c == 'h');
2099 break;
2100
2101 case 3:
2102 /* 132/80 columns (132 == 'h') */
2103 break;
2104
2105 case 4: /* smooth scroll */
2106 break;
2107
2108 case 5:
2109 /* light background (=='h') /dark background(=='l') */
2110 break;
2111
2112 case 6: /* origin mode */
2113 ip->inside_margins = (c == 'h');
2114 #if 0
2115 ip->curx = 0;
2116 ip->cury = ip->inside_margins ? ip->top_margin : 0;
2117 SUBR_CURSOR(ip, MOVE_CURSOR);
2118 #endif
2119 break;
2120
2121 case 7: /* auto wraparound */
2122 ip->auto_wrap = (c == 'h');
2123 break;
2124
2125 case 8: /* keyboard repeat */
2126 ip->key_repeat = (c == 'h');
2127 break;
2128
2129 case 20: /* newline mode */
2130 ip->linefeed_newline = (c == 'h');
2131 break;
2132
2133 case 25: /* cursor on/off */
2134 SUBR_CURSOR(ip, (c == 'h') ? DRAW_CURSOR : ERASE_CURSOR);
2135 break;
2136 }
2137 ip->escape = 0;
2138 return;
2139
2140 case 'K':
2141 /* selective erase in line */
2142 case 'J':
2143 /* selective erase in display */
2144
2145 default:
2146 ip->escape = 0;
2147 return;
2148 }
2149 break;
2150
2151
2152 default:
2153 ip->escape = 0;
2154 return;
2155 }
2156 }
2157
2158 switch (c) {
2159 case 0x00: /* NUL */
2160 case 0x01: /* SOH */
2161 case 0x02: /* STX */
2162 case 0x03: /* ETX */
2163 case 0x04: /* EOT */
2164 case 0x05: /* ENQ */
2165 case 0x06: /* ACK */
2166 break;
2167
2168 case BEL:
2169 #if NBELL > 0
2170 if (kbd_ite && ite_tty[kbd_ite->device.dv_unit])
2171 opm_bell();
2172 #endif
2173 break;
2174
2175 case BS:
2176 if (--ip->curx < 0)
2177 ip->curx = 0;
2178 else
2179 SUBR_CURSOR(ip, MOVE_CURSOR);
2180 break;
2181
2182 case HT:
2183 for (n = ip->curx + 1; n < ip->cols; n++) {
2184 if (ip->tabs[n]) {
2185 ip->curx = n;
2186 SUBR_CURSOR(ip, MOVE_CURSOR);
2187 break;
2188 }
2189 }
2190 break;
2191
2192 case VT: /* VT is treated like LF */
2193 case FF: /* so is FF */
2194 case LF:
2195 /* cr->crlf distinction is done here, on output,
2196 not on input! */
2197 if (ip->linefeed_newline)
2198 ite_crlf (ip);
2199 else
2200 ite_lf (ip);
2201 break;
2202
2203 case CR:
2204 ite_cr (ip);
2205 break;
2206
2207
2208 case SO:
2209 ip->GL = &ip->G1;
2210 break;
2211
2212 case SI:
2213 ip->GL = &ip->G0;
2214 break;
2215
2216 case 0x10: /* DLE */
2217 case 0x11: /* DC1/XON */
2218 case 0x12: /* DC2 */
2219 case 0x13: /* DC3/XOFF */
2220 case 0x14: /* DC4 */
2221 case 0x15: /* NAK */
2222 case 0x16: /* SYN */
2223 case 0x17: /* ETB */
2224 break;
2225
2226 case CAN:
2227 ip->escape = 0; /* cancel any escape sequence in progress */
2228 break;
2229
2230 case 0x19: /* EM */
2231 break;
2232
2233 case SUB:
2234 ip->escape = 0; /* dito, but see below */
2235 /* should also display a reverse question mark!! */
2236 break;
2237
2238 case ESC:
2239 ip->escape = ESC;
2240 break;
2241
2242 case 0x1c: /* FS */
2243 case 0x1d: /* GS */
2244 case 0x1e: /* RS */
2245 case 0x1f: /* US */
2246 break;
2247
2248 /* now it gets weird.. 8bit control sequences.. */
2249 case IND: /* index: move cursor down, scroll */
2250 ite_index (ip);
2251 break;
2252
2253 case NEL: /* next line. next line, first pos. */
2254 ite_crlf (ip);
2255 break;
2256
2257 case HTS: /* set horizontal tab */
2258 if (ip->curx < ip->cols)
2259 ip->tabs[ip->curx] = 1;
2260 break;
2261
2262 case RI: /* reverse index */
2263 ite_rlf (ip);
2264 break;
2265
2266 case SS2: /* go into G2 for one character */
2267 ip->save_GL = ip->GR; /* GL XXX EUC */
2268 ip->GR = &ip->G2; /* GL XXX */
2269 break;
2270
2271 case SS3: /* go into G3 for one character */
2272 ip->save_GL = ip->GR; /* GL XXX EUC */
2273 ip->GR = &ip->G3; /* GL XXX */
2274 break;
2275
2276 case DCS: /* device control string introducer */
2277 ip->escape = DCS;
2278 ip->ap = ip->argbuf;
2279 break;
2280
2281 case CSI: /* control sequence introducer */
2282 ip->escape = CSI;
2283 ip->ap = ip->argbuf;
2284 break;
2285
2286 case ST: /* string terminator */
2287 /* ignore, if not used as terminator */
2288 break;
2289
2290 case OSC: /* introduces OS command. Ignore everything upto ST */
2291 ip->escape = OSC;
2292 break;
2293
2294 case PM: /* privacy message, ignore everything upto ST */
2295 ip->escape = PM;
2296 break;
2297
2298 case APC: /* application program command, ignore everything upto ST */
2299 ip->escape = APC;
2300 break;
2301
2302 case DEL:
2303 break;
2304
2305 default:
2306 if (!ip->save_char && (*((c & 0x80) ? ip->GR : ip->GL) & CSET_MULTI)) {
2307 ip->save_char = c;
2308 break;
2309 }
2310 if (ip->imode)
2311 ite_inchar(ip, ip->save_char ? 2 : 1);
2312 iteprecheckwrap(ip);
2313 #ifdef DO_WEIRD_ATTRIBUTES
2314 if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
2315 attrset(ip, ATTR_INV);
2316 SUBR_PUTC(ip, c, ip->cury, ip->curx, ATTR_INV);
2317 }
2318 else
2319 SUBR_PUTC(ip, c, ip->cury, ip->curx, ATTR_NOR);
2320 #else
2321 SUBR_PUTC(ip, c, ip->cury, ip->curx, ip->attribute);
2322 #endif
2323 /* SUBR_CURSOR(ip, DRAW_CURSOR);*/
2324 itecheckwrap(ip);
2325 if (ip->save_char) {
2326 itecheckwrap(ip);
2327 ip->save_char = 0;
2328 }
2329 if (ip->save_GL) {
2330 /*
2331 * reset single shift
2332 */
2333 ip->GR = ip->save_GL;
2334 ip->save_GL = 0;
2335 }
2336 break;
2337 }
2338 }
2339
2340 static void
2341 iteprecheckwrap(ip)
2342 struct ite_softc *ip;
2343 {
2344 if (ip->auto_wrap && ip->curx + (ip->save_char ? 1 : 0) == ip->cols) {
2345 ip->curx = 0;
2346 clr_attr(ip, ATTR_INV);
2347 if (++ip->cury >= ip->bottom_margin + 1) {
2348 ip->cury = ip->bottom_margin;
2349 /*SUBR_CURSOR(ip, MOVE_CURSOR);*/
2350 SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
2351 ite_clrtoeol(ip);
2352 } /*else
2353 SUBR_CURSOR(ip, MOVE_CURSOR);*/
2354 }
2355 }
2356
2357 static void
2358 itecheckwrap(ip)
2359 struct ite_softc *ip;
2360 {
2361 #if 0
2362 if (++ip->curx == ip->cols) {
2363 if (ip->auto_wrap) {
2364 ip->curx = 0;
2365 clr_attr(ip, ATTR_INV);
2366 if (++ip->cury >= ip->bottom_margin + 1) {
2367 ip->cury = ip->bottom_margin;
2368 SUBR_CURSOR(ip, MOVE_CURSOR);
2369 SUBR_SCROLL(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
2370 ite_clrtoeol(ip);
2371 return;
2372 }
2373 } else
2374 /* stay there if no autowrap.. */
2375 ip->curx--;
2376 }
2377 #else
2378 if (ip->curx < ip->cols) {
2379 ip->curx++;
2380 /*SUBR_CURSOR(ip, MOVE_CURSOR);*/
2381 }
2382 #endif
2383 }
2384
2385 #endif
2386
2387 #if NITE > 0 && NKBD > 0
2388
2389 /*
2390 * Console functions
2391 */
2392 #include <dev/cons.h>
2393 extern void kbdenable __P((int));
2394 extern int kbdcngetc __P((void));
2395
2396 /*
2397 * Return a priority in consdev->cn_pri field highest wins. This function
2398 * is called before any devices have been probed.
2399 */
2400 void
2401 itecnprobe(cd)
2402 struct consdev *cd;
2403 {
2404 int maj;
2405
2406 /*
2407 * bring graphics layer up.
2408 */
2409 config_console();
2410
2411 /* locate the major number */
2412 for (maj = 0; maj < nchrdev; maj++)
2413 if (cdevsw[maj].d_open == iteopen)
2414 break;
2415
2416 /*
2417 * return priority of the best ite (already picked from attach)
2418 * or CN_DEAD.
2419 */
2420 if (con_itesoftc.grf == NULL)
2421 cd->cn_pri = CN_DEAD;
2422 else {
2423 con_itesoftc.flags = (ITE_ALIVE|ITE_CONSOLE);
2424 /*
2425 * hardcode the minor number.
2426 * currently we support only one ITE, it is enough for now.
2427 */
2428 con_itesoftc.isw = &itesw[0];
2429 cd->cn_pri = CN_INTERNAL;
2430 cd->cn_dev = makedev(maj, 0);
2431 }
2432
2433 }
2434
2435 void
2436 itecninit(cd)
2437 struct consdev *cd;
2438 {
2439 struct ite_softc *ip;
2440
2441 ip = getitesp(cd->cn_dev);
2442 iteinit(cd->cn_dev); /* init console unit */
2443 ip->flags |= ITE_ACTIVE | ITE_ISCONS;
2444 kbdenable(0);
2445 mfp_send_usart(0x49);
2446 }
2447
2448 /*
2449 * itecnfinish() is called in ite_init() when the device is
2450 * being probed in the normal fasion, thus we can finish setting
2451 * up this ite now that the system is more functional.
2452 */
2453 void
2454 itecnfinish(ip)
2455 struct ite_softc *ip;
2456 {
2457 static int done;
2458
2459 if (done)
2460 return;
2461 done = 1;
2462 }
2463
2464 /*ARGSUSED*/
2465 int
2466 itecngetc(dev)
2467 dev_t dev;
2468 {
2469 register int c;
2470
2471 do {
2472 c = kbdcngetc();
2473 c = ite_cnfilter(c);
2474 } while (c == -1);
2475 return (c);
2476 }
2477
2478 void
2479 itecnputc(dev, c)
2480 dev_t dev;
2481 int c;
2482 {
2483 static int paniced = 0;
2484 struct ite_softc *ip = getitesp(dev);
2485 char ch = c;
2486 #ifdef ITE_KERNEL_ATTR
2487 short save_attribute;
2488 #endif
2489
2490 if (panicstr && !paniced &&
2491 (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
2492 (void) iteon(dev, 3);
2493 paniced = 1;
2494 }
2495 #ifdef ITE_KERNEL_ATTR
2496 save_attribute = ip->attribute;
2497 ip->attribute = ITE_KERNEL_ATTR;
2498 #endif
2499 ite_putstr(&ch, 1, dev);
2500 #ifdef ITE_KERNEL_ATTR
2501 ip->attribute = save_attribute;
2502 #endif
2503 }
2504 #endif
2505