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