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