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