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