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