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