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