ite.c revision 1.3 1 /*
2 * Copyright (c) 1988 University of Utah.
3 * Copyright (c) 1990 The Regents of the University of California.
4 * All rights reserved.
5 *
6 * This code is derived from software contributed to Berkeley by
7 * the Systems Programming Group of the University of Utah Computer
8 * Science Department.
9 *
10 * Redistribution and use in source and binary forms, with or without
11 * modification, are permitted provided that the following conditions
12 * are met:
13 * 1. Redistributions of source code must retain the above copyright
14 * notice, this list of conditions and the following disclaimer.
15 * 2. Redistributions in binary form must reproduce the above copyright
16 * notice, this list of conditions and the following disclaimer in the
17 * documentation and/or other materials provided with the distribution.
18 * 3. All advertising materials mentioning features or use of this software
19 * must display the following acknowledgement:
20 * This product includes software developed by the University of
21 * California, Berkeley and its contributors.
22 * 4. Neither the name of the University nor the names of its contributors
23 * may be used to endorse or promote products derived from this software
24 * without specific prior written permission.
25 *
26 * THIS SOFTWARE IS PROVIDED BY THE REGENTS AND CONTRIBUTORS ``AS IS'' AND
27 * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
28 * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
29 * ARE DISCLAIMED. IN NO EVENT SHALL THE REGENTS OR CONTRIBUTORS BE LIABLE
30 * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
31 * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
32 * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
33 * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
34 * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
35 * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
36 * SUCH DAMAGE.
37 *
38 * from: Utah Hdr: ite.c 1.1 90/07/09
39 * from: @(#)ite.c 7.6 (Berkeley) 5/16/91
40 <<<<<<< ite.c
41 * $Id: ite.c,v 1.3 1993/09/02 18:08:02 mw Exp $
42 ||||||| 1.1.1.2
43 * $Id: ite.c,v 1.3 1993/09/02 18:08:02 mw Exp $
44 =======
45 * $Id: ite.c,v 1.3 1993/09/02 18:08:02 mw Exp $
46 *
47 * Original author: unknown
48 * Amiga author:: Markus Wild
49 * Other contributors: Bryan Ford (improved vt100 compability)
50 >>>>>>> /tmp/T4009622
51 */
52
53 /*
54 * Bit-mapped display terminal emulator machine independent code.
55 * This is a very rudimentary. Much more can be abstracted out of
56 * the hardware dependent routines.
57 */
58 #include "ite.h"
59 #if NITE > 0
60
61 #include "grf.h"
62
63 #undef NITE
64 #define NITE NGRF
65
66 #include "param.h"
67 #include "conf.h"
68 #include "proc.h"
69 #include "ioctl.h"
70 #include "tty.h"
71 #include "systm.h"
72 #include "malloc.h"
73
74 #include "itevar.h"
75 #include "iteioctl.h"
76 #include "kbdmap.h"
77
78 #include "machine/cpu.h"
79 #include "../amiga/cons.h"
80
81 #ifdef __STDC__
82 /* automatically generated, as you might guess:-) */
83
84 struct consdev;
85 struct itesw;
86
87 extern int iteon (dev_t dev, int flag);
88 extern int iteinit (dev_t dev);
89 extern int iteoff (dev_t dev, int flag);
90 extern int iteopen (dev_t dev, int mode, int devtype, struct proc *p);
91 extern int iteclose (dev_t dev, int flag, int mode, struct proc *p);
92 extern int iteread (dev_t dev, struct uio *uio, int flag);
93 extern int itewrite (dev_t dev, struct uio *uio, int flag);
94 extern int iteioctl (dev_t dev, int cmd, caddr_t addr, int flag);
95 extern int itestart (register struct tty *tp);
96 extern int itefilter (register u_char c, enum caller caller);
97 extern void iteputchar (register int c, dev_t dev);
98 extern int iteprecheckwrap (register struct ite_softc *ip, register struct itesw *sp);
99 extern int itecheckwrap (register struct ite_softc *ip, register struct itesw *sp);
100 extern int itecnprobe (struct consdev *cp);
101 extern int itecninit (struct consdev *cp);
102 extern int itecngetc (dev_t dev);
103 extern int itecnputc (dev_t dev, int c);
104 static void repeat_handler (int a0, int a1);
105 static void inline ite_reset(struct ite_softc *ip);
106 static void ite_dnchar (struct ite_softc *ip, struct itesw *sp, int n);
107 static void ite_inchar (struct ite_softc *ip, struct itesw *sp, int n);
108 static void ite_clrtoeol (struct ite_softc *ip, struct itesw *sp);
109 static void ite_clrtobol (struct ite_softc *ip, struct itesw *sp);
110 static void ite_clrline (struct ite_softc *ip, struct itesw *sp);
111 static void ite_clrtoeos (struct ite_softc *ip, struct itesw *sp);
112 static void ite_clrtobos (struct ite_softc *ip, struct itesw *sp);
113 static void ite_clrscreen (struct ite_softc *ip, struct itesw *sp);
114 static void ite_dnline (struct ite_softc *ip, struct itesw *sp, int n);
115 static void ite_inline (struct ite_softc *ip, struct itesw *sp, int n);
116 static void ite_lf (struct ite_softc *ip, struct itesw *sp);
117 static void ite_crlf (struct ite_softc *ip, struct itesw *sp);
118 static void ite_cr (struct ite_softc *ip, struct itesw *sp);
119 static void ite_rlf (struct ite_softc *ip, struct itesw *sp);
120 static int atoi (const char *cp);
121 static char *index (const char *cp, char ch);
122 static int ite_argnum (struct ite_softc *ip);
123 static int ite_zargnum (struct ite_softc *ip);
124 static void ite_sendstr (struct ite_softc *ip, char *str);
125 static int strncmp (const char *a, const char *b, int l);
126 #endif
127
128
129 #define set_attr(ip, attr) ((ip)->attribute |= (attr))
130 #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr))
131
132 extern int nodev();
133
134 int customc_scroll(), customc_init(), customc_deinit();
135 int customc_clear(), customc_putc(), customc_cursor();
136
137 int tiga_scroll(), tiga_init(), tiga_deinit();
138 int tiga_clear(), tiga_putc(), tiga_cursor();
139
140 int retina_scroll(), retina_init(), retina_deinit();
141 int retina_clear(), retina_putc(), retina_cursor();
142
143 struct itesw itesw[] =
144 {
145 customc_init, customc_deinit, 0,
146 0, 0, 0,
147
148 tiga_init, tiga_deinit, tiga_clear,
149 tiga_putc, tiga_cursor, tiga_scroll,
150
151 retina_init, retina_deinit, retina_clear,
152 retina_putc, retina_cursor, retina_scroll,
153 };
154
155 /*
156 * # of chars are output in a single itestart() call.
157 * If this is too big, user processes will be blocked out for
158 * long periods of time while we are emptying the queue in itestart().
159 * If it is too small, console output will be very ragged.
160 */
161 int iteburst = 64;
162
163 int nite = NITE;
164
165 struct tty *kbd_tty = NULL;
166 struct ite_softc *kbd_ip = NULL;
167
168 struct tty ite_cons1, ite_cons2;
169 #if 0
170 struct tty *ite_tty[NITE] = { &ite_cons1, &ite_cons2 };
171 #else
172 struct tty *ite_tty[NITE];
173 /* ugh.. */
174 static int delayed_con_tty = -1; /* if >= 0 set cn_tp later to that tty.. */
175 #endif
176 struct ite_softc ite_softc[NITE];
177
178 int itestart();
179 extern int ttrstrt();
180 extern struct tty *constty;
181
182 /* These are (later..) settable via an ioctl */
183 int start_repeat_timo = 20; /* /100: initial timeout till pressed key repeats */
184 int next_repeat_timo = 3; /* /100: timeout when repeating for next char */
185
186 #ifdef DO_WEIRD_ATTRIBUTES
187 /*
188 * Primary attribute buffer to be used by the first bitmapped console
189 * found. Secondary displays alloc the attribute buffer as needed.
190 * Size is based on a 68x128 display, which is currently our largest.
191 */
192 u_char console_attributes[0x2200];
193 #endif
194 u_char console_tabs[256 * NITE];
195
196 /*
197 * Perform functions necessary to setup device as a terminal emulator.
198 */
199 iteon(dev, flag)
200 dev_t dev;
201 {
202 int unit = UNIT(dev);
203 struct tty *tp = ite_tty[unit];
204 struct ite_softc *ip = &ite_softc[unit];
205
206 if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0)
207 return(ENXIO);
208 /* force ite active, overriding graphics mode */
209 if (flag & 1) {
210 ip->flags |= ITE_ACTIVE;
211 ip->flags &= ~(ITE_INGRF|ITE_INITED);
212 }
213 /* leave graphics mode */
214 if (flag & 2) {
215 ip->flags &= ~ITE_INGRF;
216 if ((ip->flags & ITE_ACTIVE) == 0)
217 return(0);
218 }
219 ip->flags |= ITE_ACTIVE;
220 if (ip->flags & ITE_INGRF)
221 return(0);
222 if (tp && (kbd_tty == NULL || kbd_tty == tp)) {
223 kbd_tty = tp;
224 kbd_ip = ip;
225 kbdenable();
226 }
227 iteinit(dev);
228 return(0);
229 }
230
231 /* used by the grf layer to reinitialize ite after changing fb parameters */
232 itereinit(dev)
233 dev_t dev;
234 {
235 int unit = UNIT(dev);
236 struct ite_softc *ip = &ite_softc[unit];
237
238 ip->flags &= ~ITE_INITED;
239 iteinit (dev);
240 }
241
242 iteinit(dev)
243 dev_t dev;
244 {
245 int unit = UNIT(dev);
246 struct ite_softc *ip = &ite_softc[unit];
247
248 if (ip->flags & ITE_INITED)
249 return;
250
251 bcopy (&ascii_kbdmap, &kbdmap, sizeof (struct kbdmap));
252
253 ip->cursorx = 0;
254 ip->cursory = 0;
255 (*itesw[ip->type].ite_init)(ip);
256 <<<<<<< ite.c
257 (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
258 ||||||| 1.1.1.2
259 (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
260
261 /* ip->rows initialized by ite_init above */
262 ip->top_margin = 0; ip->bottom_margin = ip->rows - 1;
263 =======
264 >>>>>>> /tmp/T4009622
265
266 <<<<<<< ite.c
267 /* ip->rows initialized by ite_init above */
268 ip->top_margin = 0; ip->bottom_margin = ip->rows - 1;
269
270 ip->attribute = 0;
271 ||||||| 1.1.1.2
272 ip->attribute = 0;
273 =======
274 #ifdef DO_WEIRD_ATTRIBUTES
275 >>>>>>> /tmp/T4009622
276 if (ip->attrbuf == NULL)
277 ip->attrbuf = (u_char *)
278 malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK);
279 bzero(ip->attrbuf, (ip->rows * ip->cols));
280 #endif
281 if (! ip->tabs)
282 {
283 /* can't use malloc, as this buffer might be used before
284 the allocators are initialized (console!) */
285 ip->tabs = &console_tabs[unit * 256];
286 }
287
288 ite_reset (ip);
289
290 (*itesw[ip->type].ite_cursor)(ip, DRAW_CURSOR);
291 ip->flags |= ITE_INITED;
292 }
293
294 /*
295 * "Shut down" device as terminal emulator.
296 * Note that we do not deinit the console device unless forced.
297 * Deinit'ing the console every time leads to a very active
298 * screen when processing /etc/rc.
299 */
300 iteoff(dev, flag)
301 dev_t dev;
302 {
303 register struct ite_softc *ip = &ite_softc[UNIT(dev)];
304
305 if (flag & 2)
306 ip->flags |= ITE_INGRF;
307 if ((ip->flags & ITE_ACTIVE) == 0)
308 return;
309 if ((flag & 1) ||
310 (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED)
311 (*itesw[ip->type].ite_deinit)(ip);
312 if ((flag & 2) == 0)
313 ip->flags &= ~ITE_ACTIVE;
314 }
315
316 /* ARGSUSED */
317 #ifdef __STDC__
318 iteopen(dev_t dev, int mode, int devtype, struct proc *p)
319 #else
320 iteopen(dev, mode, devtype, p)
321 dev_t dev;
322 int mode, devtype;
323 struct proc *p;
324 #endif
325 {
326 int unit = UNIT(dev);
327 register struct tty *tp;
328 register struct ite_softc *ip = &ite_softc[unit];
329 register int error;
330 int first = 0;
331
332 if (unit >= NITE)
333 return ENXIO;
334
335 if(!ite_tty[unit]) {
336 #if 0
337 MALLOC(tp, struct tty *, sizeof(struct tty), M_TTYS, M_WAITOK);
338 bzero(tp, sizeof(struct tty));
339 ite_tty[unit] = tp;
340 #else
341 tp = ite_tty[unit] = ttymalloc();
342 /* HA! caught it finally... */
343 if (unit == delayed_con_tty)
344 {
345 extern struct consdev *cn_tab;
346 extern struct tty *cn_tty;
347
348 kbd_tty = tp;
349 kbd_ip = ip;
350 kbdenable ();
351 cn_tty = cn_tab->cn_tp = tp;
352 delayed_con_tty = -1;
353 }
354 #endif
355 } else
356 tp = ite_tty[unit];
357
358 if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE)
359 && p->p_ucred->cr_uid != 0)
360 return (EBUSY);
361 if ((ip->flags & ITE_ACTIVE) == 0) {
362 error = iteon(dev, 0);
363 if (error)
364 return (error);
365 first = 1;
366 }
367 tp->t_oproc = itestart;
368 tp->t_param = NULL;
369 tp->t_dev = dev;
370 if ((tp->t_state&TS_ISOPEN) == 0) {
371 ttychars(tp);
372 tp->t_iflag = TTYDEF_IFLAG;
373 tp->t_oflag = TTYDEF_OFLAG;
374 tp->t_cflag = CS8|CREAD;
375 tp->t_lflag = TTYDEF_LFLAG;
376 tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED;
377 /* don't set TS_ISOPEN here, or the tty queues won't
378 be initialized in ttyopen()! */
379 tp->t_state = TS_CARR_ON;
380 ttsetwater(tp);
381 }
382 error = (*linesw[tp->t_line].l_open)(dev, tp);
383 if (error == 0) {
384 tp->t_winsize.ws_row = ip->rows;
385 tp->t_winsize.ws_col = ip->cols;
386 ip->open_cnt++;
387 } else if (first)
388 iteoff(dev, 0);
389 return (error);
390 }
391
392 /*ARGSUSED*/
393 iteclose(dev, flag, mode, p)
394 dev_t dev;
395 int flag, mode;
396 struct proc *p;
397 {
398 int unit = UNIT(dev);
399 register struct tty *tp = ite_tty[unit];
400 register struct ite_softc *ip = &ite_softc[unit];
401
402 #if 0
403 /* aliasing with /dev/console can lead to such weird problems... */
404 if (ip->open_cnt-- > 0)
405 return 0;
406 #endif
407
408 if (tp)
409 {
410 (*linesw[tp->t_line].l_close)(tp, flag);
411 ttyclose(tp);
412 }
413 iteoff(dev, 0);
414 #if 0
415 if (tp != &ite_cons)
416 {
417 #if 0
418 FREE(tp, M_TTYS);
419 #else
420 ttyfree (tp);
421 #endif
422 ite_tty[UNIT(dev)] = (struct tty *)NULL;
423 }
424 #endif
425 return(0);
426 }
427
428 iteread(dev, uio, flag)
429 dev_t dev;
430 struct uio *uio;
431 {
432 register struct tty *tp = ite_tty[UNIT(dev)];
433 int rc;
434
435 if (! tp)
436 return ENXIO;
437
438 rc = ((*linesw[tp->t_line].l_read)(tp, uio, flag));
439 return rc;
440 }
441
442 itewrite(dev, uio, flag)
443 dev_t dev;
444 struct uio *uio;
445 {
446 int unit = UNIT(dev);
447 register struct tty *tp = ite_tty[unit];
448
449 if (! tp)
450 return ENXIO;
451
452 if ((ite_softc[unit].flags & ITE_ISCONS) && constty &&
453 (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN))
454 tp = constty;
455 return ((*linesw[tp->t_line].l_write)(tp, uio, flag));
456 }
457
458 iteioctl(dev, cmd, addr, flag)
459 dev_t dev;
460 caddr_t addr;
461 {
462 register struct tty *tp = ite_tty[UNIT(dev)];
463 int error;
464
465 if (! tp)
466 return ENXIO;
467
468
469 error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag);
470 if (error >= 0)
471 return (error);
472 error = ttioctl(tp, cmd, addr, flag);
473 if (error >= 0)
474 return (error);
475
476 switch (cmd)
477 {
478 case ITELOADKMAP:
479 if (addr)
480 {
481 bcopy (addr, &kbdmap, sizeof (struct kbdmap));
482 return 0;
483 }
484 else
485 return EFAULT;
486
487 case ITEGETKMAP:
488 if (addr)
489 {
490 bcopy (&kbdmap, addr, sizeof (struct kbdmap));
491 return 0;
492 }
493 else
494 return EFAULT;
495 }
496
497
498 return (ENOTTY);
499 }
500
501 itestart(tp)
502 register struct tty *tp;
503 {
504 register int cc, s;
505 int unit = UNIT(tp->t_dev);
506 register struct ite_softc *ip = &ite_softc[unit];
507 int hiwat = 0;
508
509 s = spltty();
510 if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) {
511 splx(s);
512 return;
513 }
514 tp->t_state |= TS_BUSY;
515 cc = tp->t_outq.c_cc;
516 if (cc <= tp->t_lowat) {
517 if (tp->t_state & TS_ASLEEP) {
518 tp->t_state &= ~TS_ASLEEP;
519 wakeup((caddr_t) &tp->t_outq);
520 }
521 selwakeup(&tp->t_wsel);
522 }
523 /*
524 * Limit the amount of output we do in one burst
525 * to prevent hogging the CPU.
526 */
527 if (cc > iteburst) {
528 hiwat++;
529 cc = iteburst;
530 }
531 (*itesw[ip->type].ite_cursor)(ip, START_CURSOROPT);
532 while (--cc >= 0) {
533 register int c;
534
535 c = getc(&tp->t_outq);
536 /*
537 * iteputchar() may take a long time and we don't want to
538 * block all interrupts for long periods of time. Since
539 * there is no need to stay at high priority while outputing
540 * the character (since we don't have to worry about
541 * interrupts), we don't. We just need to make sure that
542 * we don't reenter iteputchar, which is guarenteed by the
543 * earlier setting of TS_BUSY.
544 */
545 splx(s);
546 iteputchar(c, tp->t_dev);
547 spltty();
548 }
549 (*itesw[ip->type].ite_cursor)(ip, END_CURSOROPT);
550 if (hiwat) {
551 tp->t_state |= TS_TIMEOUT;
552 timeout((timeout_t) ttrstrt, (caddr_t) tp, 1);
553 }
554 tp->t_state &= ~TS_BUSY;
555 splx(s);
556 }
557
558 /* these are used to implement repeating keys.. */
559 static u_char last_char = 0;
560 static u_char tout_pending = 0;
561
562 static void
563 repeat_handler (a0, a1)
564 int a0, a1;
565 {
566 tout_pending = 0;
567 /* leave it up to itefilter() to possibly install a new callout entry
568 to reinvoke repeat_handler() */
569 if (last_char)
570 {
571 /* don't call itefilter directly, we're at spl6 here, and have
572 blocked out way too much stuff. Besides, the keyboard wouldn't
573 even have a chance to tell us about key-up events if we
574 did.. */
575 add_sicallback (itefilter, last_char, ITEFILT_REPEATER);
576
577 /* itefilter (last_char, ITEFILT_REPEATER); */
578 }
579 }
580
581 static void inline
582 itesendch (int ch)
583 {
584 (*linesw[kbd_tty->t_line].l_rint)(ch, kbd_tty);
585 }
586
587
588 int
589 itefilter(c, caller)
590 register u_char c;
591 enum caller caller;
592 {
593 static u_char mod = 0;
594 static u_char last_dead = 0;
595 register unsigned char code, *str;
596 u_char up, mask, i;
597 struct key key;
598 int s;
599
600 if (caller != ITEFILT_CONSOLE && kbd_tty == NULL)
601 return;
602
603 /* have to make sure we're at spltty in here */
604 s = spltty ();
605
606 /* keyboard interrupts come at priority 2, while softint-
607 generated keyboard-repeat interrupts come at level 1.
608 So, to not allow a key-up event to get thru before
609 a repeat for the key-down, we remove any outstanding
610 callout requests.. */
611 rem_sicallback (itefilter);
612
613 up = c & 0x80 ? 1 : 0;
614 c &= 0x7f;
615 code = 0;
616
617 mask = 0;
618 if (c >= KBD_LEFT_SHIFT)
619 {
620 switch (c)
621 {
622 case KBD_LEFT_SHIFT:
623 mask = KBD_MOD_LSHIFT;
624 break;
625
626 case KBD_RIGHT_SHIFT:
627 mask = KBD_MOD_RSHIFT;
628 break;
629
630 case KBD_LEFT_ALT:
631 mask = KBD_MOD_LALT;
632 break;
633
634 case KBD_RIGHT_ALT:
635 mask = KBD_MOD_RALT;
636 break;
637
638 case KBD_LEFT_META:
639 mask = KBD_MOD_LMETA;
640 break;
641
642 case KBD_RIGHT_META:
643 mask = KBD_MOD_RMETA;
644 break;
645
646 case KBD_CAPS_LOCK:
647 /* capslock already behaves `right', don't need to keep track of the
648 state in here. */
649 mask = KBD_MOD_CAPS;
650 break;
651
652 case KBD_CTRL:
653 mask = KBD_MOD_CTRL;
654 break;
655 }
656
657 if (mask)
658 {
659 if (up)
660 mod &= ~mask;
661 else
662 mod |= mask;
663 }
664
665 /* these keys should not repeat, so it's the Right Thing dealing with
666 repeaters only after this block. */
667
668 /* return even if it wasn't a modifier key, the other codes up here
669 are either special (like reset warning), or not yet defined */
670 splx (s);
671 return -1;
672 }
673
674 /* no matter which character we're repeating, stop it if we get a key-up
675 event. I think this is the same thing amigados does. */
676 if (up)
677 {
678 if (tout_pending)
679 {
680 untimeout ((timeout_t) repeat_handler, 0);
681 tout_pending = 0;
682 last_char = 0;
683 }
684 splx (s);
685 return -1;
686 }
687
688
689 /* intercept Ctrl-LAlt-F1 here to switch back to original ascii-keymap.
690 this should probably be configurable.. */
691 if (mod == (KBD_MOD_LALT|KBD_MOD_SHIFT) && code == 0x50)
692 {
693 bcopy (&ascii_kbdmap, &kbdmap, sizeof (struct kbdmap));
694 splx (s);
695 return -1;
696 }
697
698
699 switch (mod & (KBD_MOD_ALT | KBD_MOD_SHIFT))
700 {
701 case 0:
702 key = kbdmap.keys[c];
703 if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS))
704 break;
705 /* FALL INTO */
706
707 case KBD_MOD_LSHIFT:
708 case KBD_MOD_RSHIFT:
709 case KBD_MOD_SHIFT:
710 key = kbdmap.shift_keys[c];
711 break;
712
713 case KBD_MOD_LALT:
714 case KBD_MOD_RALT:
715 case KBD_MOD_ALT:
716 key = kbdmap.alt_keys[c];
717 if (!(mod & KBD_MOD_CAPS) || !(key.mode & KBD_MODE_CAPS))
718 break;
719 /* FALL INTO */
720
721 case KBD_MOD_LALT|KBD_MOD_LSHIFT:
722 case KBD_MOD_LALT|KBD_MOD_RSHIFT:
723 case KBD_MOD_LALT|KBD_MOD_SHIFT:
724 case KBD_MOD_RALT|KBD_MOD_RSHIFT:
725 case KBD_MOD_RALT|KBD_MOD_SHIFT:
726 case KBD_MOD_ALT|KBD_MOD_RSHIFT:
727 key = kbdmap.alt_shift_keys[c];
728 break;
729 }
730
731 code = key.code;
732
733 /* arrange to repeat the keystroke. By doing this at the level of scan-codes,
734 we can have function keys, and keys that send strings, repeat too. This
735 also entitles an additional overhead, since we have to do the conversion
736 each time, but I guess that's ok. */
737 if (!tout_pending && caller == ITEFILT_TTY && kbd_ip->key_repeat)
738 {
739 tout_pending = 1;
740 last_char = c;
741 timeout ((timeout_t) repeat_handler, 0, start_repeat_timo);
742 }
743 else if (!tout_pending && caller == ITEFILT_REPEATER && kbd_ip->key_repeat)
744 {
745 tout_pending = 1;
746 last_char = c;
747 timeout ((timeout_t) repeat_handler, 0, next_repeat_timo);
748 }
749
750 /* handle dead keys */
751 if (key.mode & KBD_MODE_DEAD)
752 {
753 /* if entered twice, send accent itself */
754 if (last_dead == key.mode & KBD_MODE_ACCMASK)
755 last_dead = 0;
756 else
757 {
758 last_dead = key.mode & KBD_MODE_ACCMASK;
759 splx (s);
760 return -1;
761 }
762 }
763 if (last_dead)
764 {
765 /* can't apply dead flag to string-keys */
766 if (! (key.mode & KBD_MODE_STRING) && code >= '@' && code < 0x7f)
767 code = acctable[KBD_MODE_ACCENT (last_dead)][code - '@'];
768
769 last_dead = 0;
770 }
771
772 /* if not string, apply META and CTRL modifiers */
773 if (! (key.mode & KBD_MODE_STRING))
774 {
775 if (mod & KBD_MOD_CTRL)
776 code &= 0x1f;
777
778 if (mod & KBD_MOD_META)
779 code |= 0x80;
780 }
781 else
782 {
783 /* strings are only supported in normal tty mode, not in console mode */
784 if (caller != ITEFILT_CONSOLE)
785 {
786 str = kbdmap.strings + code;
787 /* using a length-byte instead of 0-termination allows to embed \0 into
788 strings, although this is not used in the default keymap */
789 for (i = *str++; i; i--)
790 itesendch(*str++);
791 }
792 splx (s);
793 return -1;
794 }
795
796 if (caller == ITEFILT_CONSOLE)
797 {
798 /* do the conversion here because raw console input doesn't go thru
799 tty conversions */
800 code = code == '\r' ? '\n' : code;
801 splx (s);
802 return code;
803 }
804 else
805 /* NOTE: *don't* do any cr->crlf conversion here, this is input
806 processing, the mentioned conversion should only be
807 done for output processing (for input, it is not
808 terminal-specific but depends on tty-settings!) */
809 (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty);
810
811 splx (s);
812 return -1;
813 }
814
815
816 /* helper functions, makes the code below more readable */
817 static void inline
818 ite_sendstr (ip, str)
819 struct ite_softc *ip;
820 char *str;
821 {
822 while (*str)
823 itesendch (*str++);
824 }
825
826 static void
827 alignment_display(struct ite_softc *ip, struct itesw *sp)
828 {
829 int i, j;
830
831 for (j = 0; j < ip->rows; j++)
832 for (i = 0; i < ip->cols; i++)
833 (*sp->ite_putc)(ip, 'E', j, i, ATTR_NOR);
834 attrclr(ip, 0, 0, ip->rows, ip->cols);
835 (*sp->ite_cursor)(ip, DRAW_CURSOR);
836 }
837
838 static void inline
839 snap_cury(struct ite_softc *ip, struct itesw *sp)
840 {
841 if (ip->inside_margins)
842 {
843 if (ip->cury < ip->top_margin)
844 ip->cury = ip->top_margin;
845 if (ip->cury > ip->bottom_margin)
846 ip->cury = ip->bottom_margin;
847 }
848 }
849
850 static void inline
851 ite_dnchar(ip, sp, n)
852 struct ite_softc *ip;
853 struct itesw *sp;
854 int n;
855 {
856 n = MIN(n, ip->cols - ip->curx);
857 if (n < ip->cols - ip->curx)
858 {
859 (*sp->ite_scroll)(ip, ip->cury, ip->curx + n, n, SCROLL_LEFT);
860 attrmov(ip, ip->cury, ip->curx + n, ip->cury, ip->curx,
861 1, ip->cols - ip->curx - n);
862 attrclr(ip, ip->cury, ip->cols - n, 1, n);
863 }
864 while (n-- > 0)
865 (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - n - 1, ATTR_NOR);
866 (*sp->ite_cursor)(ip, DRAW_CURSOR);
867 }
868
869 static void inline
870 ite_inchar(ip, sp, n)
871 struct ite_softc *ip;
872 struct itesw *sp;
873 int n;
874 {
875 n = MIN(n, ip->cols - ip->curx);
876 if (n < ip->cols - ip->curx)
877 {
878 (*sp->ite_scroll)(ip, ip->cury, ip->curx, n, SCROLL_RIGHT);
879 attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + n,
880 1, ip->cols - ip->curx - n);
881 attrclr(ip, ip->cury, ip->curx, 1, n);
882 }
883 while (n--)
884 (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
885 (*sp->ite_cursor)(ip, DRAW_CURSOR);
886 }
887
888 static void inline
889 ite_clrtoeol(ip, sp)
890 struct ite_softc *ip;
891 struct itesw *sp;
892 {
893 int y = ip->cury, x = ip->curx;
894 if (ip->cols - x > 0)
895 {
896 (*sp->ite_clear)(ip, y, x, 1, ip->cols - x);
897 attrclr(ip, y, x, 1, ip->cols - x);
898 (*sp->ite_cursor)(ip, DRAW_CURSOR);
899 }
900 }
901
902 static void inline
903 ite_clrtobol(ip, sp)
904 struct ite_softc *ip;
905 struct itesw *sp;
906 {
907 int y = ip->cury, x = MIN(ip->curx + 1, ip->cols);
908 (*sp->ite_clear)(ip, y, 0, 1, x);
909 attrclr(ip, y, 0, 1, x);
910 (*sp->ite_cursor)(ip, DRAW_CURSOR);
911 }
912
913 static void inline
914 ite_clrline(ip, sp)
915 struct ite_softc *ip;
916 struct itesw *sp;
917 {
918 int y = ip->cury;
919 (*sp->ite_clear)(ip, y, 0, 1, ip->cols);
920 attrclr(ip, y, 0, 1, ip->cols);
921 (*sp->ite_cursor)(ip, DRAW_CURSOR);
922 }
923
924
925
926 static void inline
927 ite_clrtoeos(ip, sp)
928 struct ite_softc *ip;
929 struct itesw *sp;
930 {
931 ite_clrtoeol(ip, sp);
932 if (ip->cury < ip->rows - 1)
933 {
934 (*sp->ite_clear)(ip, ip->cury + 1, 0, ip->rows - 1 - ip->cury, ip->cols);
935 attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols);
936 (*sp->ite_cursor)(ip, DRAW_CURSOR);
937 }
938 }
939
940 static void inline
941 ite_clrtobos(ip, sp)
942 struct ite_softc *ip;
943 struct itesw *sp;
944 {
945 ite_clrtobol(ip, sp);
946 if (ip->cury > 0)
947 {
948 (*sp->ite_clear)(ip, 0, 0, ip->cury, ip->cols);
949 attrclr(ip, 0, 0, ip->cury, ip->cols);
950 (*sp->ite_cursor)(ip, DRAW_CURSOR);
951 }
952 }
953
954 static void inline
955 ite_clrscreen(ip, sp)
956 struct ite_softc *ip;
957 struct itesw *sp;
958 {
959 (*sp->ite_clear)(ip, 0, 0, ip->rows, ip->cols);
960 attrclr(ip, 0, 0, ip->rows, ip->cols);
961 (*sp->ite_cursor)(ip, DRAW_CURSOR);
962 }
963
964
965
966 static void inline
967 ite_dnline(ip, sp, n)
968 struct ite_softc *ip;
969 struct itesw *sp;
970 int n;
971 {
972 n = MIN(n, ip->bottom_margin + 1 - ip->cury);
973 if (n <= ip->bottom_margin - ip->cury)
974 {
975 (*sp->ite_scroll)(ip, ip->cury + n, 0, n, SCROLL_UP);
976 attrmov(ip, ip->cury + n, 0, ip->cury, 0,
977 ip->bottom_margin + 1 - ip->cury - n, ip->cols);
978 }
979 (*sp->ite_clear)(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
980 attrclr(ip, ip->bottom_margin - n + 1, 0, n, ip->cols);
981 (*sp->ite_cursor)(ip, DRAW_CURSOR);
982 }
983
984 static void inline
985 ite_inline(ip, sp, n)
986 struct ite_softc *ip;
987 struct itesw *sp;
988 int n;
989 {
990 if ((ip->cury >= ip->top_margin) && (ip->cury <= ip->bottom_margin))
991 {
992 n = MIN(n, ip->bottom_margin + 1 - ip->cury);
993 if (n <= ip->bottom_margin - ip->cury)
994 {
995 (*sp->ite_scroll)(ip, ip->cury, 0, n, SCROLL_DOWN);
996 attrmov(ip, ip->cury, 0, ip->cury + n, 0,
997 ip->bottom_margin + 1 - ip->cury - n, ip->cols);
998 }
999 (*sp->ite_clear)(ip, ip->cury, 0, n, ip->cols);
1000 attrclr(ip, ip->cury, 0, n, ip->cols);
1001 (*sp->ite_cursor)(ip, DRAW_CURSOR);
1002 }
1003 }
1004
1005 static void inline
1006 ite_lf (ip, sp)
1007 struct ite_softc *ip;
1008 struct itesw *sp;
1009 {
1010 if (ip->inside_margins)
1011 {
1012 ++ip->cury;
1013 if ((ip->cury == ip->bottom_margin+1) || (ip->cury == ip->rows))
1014 {
1015 ip->cury--;
1016 (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
1017 ite_clrline(ip, sp);
1018 }
1019 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1020 }
1021 else
1022 {
1023 if (++ip->cury >= ip->rows)
1024 {
1025 ip->cury = ip->rows - 1;
1026 (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP);
1027 ite_clrline(ip, sp);
1028 }
1029 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1030 }
1031 clr_attr(ip, ATTR_INV);
1032 }
1033
1034 static void inline
1035 ite_crlf (ip, sp)
1036 struct ite_softc *ip;
1037 struct itesw *sp;
1038 {
1039 ip->curx = 0;
1040 ite_lf (ip, sp);
1041 }
1042
1043 static void inline
1044 ite_cr (ip, sp)
1045 struct ite_softc *ip;
1046 struct itesw *sp;
1047 {
1048 if (ip->curx)
1049 {
1050 ip->curx = 0;
1051 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1052 }
1053 }
1054
1055 static void inline
1056 ite_rlf (ip, sp)
1057 struct ite_softc *ip;
1058 struct itesw *sp;
1059 {
1060 int top = ip->inside_margins ? ip->top_margin : 0;
1061
1062 ip->cury--;
1063 if ((ip->cury < 0) || (ip->cury == top-1))
1064 {
1065 ip->cury++;
1066 (*sp->ite_scroll)(ip, top, 0, 1, SCROLL_DOWN);
1067 ite_clrline(ip, sp);
1068 }
1069 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1070 clr_attr(ip, ATTR_INV);
1071 }
1072
1073 static int inline
1074 atoi (cp)
1075 const char *cp;
1076 {
1077 int n;
1078
1079 for (n = 0; *cp && *cp >= '0' && *cp <= '9'; cp++)
1080 n = n * 10 + *cp - '0';
1081
1082 return n;
1083 }
1084
1085 static char *
1086 index (cp, ch)
1087 const char *cp;
1088 char ch;
1089 {
1090 while (*cp && *cp != ch) cp++;
1091 return *cp ? (char *) cp : 0;
1092 }
1093
1094
1095
1096 static int inline
1097 ite_argnum (ip)
1098 struct ite_softc *ip;
1099 {
1100 char ch;
1101 int n;
1102
1103 /* convert argument string into number */
1104 if (ip->ap == ip->argbuf)
1105 return 1;
1106 ch = *ip->ap;
1107 *ip->ap = 0;
1108 n = atoi (ip->argbuf);
1109 *ip->ap = ch;
1110
1111 return n;
1112 }
1113
1114 static int inline
1115 ite_zargnum (ip)
1116 struct ite_softc *ip;
1117 {
1118 char ch, *cp;
1119 int n;
1120
1121 /* convert argument string into number */
1122 if (ip->ap == ip->argbuf)
1123 return 0;
1124 ch = *ip->ap;
1125 *ip->ap = 0;
1126 n = atoi (ip->argbuf);
1127 *ip->ap = ch;
1128
1129 return n; /* don't "n ? n : 1" here, <CSI>0m != <CSI>1m ! */
1130 }
1131
1132 static int inline
1133 strncmp (a, b, l)
1134 const char *a, *b;
1135 int l;
1136 {
1137 for (;l--; a++, b++)
1138 if (*a != *b)
1139 return *a - *b;
1140 return 0;
1141 }
1142
1143 static void inline
1144 ite_reset(ip)
1145 struct ite_softc *ip;
1146 {
1147 int i;
1148
1149 ip->curx = 0;
1150 ip->cury = 0;
1151 ip->attribute = 0;
1152 ip->save_curx = 0;
1153 ip->save_cury = 0;
1154 ip->save_attribute = 0;
1155 ip->ap = ip->argbuf;
1156 ip->emul_level = EMUL_VT300_7;
1157 ip->eightbit_C1 = 0;
1158 ip->top_margin = 0; ip->bottom_margin = ip->rows - 1;
1159 ip->inside_margins = 1;
1160 ip->linefeed_newline = 0;
1161 ip->auto_wrap = 0;
1162 ip->cursor_appmode = 0;
1163 ip->keypad_appmode = 0;
1164 ip->imode = 0;
1165 ip->key_repeat = 1;
1166
1167 #ifdef DO_WEIRD_ATTRIBUTES
1168 bzero(ip->attrbuf, (ip->rows * ip->cols));
1169 #endif
1170 bzero (ip->tabs, ip->cols);
1171 for (i = 0; i < ip->cols; i++)
1172 ip->tabs[i] = (i & 7) == 0;
1173 }
1174
1175
1176 void
1177 iteputchar(c, dev)
1178 register int c;
1179 dev_t dev;
1180 {
1181 int unit = UNIT(dev);
1182 register struct ite_softc *ip = &ite_softc[unit];
1183 register struct itesw *sp = &itesw[ip->type];
1184 register int n;
1185 int x, y;
1186 char *cp;
1187
1188 if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE)
1189 return;
1190
1191 #if 0
1192 if (ite_tty[unit])
1193 if ((ite_tty[unit]->t_cflag & CSIZE) == CS7
1194 || (ite_tty[unit]->t_cflag & PARENB))
1195 c &= 0x7f;
1196 #endif
1197
1198 if (ip->escape)
1199 {
1200 doesc:
1201 switch (ip->escape)
1202 {
1203 case ESC:
1204 switch (c)
1205 {
1206 /* first 7bit equivalents for the 8bit control characters */
1207
1208 case 'D':
1209 c = IND;
1210 ip->escape = 0;
1211 break; /* and fall into the next switch below (same for all `break') */
1212
1213 case 'E':
1214 c = NEL;
1215 ip->escape = 0;
1216 break;
1217
1218 case 'H':
1219 c = HTS;
1220 ip->escape = 0;
1221 break;
1222
1223 case 'M':
1224 c = RI;
1225 ip->escape = 0;
1226 break;
1227
1228 case 'N':
1229 c = SS2;
1230 ip->escape = 0;
1231 break;
1232
1233 case 'O':
1234 c = SS3;
1235 ip->escape = 0;
1236 break;
1237
1238 case 'P':
1239 c = DCS;
1240 ip->escape = 0;
1241 break;
1242
1243 case '[':
1244 c = CSI;
1245 ip->escape = 0;
1246 break;
1247
1248 case '\\':
1249 c = ST;
1250 ip->escape = 0;
1251 break;
1252
1253 case ']':
1254 c = OSC;
1255 ip->escape = 0;
1256 break;
1257
1258 case '^':
1259 c = PM;
1260 ip->escape = 0;
1261 break;
1262
1263 case '_':
1264 c = APC;
1265 ip->escape = 0;
1266 break;
1267
1268
1269 /* introduces 7/8bit control */
1270 case ' ':
1271 /* can be followed by either F or G */
1272 ip->escape = ' ';
1273 break;
1274
1275
1276 /* a lot of character set selections, not yet used...
1277 94-character sets: */
1278 case '(': /* G0 */
1279 case ')': /* G1 */
1280 ip->escape = c;
1281 return;
1282
1283 case '*': /* G2 */
1284 case '+': /* G3 */
1285 case 'B': /* ASCII */
1286 case 'A': /* ISO latin 1 */
1287 case '<': /* user preferred suplemental */
1288 case '0': /* dec special graphics */
1289
1290 /* 96-character sets: */
1291 case '-': /* G1 */
1292 case '.': /* G2 */
1293 case '/': /* G3 */
1294
1295 /* national character sets: */
1296 case '4': /* dutch */
1297 case '5':
1298 case 'C': /* finnish */
1299 case 'R': /* french */
1300 case 'Q': /* french canadian */
1301 case 'K': /* german */
1302 case 'Y': /* italian */
1303 case '6': /* norwegian/danish */
1304 /* note: %5 and %6 are not supported (two chars..) */
1305
1306 ip->escape = 0;
1307 /* just ignore for now */
1308 return;
1309
1310
1311 /* locking shift modes (as you might guess, not yet supported..) */
1312 case '`':
1313 ip->GR = ip->G1;
1314 ip->escape = 0;
1315 return;
1316
1317 case 'n':
1318 ip->GL = ip->G2;
1319 ip->escape = 0;
1320 return;
1321
1322 case '}':
1323 ip->GR = ip->G2;
1324 ip->escape = 0;
1325 return;
1326
1327 case 'o':
1328 ip->GL = ip->G3;
1329 ip->escape = 0;
1330 return;
1331
1332 case '|':
1333 ip->GR = ip->G3;
1334 ip->escape = 0;
1335 return;
1336
1337
1338 /* font width/height control */
1339 case '#':
1340 ip->escape = '#';
1341 return;
1342
1343
1344 /* hard terminal reset .. */
1345 case 'c':
1346 ite_reset (ip);
1347 (*itesw[ip->type].ite_cursor)(ip, MOVE_CURSOR);
1348 ip->escape = 0;
1349 return;
1350
1351
1352 case '7':
1353 ip->save_curx = ip->curx;
1354 ip->save_cury = ip->cury;
1355 ip->save_attribute = ip->attribute;
1356 ip->escape = 0;
1357 return;
1358
1359 case '8':
1360 ip->curx = ip->save_curx;
1361 ip->cury = ip->save_cury;
1362 ip->attribute = ip->save_attribute;
1363 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1364 ip->escape = 0;
1365 return;
1366
1367 case '=':
1368 ip->keypad_appmode = 1;
1369 ip->escape = 0;
1370 return;
1371
1372 case '>':
1373 ip->keypad_appmode = 0;
1374 ip->escape = 0;
1375 return;
1376
1377 case 'Z': /* request ID */
1378 if (ip->emul_level == EMUL_VT100)
1379 ite_sendstr (ip, "\033[61;0c");
1380 else
1381 ite_sendstr (ip, "\033[63;0c");
1382 ip->escape = 0;
1383 return;
1384
1385 /* default catch all for not recognized ESC sequences */
1386 default:
1387 ip->escape = 0;
1388 return;
1389 }
1390 break;
1391
1392
1393 case '(':
1394 case ')':
1395 ip->escape = 0;
1396 return;
1397
1398
1399 case ' ':
1400 switch (c)
1401 {
1402 case 'F':
1403 ip->eightbit_C1 = 0;
1404 ip->escape = 0;
1405 return;
1406
1407 case 'G':
1408 ip->eightbit_C1 = 1;
1409 ip->escape = 0;
1410 return;
1411
1412 default:
1413 /* not supported */
1414 ip->escape = 0;
1415 return;
1416 }
1417 break;
1418
1419
1420 case '#':
1421 switch (c)
1422 {
1423 case '5':
1424 /* single height, single width */
1425 ip->escape = 0;
1426 return;
1427
1428 case '6':
1429 /* double width, single height */
1430 ip->escape = 0;
1431 return;
1432
1433 case '3':
1434 /* top half */
1435 ip->escape = 0;
1436 return;
1437
1438 case '4':
1439 /* bottom half */
1440 ip->escape = 0;
1441 return;
1442
1443 case '8':
1444 /* screen alignment pattern... */
1445 ip->escape = 0;
1446 return;
1447
1448 default:
1449 ip->escape = 0;
1450 return;
1451 }
1452 break;
1453
1454
1455
1456 case CSI:
1457 /* the biggie... */
1458 switch (c)
1459 {
1460 case '0': case '1': case '2': case '3': case '4':
1461 case '5': case '6': case '7': case '8': case '9':
1462 case ';': case '\"': case '$': case '>':
1463 if (ip->ap < ip->argbuf + ARGBUF_SIZE)
1464 *ip->ap++ = c;
1465 return;
1466
1467 case 'p':
1468 *ip->ap = 0;
1469 if (! strncmp (ip->argbuf, "61\"", 3))
1470 ip->emul_level = EMUL_VT100;
1471 else if (! strncmp (ip->argbuf, "63;1\"", 5)
1472 || ! strncmp (ip->argbuf, "62;1\"", 5))
1473 ip->emul_level = EMUL_VT300_7;
1474 else
1475 ip->emul_level = EMUL_VT300_8;
1476 ip->escape = 0;
1477 return;
1478
1479
1480 case '?':
1481 *ip->ap = 0;
1482 ip->escape = '?';
1483 ip->ap = ip->argbuf;
1484 return;
1485
1486
1487 case 'c':
1488 *ip->ap = 0;
1489 if (ip->argbuf[0] == '>')
1490 {
1491 ite_sendstr (ip, "\033[>24;0;0;0c");
1492 }
1493 else switch (ite_zargnum(ip))
1494 {
1495 case 0:
1496 /* primary DA request, send primary DA response */
1497 if (ip->emul_level == EMUL_VT100)
1498 ite_sendstr (ip, "\033[?1;1c");
1499 else
1500 ite_sendstr (ip, "\033[63;0c");
1501 break;
1502 }
1503 ip->escape = 0;
1504 <<<<<<< ite.c
1505 return -1;
1506 ||||||| 1.1.1.2
1507 return -1;
1508
1509 =======
1510 return;
1511 >>>>>>> /tmp/T4009622
1512
1513
1514 case 'n':
1515 switch (ite_zargnum(ip))
1516 {
1517 case 5:
1518 ite_sendstr (ip, "\033[0n"); /* no malfunction */
1519 break;
1520 case 6:
1521 /* cursor position report */
1522 sprintf (ip->argbuf, "\033[%d;%dR",
1523 ip->cury + 1, ip->curx + 1);
1524 ite_sendstr (ip, ip->argbuf);
1525 break;
1526 }
1527 ip->escape = 0;
1528 <<<<<<< ite.c
1529 return -1;
1530
1531 ||||||| 1.1.1.2
1532 return -1;
1533 =======
1534 return;
1535 >>>>>>> /tmp/T4009622
1536
1537 <<<<<<< ite.c
1538 case 'h': case 'l':
1539 *ip->ap = 0;
1540 if (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '4')
1541 ip->imode = (c == 'h'); /* insert/replace mode */
1542 ||||||| 1.1.1.2
1543
1544 case 'h': case 'l':
1545 *ip->ap = 0;
1546 if (ip->ap == &ip->argbuf[1] && ip->argbuf[0] == '4')
1547 ip->imode = (c == 'h'); /* insert/replace mode */
1548 =======
1549
1550 case 'x':
1551 switch (ite_zargnum(ip))
1552 {
1553 case 0:
1554 /* Fake some terminal parameters. */
1555 ite_sendstr (ip, "\033[2;1;1;112;112;1;0x");
1556 break;
1557 case 1:
1558 ite_sendstr (ip, "\033[3;1;1;112;112;1;0x");
1559 break;
1560 }
1561 ip->escape = 0;
1562 return;
1563 >>>>>>> /tmp/T4009622
1564
1565
1566 case 'g':
1567 switch (ite_zargnum(ip))
1568 {
1569 case 0:
1570 if (ip->curx < ip->cols)
1571 ip->tabs[ip->curx] = 0;
1572 break;
1573 case 3:
1574 for (n = 0; n < ip->cols; n++)
1575 ip->tabs[n] = 0;
1576 break;
1577 }
1578 ip->escape = 0;
1579 return;
1580
1581
1582 case 'h': case 'l':
1583 n = ite_zargnum (ip);
1584 switch (n)
1585 {
1586 case 4:
1587 ip->imode = (c == 'h'); /* insert/replace mode */
1588 break;
1589 case 20:
1590 ip->linefeed_newline = (c == 'h');
1591 break;
1592 }
1593 ip->escape = 0;
1594 return;
1595
1596
1597 case 'M':
1598 ite_dnline (ip, sp, ite_argnum (ip));
1599 ip->escape = 0;
1600 return;
1601
1602
1603 case 'L':
1604 ite_inline (ip, sp, ite_argnum (ip));
1605 ip->escape = 0;
1606 return;
1607
1608
1609 case 'P':
1610 ite_dnchar (ip, sp, ite_argnum (ip));
1611 ip->escape = 0;
1612 return;
1613
1614
1615 case '@':
1616 ite_inchar (ip, sp, ite_argnum (ip));
1617 ip->escape = 0;
1618 return;
1619
1620
1621 case 'H':
1622 case 'f':
1623 *ip->ap = 0;
1624 y = atoi (ip->argbuf);
1625 x = 0;
1626 cp = index (ip->argbuf, ';');
1627 if (cp)
1628 x = atoi (cp + 1);
1629 if (x) x--;
1630 if (y) y--;
1631 ip->cury = MIN(y, ip->rows - 1);
1632 ip->curx = MIN(x, ip->cols - 1);
1633 ip->escape = 0;
1634 snap_cury(ip, sp);
1635 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1636 clr_attr (ip, ATTR_INV);
1637 return;
1638
1639 case 'A':
1640 n = ip->cury - ite_argnum (ip);
1641 if (n < 0) n = 0;
1642 ip->cury = MAX(n, ip->inside_margins ? ip->top_margin : 0);
1643 ip->escape = 0;
1644 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1645 clr_attr (ip, ATTR_INV);
1646 return;
1647
1648 case 'B':
1649 n = ite_argnum (ip) + ip->cury;
1650 ip->cury = MIN(n, ip->inside_margins ? ip->bottom_margin : ip->rows - 1);
1651 ip->escape = 0;
1652 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1653 clr_attr (ip, ATTR_INV);
1654 return;
1655
1656 case 'C':
1657 n = ite_argnum (ip);
1658 ip->curx = MIN(ip->curx + n, ip->cols - 1);
1659 ip->escape = 0;
1660 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1661 clr_attr (ip, ATTR_INV);
1662 return;
1663
1664 case 'D':
1665 n = ite_argnum (ip);
1666 n = ip->curx - n;
1667 ip->curx = n >= 0 ? n : 0;
1668 ip->escape = 0;
1669 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1670 clr_attr (ip, ATTR_INV);
1671 return;
1672
1673
1674
1675
1676 case 'J':
1677 *ip->ap = 0;
1678 n = ite_zargnum (ip);
1679 if (n == 0)
1680 ite_clrtoeos(ip, sp);
1681 else if (n == 1)
1682 ite_clrtobos(ip, sp);
1683 else if (n == 2)
1684 ite_clrscreen(ip, sp);
1685 ip->escape = 0;
1686 return;
1687
1688
1689 case 'K':
1690 n = ite_zargnum (ip);
1691 if (n == 0)
1692 ite_clrtoeol(ip, sp);
1693 else if (n == 1)
1694 ite_clrtobol(ip, sp);
1695 else if (n == 2)
1696 ite_clrline(ip, sp);
1697 ip->escape = 0;
1698 return;
1699
1700
1701 case 'X':
1702 n = ite_argnum(ip) - 1;
1703 n = MIN(n, ip->cols - 1 - ip->curx);
1704 for (; n >= 0; n--)
1705 {
1706 attrclr(ip, ip->cury, ip->curx + n, 1, 1);
1707 (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx + n, ATTR_NOR);
1708 }
1709 ip->escape = 0;
1710 return;
1711
1712
1713 case '}': case '`':
1714 /* status line control */
1715 ip->escape = 0;
1716 return;
1717
1718
1719 case 'r':
1720 *ip->ap = 0;
1721 x = atoi (ip->argbuf);
1722 y = 0;
1723 cp = index (ip->argbuf, ';');
1724 if (cp)
1725 y = atoi (cp + 1);
1726 if ((x > 0) || (y > 1))
1727 {
1728 if (x) x--;
1729 if (y) y--;
1730 ip->top_margin = MIN(x, ip->rows - 1);
1731 ip->bottom_margin = MIN(y, ip->rows - 1);
1732 if (ip->bottom_margin < ip->top_margin)
1733 ip->bottom_margin = ip->top_margin;
1734 }
1735 else
1736 {
1737 ip->top_margin = 0;
1738 ip->bottom_margin = ip->rows - 1;
1739 }
1740 ip->cury = ip->top_margin;
1741 ip->curx = 0;
1742 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1743 ip->escape = 0;
1744 return;
1745
1746
1747 case 'm':
1748 /* big attribute setter/resetter */
1749 {
1750 char *cp;
1751 *ip->ap = 0;
1752 /* kludge to make CSIm work (== CSI0m) */
1753 if (ip->ap == ip->argbuf)
1754 ip->ap++;
1755 for (cp = ip->argbuf; cp < ip->ap; )
1756 {
1757 switch (*cp)
1758 {
1759 case 0:
1760 case '0':
1761 clr_attr (ip, ATTR_ALL);
1762 cp++;
1763 break;
1764
1765 case '1':
1766 set_attr (ip, ATTR_BOLD);
1767 cp++;
1768 break;
1769
1770 case '2':
1771 switch (cp[1])
1772 {
1773 case '2':
1774 clr_attr (ip, ATTR_BOLD);
1775 cp += 2;
1776 break;
1777
1778 case '4':
1779 clr_attr (ip, ATTR_UL);
1780 cp += 2;
1781 break;
1782
1783 case '5':
1784 clr_attr (ip, ATTR_BLINK);
1785 cp += 2;
1786 break;
1787
1788 case '7':
1789 clr_attr (ip, ATTR_INV);
1790 cp += 2;
1791 break;
1792
1793 default:
1794 cp++;
1795 break;
1796 }
1797 break;
1798
1799 case '4':
1800 set_attr (ip, ATTR_UL);
1801 cp++;
1802 break;
1803
1804 case '5':
1805 set_attr (ip, ATTR_BLINK);
1806 cp++;
1807 break;
1808
1809 case '7':
1810 set_attr (ip, ATTR_INV);
1811 cp++;
1812 break;
1813
1814 default:
1815 cp++;
1816 break;
1817 }
1818 }
1819
1820 }
1821 ip->escape = 0;
1822 return;
1823
1824
1825 case 'u':
1826 /* DECRQTSR */
1827 ite_sendstr (ip, "\033P\033\\");
1828 ip->escape = 0;
1829 return;
1830
1831
1832
1833 default:
1834 ip->escape = 0;
1835 return;
1836 }
1837 break;
1838
1839
1840
1841 case '?': /* CSI ? */
1842 switch (c)
1843 {
1844 case '0': case '1': case '2': case '3': case '4':
1845 case '5': case '6': case '7': case '8': case '9':
1846 case ';': case '\"': case '$':
1847 /* Don't fill the last character; it's needed. */
1848 /* XXX yeah, where ?? */
1849 if (ip->ap < ip->argbuf + ARGBUF_SIZE - 1)
1850 *ip->ap++ = c;
1851 return;
1852
1853
1854 case 'n':
1855 *ip->ap = 0;
1856 if (ip->ap == &ip->argbuf[2])
1857 {
1858 if (! strncmp (ip->argbuf, "15", 2))
1859 /* printer status: no printer */
1860 ite_sendstr (ip, "\033[13n");
1861
1862 else if (! strncmp (ip->argbuf, "25", 2))
1863 /* udk status */
1864 ite_sendstr (ip, "\033[20n");
1865
1866 else if (! strncmp (ip->argbuf, "26", 2))
1867 /* keyboard dialect: US */
1868 ite_sendstr (ip, "\033[27;1n");
1869 }
1870 ip->escape = 0;
1871 return;
1872
1873
1874 case 'h': case 'l':
1875 n = ite_zargnum (ip);
1876 switch (n)
1877 {
1878 case 1:
1879 ip->cursor_appmode = (c == 'h');
1880 break;
1881
1882 case 3:
1883 /* 132/80 columns (132 == 'h') */
1884 break;
1885
1886 case 4: /* smooth scroll */
1887 break;
1888
1889 case 5:
1890 /* light background (=='h') /dark background(=='l') */
1891 break;
1892
1893 case 6: /* origin mode */
1894 ip->inside_margins = (c == 'h');
1895 break;
1896
1897 case 7: /* auto wraparound */
1898 ip->auto_wrap = (c == 'h');
1899 break;
1900
1901 case 8: /* keyboard repeat */
1902 ip->key_repeat = (c == 'h');
1903 break;
1904
1905 case 20: /* newline mode */
1906 ip->linefeed_newline = (c == 'h');
1907 break;
1908
1909 case 25: /* cursor on/off */
1910 (*itesw[ip->type].ite_cursor)(ip, (c == 'h') ? DRAW_CURSOR : ERASE_CURSOR);
1911 break;
1912 }
1913 ip->escape = 0;
1914 return;
1915
1916 default:
1917 ip->escape = 0;
1918 return;
1919 }
1920 break;
1921
1922
1923 default:
1924 ip->escape = 0;
1925 return;
1926 }
1927 }
1928
1929
1930 switch (c) {
1931
1932 case VT: /* VT is treated like LF */
1933 case FF: /* so is FF */
1934 case LF:
1935 /* cr->crlf distinction is done here, on output,
1936 not on input! */
1937 if (ip->linefeed_newline)
1938 ite_crlf (ip, sp);
1939 else
1940 ite_lf (ip, sp);
1941 break;
1942
1943 case CR:
1944 ite_cr (ip, sp);
1945 break;
1946
1947 case BS:
1948 if (--ip->curx < 0)
1949 ip->curx = 0;
1950 else
1951 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1952 break;
1953
1954 case HT:
1955 for (n = ip->curx + 1; n < ip->cols; n++) {
1956 if (ip->tabs[n]) {
1957 ip->curx = n;
1958 (*sp->ite_cursor)(ip, MOVE_CURSOR);
1959 break;
1960 }
1961 }
1962 break;
1963
1964 case BEL:
1965 if (kbd_tty && ite_tty[unit] == kbd_tty)
1966 kbdbell();
1967 break;
1968
1969 case SO:
1970 ip->GL = ip->G1;
1971 break;
1972
1973 case SI:
1974 ip->GL = ip->G0;
1975 break;
1976
1977 case ENQ:
1978 /* send answer-back message !! */
1979 break;
1980
1981 case CAN:
1982 ip->escape = 0; /* cancel any escape sequence in progress */
1983 break;
1984
1985 case SUB:
1986 ip->escape = 0; /* dito, but see below */
1987 /* should also display a reverse question mark!! */
1988 break;
1989
1990 case ESC:
1991 ip->escape = ESC;
1992 break;
1993
1994
1995 /* now it gets weird.. 8bit control sequences.. */
1996 case IND: /* index: move cursor down, scroll */
1997 ite_lf (ip, sp);
1998 break;
1999
2000 case NEL: /* next line. next line, first pos. */
2001 ite_crlf (ip, sp);
2002 break;
2003
2004 case HTS: /* set horizontal tab */
2005 if (ip->curx < ip->cols)
2006 ip->tabs[ip->curx] = 1;
2007 break;
2008
2009 case RI: /* reverse index */
2010 ite_rlf (ip, sp);
2011 break;
2012
2013 case SS2: /* go into G2 for one character */
2014 /* not yet supported */
2015 break;
2016
2017 case SS3: /* go into G3 for one character */
2018 break;
2019
2020 case DCS: /* device control string introducer */
2021 ip->escape = DCS;
2022 ip->ap = ip->argbuf;
2023 break;
2024
2025 case CSI: /* control sequence introducer */
2026 ip->escape = CSI;
2027 ip->ap = ip->argbuf;
2028 break;
2029
2030 case ST: /* string terminator */
2031 /* ignore, if not used as terminator */
2032 break;
2033
2034 case OSC: /* introduces OS command. Ignore everything upto ST */
2035 ip->escape = OSC;
2036 break;
2037
2038 case PM: /* privacy message, ignore everything upto ST */
2039 ip->escape = PM;
2040 break;
2041
2042 case APC: /* application program command, ignore everything upto ST */
2043 ip->escape = APC;
2044 break;
2045
2046 default:
2047 if (c < ' ' || c == DEL)
2048 break;
2049 if (ip->imode)
2050 ite_inchar(ip, sp, 1);
2051 iteprecheckwrap(ip, sp);
2052 #ifdef DO_WEIRD_ATTRIBUTES
2053 if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) {
2054 attrset(ip, ATTR_INV);
2055 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV);
2056 }
2057 else
2058 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR);
2059 #else
2060 (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ip->attribute);
2061 #endif
2062 (*sp->ite_cursor)(ip, DRAW_CURSOR);
2063 itecheckwrap(ip, sp);
2064 break;
2065 }
2066 }
2067
2068 iteprecheckwrap(ip, sp)
2069 register struct ite_softc *ip;
2070 register struct itesw *sp;
2071 {
2072 if (ip->auto_wrap && ip->curx == ip->cols) {
2073 ip->curx = 0;
2074 clr_attr(ip, ATTR_INV);
2075 if (++ip->cury >= ip->bottom_margin + 1) {
2076 ip->cury = ip->bottom_margin;
2077 (*sp->ite_cursor)(ip, MOVE_CURSOR);
2078 (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
2079 ite_clrtoeol(ip, sp);
2080 } else
2081 (*sp->ite_cursor)(ip, MOVE_CURSOR);
2082 }
2083 }
2084
2085 itecheckwrap(ip, sp)
2086 register struct ite_softc *ip;
2087 register struct itesw *sp;
2088 {
2089 #if 0
2090 if (++ip->curx == ip->cols) {
2091 if (ip->auto_wrap) {
2092 ip->curx = 0;
2093 clr_attr(ip, ATTR_INV);
2094 if (++ip->cury >= ip->bottom_margin + 1) {
2095 ip->cury = ip->bottom_margin;
2096 (*sp->ite_cursor)(ip, MOVE_CURSOR);
2097 (*sp->ite_scroll)(ip, ip->top_margin + 1, 0, 1, SCROLL_UP);
2098 ite_clrtoeol(ip, sp);
2099 return;
2100 }
2101 } else
2102 /* stay there if no autowrap.. */
2103 ip->curx--;
2104 }
2105 #else
2106 if (ip->curx < ip->cols) {
2107 ip->curx++;
2108 (*sp->ite_cursor)(ip, MOVE_CURSOR);
2109 }
2110 #endif
2111 }
2112
2113 /*
2114 * Console functions
2115 */
2116 #include "grfioctl.h"
2117 #include "grfvar.h"
2118
2119 #ifdef DEBUG
2120 /*
2121 * Minimum ITE number at which to start looking for a console.
2122 * Setting to 0 will do normal search, 1 will skip first ITE device,
2123 * NITE will skip ITEs and use serial port.
2124 */
2125 int whichconsole = 0;
2126 #endif
2127
2128 itecnprobe(cp)
2129 struct consdev *cp;
2130 {
2131 register struct ite_softc *ip;
2132 int i, maj, unit, pri;
2133
2134 /* locate the major number */
2135 for (maj = 0; maj < nchrdev; maj++)
2136 if (cdevsw[maj].d_open == iteopen)
2137 break;
2138
2139 /* urk! */
2140 grfconfig();
2141
2142 /* check all the individual displays and find the best */
2143 unit = -1;
2144 pri = CN_DEAD;
2145 for (i = 0; i < NITE; i++) {
2146 struct grf_softc *gp = &grf_softc[i];
2147
2148 ip = &ite_softc[i];
2149 if ((gp->g_flags & GF_ALIVE) == 0)
2150 continue;
2151 ip->flags = (ITE_ALIVE|ITE_CONSOLE);
2152
2153 /* XXX - we need to do something about mapping these */
2154 switch (gp->g_type) {
2155 case GT_CUSTOMCHIPS:
2156 ip->type = ITE_CUSTOMCHIPS;
2157 break;
2158
2159 case GT_TIGA_A2410:
2160 ip->type = ITE_TIGA_A2410;
2161 break;
2162
2163 case GT_RETINA:
2164 ip->type = ITE_RETINA;
2165 break;
2166 }
2167 #ifdef DEBUG
2168 if (i < whichconsole)
2169 continue;
2170 #endif
2171 if ((int)gp->g_type == GT_CUSTOMCHIPS) {
2172 pri = CN_INTERNAL;
2173 unit = i;
2174 } else /* if (unit < 0) */ {
2175 pri = CN_NORMAL;
2176 unit = i;
2177 }
2178
2179 }
2180
2181 /* initialize required fields */
2182 cp->cn_dev = makedev(maj, unit);
2183 #if 0
2184 cp->cn_tp = ite_tty[unit];
2185 #else
2186 delayed_con_tty = unit;
2187 #endif
2188 cp->cn_pri = pri;
2189 }
2190
2191 itecninit(cp)
2192 struct consdev *cp;
2193 {
2194 int unit;
2195 struct ite_softc *ip;
2196
2197 iteinit(cp->cn_dev);
2198 unit = UNIT(cp->cn_dev);
2199 ip = &ite_softc[unit];
2200
2201 #ifdef DO_WEIRD_ATTRIBUTES
2202 ip->attrbuf = console_attributes;
2203 #endif
2204 ip->flags |= (ITE_ACTIVE|ITE_ISCONS);
2205 /* if this is the console, NEVER close the device! */
2206 ip->open_cnt++;
2207 #if 0
2208 /* have to delay this too.. sigh.. */
2209 kbd_tty = ite_tty[unit];
2210 kbd_ip = ip;
2211 kbdenable();
2212 #endif
2213 }
2214
2215 /*ARGSUSED*/
2216 itecngetc(dev)
2217 dev_t dev;
2218 {
2219 register int c;
2220
2221 do
2222 {
2223 c = kbdgetcn ();
2224 c = itefilter (c, ITEFILT_CONSOLE);
2225 }
2226 while (c == -1);
2227
2228 return(c);
2229 }
2230
2231 itecnputc(dev, c)
2232 dev_t dev;
2233 int c;
2234 {
2235 static int paniced = 0;
2236 struct ite_softc *ip = &ite_softc[UNIT(dev)];
2237
2238 if (panicstr && !paniced &&
2239 (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) {
2240 (void) iteon(dev, 3);
2241 paniced = 1;
2242 }
2243 iteputchar(c, dev);
2244 }
2245 #endif
2246