Commit | Line | Data |
---|---|---|
60f56dfc KM |
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 | * %sccs.include.redist.c% | |
11 | * | |
7b7da76f | 12 | * from: Utah $Hdr: ite.c 1.24 92/01/21$ |
60f56dfc | 13 | * |
38a01dbe | 14 | * @(#)ite.c 7.14 (Berkeley) %G% |
60f56dfc KM |
15 | */ |
16 | ||
17 | /* | |
18 | * Bit-mapped display terminal emulator machine independent code. | |
19 | * This is a very rudimentary. Much more can be abstracted out of | |
20 | * the hardware dependent routines. | |
21 | */ | |
22 | #include "ite.h" | |
23 | #if NITE > 0 | |
24 | ||
25 | #include "grf.h" | |
26 | ||
27 | #undef NITE | |
28 | #define NITE NGRF | |
29 | ||
38a01dbe KB |
30 | #include <sys/param.h> |
31 | #include <sys/conf.h> | |
32 | #include <sys/proc.h> | |
33 | #include <sys/ioctl.h> | |
34 | #include <sys/tty.h> | |
35 | #include <sys/systm.h> | |
36 | #include <sys/malloc.h> | |
60f56dfc | 37 | |
38a01dbe KB |
38 | #include <hp/dev/grfioctl.h> |
39 | #include <hp/dev/grfvar.h> | |
40 | #include <hp/dev/itevar.h> | |
41 | #include <hp/dev/kbdmap.h> | |
60f56dfc | 42 | |
60f56dfc KM |
43 | #define set_attr(ip, attr) ((ip)->attribute |= (attr)) |
44 | #define clr_attr(ip, attr) ((ip)->attribute &= ~(attr)) | |
45 | ||
60f56dfc KM |
46 | /* |
47 | * # of chars are output in a single itestart() call. | |
48 | * If this is too big, user processes will be blocked out for | |
49 | * long periods of time while we are emptying the queue in itestart(). | |
50 | * If it is too small, console output will be very ragged. | |
51 | */ | |
52 | int iteburst = 64; | |
53 | ||
54 | int nite = NITE; | |
55 | struct tty *kbd_tty = NULL; | |
56 | struct tty ite_tty[NITE]; | |
57 | struct ite_softc ite_softc[NITE]; | |
58 | ||
c3463f28 | 59 | void itestart(); |
88a0c57a | 60 | extern void ttrstrt __P((void *)); |
60f56dfc KM |
61 | extern struct tty *constty; |
62 | ||
63 | /* | |
64 | * Primary attribute buffer to be used by the first bitmapped console | |
65 | * found. Secondary displays alloc the attribute buffer as needed. | |
66 | * Size is based on a 68x128 display, which is currently our largest. | |
67 | */ | |
68 | u_char console_attributes[0x2200]; | |
69 | ||
70 | /* | |
71 | * Perform functions necessary to setup device as a terminal emulator. | |
72 | */ | |
73 | iteon(dev, flag) | |
74 | dev_t dev; | |
75 | { | |
76 | int unit = UNIT(dev); | |
77 | struct tty *tp = &ite_tty[unit]; | |
78 | struct ite_softc *ip = &ite_softc[unit]; | |
79 | ||
80 | if (unit < 0 || unit >= NITE || (ip->flags&ITE_ALIVE) == 0) | |
81 | return(ENXIO); | |
82 | /* force ite active, overriding graphics mode */ | |
83 | if (flag & 1) { | |
84 | ip->flags |= ITE_ACTIVE; | |
85 | ip->flags &= ~(ITE_INGRF|ITE_INITED); | |
86 | } | |
87 | /* leave graphics mode */ | |
88 | if (flag & 2) { | |
89 | ip->flags &= ~ITE_INGRF; | |
90 | if ((ip->flags & ITE_ACTIVE) == 0) | |
91 | return(0); | |
92 | } | |
93 | ip->flags |= ITE_ACTIVE; | |
94 | if (ip->flags & ITE_INGRF) | |
95 | return(0); | |
96 | if (kbd_tty == NULL || kbd_tty == tp) { | |
97 | kbd_tty = tp; | |
7b7da76f | 98 | kbdenable(unit); |
60f56dfc KM |
99 | } |
100 | iteinit(dev); | |
101 | return(0); | |
102 | } | |
103 | ||
104 | iteinit(dev) | |
105 | dev_t dev; | |
106 | { | |
107 | int unit = UNIT(dev); | |
108 | struct ite_softc *ip = &ite_softc[unit]; | |
109 | ||
110 | if (ip->flags & ITE_INITED) | |
111 | return; | |
112 | ||
113 | ip->curx = 0; | |
114 | ip->cury = 0; | |
115 | ip->cursorx = 0; | |
116 | ip->cursory = 0; | |
117 | ||
7b7da76f MH |
118 | (*ip->isw->ite_init)(ip); |
119 | (*ip->isw->ite_cursor)(ip, DRAW_CURSOR); | |
60f56dfc KM |
120 | |
121 | ip->attribute = 0; | |
122 | if (ip->attrbuf == NULL) | |
123 | ip->attrbuf = (u_char *) | |
124 | malloc(ip->rows * ip->cols, M_DEVBUF, M_WAITOK); | |
125 | bzero(ip->attrbuf, (ip->rows * ip->cols)); | |
126 | ||
127 | ip->imode = 0; | |
128 | ip->flags |= ITE_INITED; | |
129 | } | |
130 | ||
131 | /* | |
132 | * "Shut down" device as terminal emulator. | |
133 | * Note that we do not deinit the console device unless forced. | |
134 | * Deinit'ing the console every time leads to a very active | |
135 | * screen when processing /etc/rc. | |
136 | */ | |
137 | iteoff(dev, flag) | |
138 | dev_t dev; | |
139 | { | |
140 | register struct ite_softc *ip = &ite_softc[UNIT(dev)]; | |
141 | ||
142 | if (flag & 2) | |
143 | ip->flags |= ITE_INGRF; | |
144 | if ((ip->flags & ITE_ACTIVE) == 0) | |
145 | return; | |
146 | if ((flag & 1) || | |
147 | (ip->flags & (ITE_INGRF|ITE_ISCONS|ITE_INITED)) == ITE_INITED) | |
7b7da76f | 148 | (*ip->isw->ite_deinit)(ip); |
60f56dfc KM |
149 | if ((flag & 2) == 0) |
150 | ip->flags &= ~ITE_ACTIVE; | |
151 | } | |
152 | ||
88f29710 MK |
153 | /* ARGSUSED */ |
154 | #ifdef __STDC__ | |
155 | iteopen(dev_t dev, int mode, int devtype, struct proc *p) | |
156 | #else | |
157 | iteopen(dev, mode, devtype, p) | |
60f56dfc | 158 | dev_t dev; |
88f29710 MK |
159 | int mode, devtype; |
160 | struct proc *p; | |
161 | #endif | |
60f56dfc KM |
162 | { |
163 | int unit = UNIT(dev); | |
164 | register struct tty *tp = &ite_tty[unit]; | |
165 | register struct ite_softc *ip = &ite_softc[unit]; | |
166 | register int error; | |
167 | int first = 0; | |
168 | ||
19fe8dbe | 169 | if ((tp->t_state&(TS_ISOPEN|TS_XCLUDE)) == (TS_ISOPEN|TS_XCLUDE) |
88f29710 | 170 | && p->p_ucred->cr_uid != 0) |
60f56dfc KM |
171 | return (EBUSY); |
172 | if ((ip->flags & ITE_ACTIVE) == 0) { | |
173 | error = iteon(dev, 0); | |
174 | if (error) | |
175 | return (error); | |
176 | first = 1; | |
177 | } | |
178 | tp->t_oproc = itestart; | |
179 | tp->t_param = NULL; | |
180 | tp->t_dev = dev; | |
181 | if ((tp->t_state&TS_ISOPEN) == 0) { | |
182 | ttychars(tp); | |
183 | tp->t_iflag = TTYDEF_IFLAG; | |
184 | tp->t_oflag = TTYDEF_OFLAG; | |
185 | tp->t_cflag = CS8|CREAD; | |
186 | tp->t_lflag = TTYDEF_LFLAG; | |
187 | tp->t_ispeed = tp->t_ospeed = TTYDEF_SPEED; | |
188 | tp->t_state = TS_ISOPEN|TS_CARR_ON; | |
189 | ttsetwater(tp); | |
190 | } | |
191 | error = (*linesw[tp->t_line].l_open)(dev, tp); | |
192 | if (error == 0) { | |
193 | tp->t_winsize.ws_row = ip->rows; | |
194 | tp->t_winsize.ws_col = ip->cols; | |
195 | } else if (first) | |
196 | iteoff(dev, 0); | |
197 | return (error); | |
198 | } | |
199 | ||
200 | /*ARGSUSED*/ | |
f5daa13d | 201 | iteclose(dev, flag, mode, p) |
60f56dfc | 202 | dev_t dev; |
f5daa13d MT |
203 | int flag, mode; |
204 | struct proc *p; | |
60f56dfc KM |
205 | { |
206 | register struct tty *tp = &ite_tty[UNIT(dev)]; | |
207 | ||
f5daa13d | 208 | (*linesw[tp->t_line].l_close)(tp, flag); |
60f56dfc KM |
209 | ttyclose(tp); |
210 | iteoff(dev, 0); | |
211 | return(0); | |
212 | } | |
213 | ||
214 | iteread(dev, uio, flag) | |
215 | dev_t dev; | |
216 | struct uio *uio; | |
217 | { | |
218 | register struct tty *tp = &ite_tty[UNIT(dev)]; | |
219 | ||
220 | return ((*linesw[tp->t_line].l_read)(tp, uio, flag)); | |
221 | } | |
222 | ||
223 | itewrite(dev, uio, flag) | |
224 | dev_t dev; | |
225 | struct uio *uio; | |
226 | { | |
227 | int unit = UNIT(dev); | |
228 | register struct tty *tp = &ite_tty[unit]; | |
229 | ||
230 | if ((ite_softc[unit].flags & ITE_ISCONS) && constty && | |
231 | (constty->t_state&(TS_CARR_ON|TS_ISOPEN))==(TS_CARR_ON|TS_ISOPEN)) | |
232 | tp = constty; | |
233 | return ((*linesw[tp->t_line].l_write)(tp, uio, flag)); | |
234 | } | |
235 | ||
ba881aac | 236 | iteioctl(dev, cmd, addr, flag, p) |
60f56dfc | 237 | dev_t dev; |
ba881aac | 238 | int cmd; |
60f56dfc | 239 | caddr_t addr; |
ba881aac KM |
240 | int flag; |
241 | struct proc *p; | |
60f56dfc KM |
242 | { |
243 | register struct tty *tp = &ite_tty[UNIT(dev)]; | |
244 | int error; | |
245 | ||
ba881aac | 246 | error = (*linesw[tp->t_line].l_ioctl)(tp, cmd, addr, flag, p); |
60f56dfc KM |
247 | if (error >= 0) |
248 | return (error); | |
249 | error = ttioctl(tp, cmd, addr, flag); | |
250 | if (error >= 0) | |
251 | return (error); | |
252 | return (ENOTTY); | |
253 | } | |
254 | ||
c3463f28 | 255 | void |
60f56dfc KM |
256 | itestart(tp) |
257 | register struct tty *tp; | |
258 | { | |
259 | register int cc, s; | |
260 | int hiwat = 0; | |
261 | ||
262 | s = spltty(); | |
263 | if (tp->t_state & (TS_TIMEOUT|TS_BUSY|TS_TTSTOP)) { | |
264 | splx(s); | |
265 | return; | |
266 | } | |
267 | tp->t_state |= TS_BUSY; | |
268 | cc = tp->t_outq.c_cc; | |
269 | if (cc <= tp->t_lowat) { | |
270 | if (tp->t_state & TS_ASLEEP) { | |
271 | tp->t_state &= ~TS_ASLEEP; | |
c3463f28 | 272 | wakeup((caddr_t)&tp->t_outq); |
60f56dfc | 273 | } |
2d32402a | 274 | selwakeup(&tp->t_wsel); |
60f56dfc KM |
275 | } |
276 | /* | |
277 | * Limit the amount of output we do in one burst | |
278 | * to prevent hogging the CPU. | |
279 | */ | |
280 | if (cc > iteburst) { | |
281 | hiwat++; | |
282 | cc = iteburst; | |
283 | } | |
284 | while (--cc >= 0) { | |
285 | register int c; | |
286 | ||
287 | c = getc(&tp->t_outq); | |
288 | /* | |
289 | * iteputchar() may take a long time and we don't want to | |
290 | * block all interrupts for long periods of time. Since | |
291 | * there is no need to stay at high priority while outputing | |
292 | * the character (since we don't have to worry about | |
293 | * interrupts), we don't. We just need to make sure that | |
294 | * we don't reenter iteputchar, which is guarenteed by the | |
295 | * earlier setting of TS_BUSY. | |
296 | */ | |
297 | splx(s); | |
298 | iteputchar(c, tp->t_dev); | |
299 | spltty(); | |
300 | } | |
301 | if (hiwat) { | |
302 | tp->t_state |= TS_TIMEOUT; | |
303 | timeout(ttrstrt, tp, 1); | |
304 | } | |
305 | tp->t_state &= ~TS_BUSY; | |
306 | splx(s); | |
307 | } | |
308 | ||
309 | itefilter(stat, c) | |
310 | register char stat, c; | |
311 | { | |
312 | static int capsmode = 0; | |
313 | static int metamode = 0; | |
314 | register char code, *str; | |
315 | ||
316 | if (kbd_tty == NULL) | |
317 | return; | |
318 | ||
319 | switch (c & 0xFF) { | |
320 | case KBD_CAPSLOCK: | |
321 | capsmode = !capsmode; | |
322 | return; | |
323 | ||
324 | case KBD_EXT_LEFT_DOWN: | |
325 | case KBD_EXT_RIGHT_DOWN: | |
326 | metamode = 1; | |
327 | return; | |
328 | ||
329 | case KBD_EXT_LEFT_UP: | |
330 | case KBD_EXT_RIGHT_UP: | |
331 | metamode = 0; | |
332 | return; | |
333 | } | |
334 | ||
335 | c &= KBD_CHARMASK; | |
336 | switch ((stat>>KBD_SSHIFT) & KBD_SMASK) { | |
337 | ||
338 | case KBD_KEY: | |
339 | if (!capsmode) { | |
340 | code = kbd_keymap[c]; | |
341 | break; | |
342 | } | |
343 | /* fall into... */ | |
344 | ||
345 | case KBD_SHIFT: | |
346 | code = kbd_shiftmap[c]; | |
347 | break; | |
348 | ||
349 | case KBD_CTRL: | |
350 | code = kbd_ctrlmap[c]; | |
351 | break; | |
352 | ||
353 | case KBD_CTRLSHIFT: | |
354 | code = kbd_ctrlshiftmap[c]; | |
355 | break; | |
356 | } | |
357 | ||
358 | if (code == NULL && (str = kbd_stringmap[c]) != NULL) { | |
359 | while (*str) | |
360 | (*linesw[kbd_tty->t_line].l_rint)(*str++, kbd_tty); | |
361 | } else { | |
362 | if (metamode) | |
363 | code |= 0x80; | |
364 | (*linesw[kbd_tty->t_line].l_rint)(code, kbd_tty); | |
365 | } | |
366 | } | |
367 | ||
368 | iteputchar(c, dev) | |
369 | register int c; | |
370 | dev_t dev; | |
371 | { | |
372 | int unit = UNIT(dev); | |
373 | register struct ite_softc *ip = &ite_softc[unit]; | |
7b7da76f | 374 | register struct itesw *sp = ip->isw; |
60f56dfc KM |
375 | register int n; |
376 | ||
377 | if ((ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) | |
378 | return; | |
379 | ||
380 | if (ip->escape) { | |
381 | doesc: | |
382 | switch (ip->escape) { | |
383 | ||
384 | case '&': /* Next can be a,d, or s */ | |
385 | if (ip->fpd++) { | |
386 | ip->escape = c; | |
387 | ip->fpd = 0; | |
388 | } | |
389 | return; | |
390 | ||
391 | case 'a': /* cursor change */ | |
392 | switch (c) { | |
393 | ||
394 | case 'Y': /* Only y coord. */ | |
479c0df7 | 395 | ip->cury = min(ip->pos, ip->rows-1); |
60f56dfc KM |
396 | ip->pos = 0; |
397 | ip->escape = 0; | |
398 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
399 | clr_attr(ip, ATTR_INV); | |
400 | break; | |
401 | ||
402 | case 'y': /* y coord first */ | |
479c0df7 | 403 | ip->cury = min(ip->pos, ip->rows-1); |
60f56dfc KM |
404 | ip->pos = 0; |
405 | ip->fpd = 0; | |
406 | break; | |
407 | ||
408 | case 'C': /* x coord */ | |
479c0df7 | 409 | ip->curx = min(ip->pos, ip->cols-1); |
60f56dfc KM |
410 | ip->pos = 0; |
411 | ip->escape = 0; | |
412 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
413 | clr_attr(ip, ATTR_INV); | |
414 | break; | |
415 | ||
416 | default: /* Possibly a 3 digit number. */ | |
417 | if (c >= '0' && c <= '9' && ip->fpd < 3) { | |
418 | ip->pos = ip->pos * 10 + (c - '0'); | |
419 | ip->fpd++; | |
420 | } else { | |
421 | ip->pos = 0; | |
422 | ip->escape = 0; | |
423 | } | |
424 | break; | |
425 | } | |
426 | return; | |
427 | ||
428 | case 'd': /* attribute change */ | |
429 | switch (c) { | |
430 | ||
431 | case 'B': | |
432 | set_attr(ip, ATTR_INV); | |
433 | break; | |
434 | case 'D': | |
435 | /* XXX: we don't do anything for underline */ | |
436 | set_attr(ip, ATTR_UL); | |
437 | break; | |
438 | case '@': | |
439 | clr_attr(ip, ATTR_ALL); | |
440 | break; | |
441 | } | |
442 | ip->escape = 0; | |
443 | return; | |
444 | ||
445 | case 's': /* keypad control */ | |
446 | switch (ip->fpd) { | |
447 | ||
448 | case 0: | |
449 | ip->hold = c; | |
450 | ip->fpd++; | |
451 | return; | |
452 | ||
453 | case 1: | |
454 | if (c == 'A') { | |
455 | switch (ip->hold) { | |
456 | ||
457 | case '0': | |
458 | clr_attr(ip, ATTR_KPAD); | |
459 | break; | |
460 | case '1': | |
461 | set_attr(ip, ATTR_KPAD); | |
462 | break; | |
463 | } | |
464 | } | |
465 | ip->hold = 0; | |
466 | } | |
467 | ip->escape = 0; | |
468 | return; | |
469 | ||
470 | case 'i': /* back tab */ | |
471 | if (ip->curx > TABSIZE) { | |
472 | n = ip->curx - (ip->curx & (TABSIZE - 1)); | |
473 | ip->curx -= n; | |
474 | } else | |
475 | ip->curx = 0; | |
476 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
477 | ip->escape = 0; | |
478 | return; | |
479 | ||
480 | case '3': /* clear all tabs */ | |
481 | goto ignore; | |
482 | ||
483 | case 'K': /* clear_eol */ | |
484 | ite_clrtoeol(ip, sp, ip->cury, ip->curx); | |
485 | ip->escape = 0; | |
486 | return; | |
487 | ||
488 | case 'J': /* clear_eos */ | |
489 | ite_clrtoeos(ip, sp); | |
490 | ip->escape = 0; | |
491 | return; | |
492 | ||
493 | case 'B': /* cursor down 1 line */ | |
494 | if (++ip->cury == ip->rows) { | |
495 | --ip->cury; | |
496 | (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); | |
497 | ite_clrtoeol(ip, sp, ip->cury, 0); | |
498 | } | |
499 | else | |
500 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
501 | clr_attr(ip, ATTR_INV); | |
502 | ip->escape = 0; | |
503 | return; | |
504 | ||
505 | case 'C': /* cursor forward 1 char */ | |
506 | ip->escape = 0; | |
507 | itecheckwrap(ip, sp); | |
508 | return; | |
509 | ||
510 | case 'A': /* cursor up 1 line */ | |
511 | if (ip->cury > 0) { | |
512 | ip->cury--; | |
513 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
514 | } | |
515 | ip->escape = 0; | |
516 | clr_attr(ip, ATTR_INV); | |
517 | return; | |
518 | ||
519 | case 'P': /* delete character */ | |
520 | ite_dchar(ip, sp); | |
521 | ip->escape = 0; | |
522 | return; | |
523 | ||
524 | case 'M': /* delete line */ | |
525 | ite_dline(ip, sp); | |
526 | ip->escape = 0; | |
527 | return; | |
528 | ||
529 | case 'Q': /* enter insert mode */ | |
530 | ip->imode = 1; | |
531 | ip->escape = 0; | |
532 | return; | |
533 | ||
534 | case 'R': /* exit insert mode */ | |
535 | ip->imode = 0; | |
536 | ip->escape = 0; | |
537 | return; | |
538 | ||
539 | case 'L': /* insert blank line */ | |
540 | ite_iline(ip, sp); | |
541 | ip->escape = 0; | |
542 | return; | |
543 | ||
544 | case 'h': /* home key */ | |
545 | ip->cury = ip->curx = 0; | |
546 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
547 | ip->escape = 0; | |
548 | return; | |
549 | ||
550 | case 'D': /* left arrow key */ | |
551 | if (ip->curx > 0) { | |
552 | ip->curx--; | |
553 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
554 | } | |
555 | ip->escape = 0; | |
556 | return; | |
557 | ||
558 | case '1': /* set tab in all rows */ | |
559 | goto ignore; | |
560 | ||
561 | case ESC: | |
562 | if ((ip->escape = c) == ESC) | |
563 | break; | |
564 | ip->fpd = 0; | |
565 | goto doesc; | |
566 | ||
567 | default: | |
568 | ignore: | |
569 | ip->escape = 0; | |
570 | return; | |
571 | ||
572 | } | |
573 | } | |
574 | ||
575 | switch (c &= 0x7F) { | |
576 | ||
577 | case '\n': | |
578 | ||
579 | if (++ip->cury == ip->rows) { | |
580 | --ip->cury; | |
581 | (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); | |
582 | ite_clrtoeol(ip, sp, ip->cury, 0); | |
583 | } | |
584 | else | |
585 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
586 | clr_attr(ip, ATTR_INV); | |
587 | break; | |
588 | ||
589 | case '\r': | |
590 | if (ip->curx) { | |
591 | ip->curx = 0; | |
592 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
593 | } | |
594 | break; | |
595 | ||
596 | case '\b': | |
597 | if (--ip->curx < 0) | |
598 | ip->curx = 0; | |
599 | else | |
600 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
601 | break; | |
602 | ||
603 | case '\t': | |
604 | if (ip->curx < TABEND(unit)) { | |
605 | n = TABSIZE - (ip->curx & (TABSIZE - 1)); | |
606 | ip->curx += n; | |
607 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
608 | } else | |
609 | itecheckwrap(ip, sp); | |
610 | break; | |
611 | ||
612 | case CTRL('G'): | |
613 | if (&ite_tty[unit] == kbd_tty) | |
7b7da76f | 614 | kbdbell(unit); |
60f56dfc KM |
615 | break; |
616 | ||
617 | case ESC: | |
618 | ip->escape = ESC; | |
619 | break; | |
620 | ||
621 | default: | |
622 | if (c < ' ' || c == DEL) | |
623 | break; | |
624 | if (ip->imode) | |
625 | ite_ichar(ip, sp); | |
626 | if ((ip->attribute & ATTR_INV) || attrtest(ip, ATTR_INV)) { | |
627 | attrset(ip, ATTR_INV); | |
628 | (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_INV); | |
629 | } | |
630 | else | |
631 | (*sp->ite_putc)(ip, c, ip->cury, ip->curx, ATTR_NOR); | |
632 | (*sp->ite_cursor)(ip, DRAW_CURSOR); | |
633 | itecheckwrap(ip, sp); | |
634 | break; | |
635 | } | |
636 | } | |
637 | ||
638 | itecheckwrap(ip, sp) | |
639 | register struct ite_softc *ip; | |
640 | register struct itesw *sp; | |
641 | { | |
642 | if (++ip->curx == ip->cols) { | |
643 | ip->curx = 0; | |
644 | clr_attr(ip, ATTR_INV); | |
645 | if (++ip->cury == ip->rows) { | |
646 | --ip->cury; | |
647 | (*sp->ite_scroll)(ip, 1, 0, 1, SCROLL_UP); | |
648 | ite_clrtoeol(ip, sp, ip->cury, 0); | |
649 | return; | |
650 | } | |
651 | } | |
652 | (*sp->ite_cursor)(ip, MOVE_CURSOR); | |
653 | } | |
654 | ||
655 | ite_dchar(ip, sp) | |
656 | register struct ite_softc *ip; | |
657 | register struct itesw *sp; | |
658 | { | |
659 | (*sp->ite_scroll)(ip, ip->cury, ip->curx + 1, 1, SCROLL_LEFT); | |
660 | attrmov(ip, ip->cury, ip->curx + 1, ip->cury, ip->curx, | |
661 | 1, ip->cols - ip->curx - 1); | |
662 | attrclr(ip, ip->cury, ip->cols - 1, 1, 1); | |
663 | (*sp->ite_putc)(ip, ' ', ip->cury, ip->cols - 1, ATTR_NOR); | |
664 | (*sp->ite_cursor)(ip, DRAW_CURSOR); | |
665 | } | |
666 | ||
667 | ite_ichar(ip, sp) | |
668 | register struct ite_softc *ip; | |
669 | register struct itesw *sp; | |
670 | { | |
671 | (*sp->ite_scroll)(ip, ip->cury, ip->curx, 1, SCROLL_RIGHT); | |
672 | attrmov(ip, ip->cury, ip->curx, ip->cury, ip->curx + 1, | |
673 | 1, ip->cols - ip->curx - 1); | |
674 | attrclr(ip, ip->cury, ip->curx, 1, 1); | |
675 | (*sp->ite_putc)(ip, ' ', ip->cury, ip->curx, ATTR_NOR); | |
676 | (*sp->ite_cursor)(ip, DRAW_CURSOR); | |
677 | } | |
678 | ||
679 | ite_dline(ip, sp) | |
680 | register struct ite_softc *ip; | |
681 | register struct itesw *sp; | |
682 | { | |
683 | (*sp->ite_scroll)(ip, ip->cury + 1, 0, 1, SCROLL_UP); | |
684 | attrmov(ip, ip->cury + 1, 0, ip->cury, 0, | |
685 | ip->rows - ip->cury - 1, ip->cols); | |
686 | ite_clrtoeol(ip, sp, ip->rows - 1, 0); | |
687 | } | |
688 | ||
689 | ite_iline(ip, sp) | |
690 | register struct ite_softc *ip; | |
691 | register struct itesw *sp; | |
692 | { | |
693 | (*sp->ite_scroll)(ip, ip->cury, 0, 1, SCROLL_DOWN); | |
694 | attrmov(ip, ip->cury, 0, ip->cury + 1, 0, | |
695 | ip->rows - ip->cury - 1, ip->cols); | |
696 | ite_clrtoeol(ip, sp, ip->cury, 0); | |
697 | } | |
698 | ||
699 | ite_clrtoeol(ip, sp, y, x) | |
700 | register struct ite_softc *ip; | |
701 | register struct itesw *sp; | |
702 | register int y, x; | |
703 | { | |
704 | (*sp->ite_clear)(ip, y, x, 1, ip->cols - x); | |
705 | attrclr(ip, y, x, 1, ip->cols - x); | |
706 | (*sp->ite_cursor)(ip, DRAW_CURSOR); | |
707 | } | |
708 | ||
709 | ite_clrtoeos(ip, sp) | |
710 | register struct ite_softc *ip; | |
711 | register struct itesw *sp; | |
712 | { | |
713 | (*sp->ite_clear)(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); | |
714 | attrclr(ip, ip->cury, 0, ip->rows - ip->cury, ip->cols); | |
715 | (*sp->ite_cursor)(ip, DRAW_CURSOR); | |
716 | } | |
717 | ||
718 | /* | |
719 | * Console functions | |
720 | */ | |
38a01dbe | 721 | #include <hp/dev/cons.h> |
7b7da76f | 722 | #ifdef hp300 |
38a01dbe | 723 | #include <hp/dev/grfreg.h> |
7b7da76f | 724 | #endif |
60f56dfc KM |
725 | |
726 | #ifdef DEBUG | |
727 | /* | |
728 | * Minimum ITE number at which to start looking for a console. | |
729 | * Setting to 0 will do normal search, 1 will skip first ITE device, | |
730 | * NITE will skip ITEs and use serial port. | |
731 | */ | |
732 | int whichconsole = 0; | |
733 | #endif | |
734 | ||
735 | itecnprobe(cp) | |
736 | struct consdev *cp; | |
737 | { | |
738 | register struct ite_softc *ip; | |
7b7da76f | 739 | int i, sw, maj, unit, pri; |
60f56dfc KM |
740 | |
741 | /* locate the major number */ | |
742 | for (maj = 0; maj < nchrdev; maj++) | |
743 | if (cdevsw[maj].d_open == iteopen) | |
744 | break; | |
745 | ||
746 | /* urk! */ | |
747 | grfconfig(); | |
748 | ||
749 | /* check all the individual displays and find the best */ | |
750 | unit = -1; | |
751 | pri = CN_DEAD; | |
752 | for (i = 0; i < NITE; i++) { | |
753 | struct grf_softc *gp = &grf_softc[i]; | |
754 | ||
755 | ip = &ite_softc[i]; | |
756 | if ((gp->g_flags & GF_ALIVE) == 0) | |
757 | continue; | |
758 | ip->flags = (ITE_ALIVE|ITE_CONSOLE); | |
759 | ||
7b7da76f MH |
760 | /* locate the proper switch table. */ |
761 | for (sw = 0; sw < nitesw; sw++) | |
762 | if (itesw[sw].ite_hwid == gp->g_sw->gd_hwid) | |
763 | break; | |
60f56dfc | 764 | |
7b7da76f MH |
765 | if (sw == nitesw) |
766 | continue; | |
60f56dfc KM |
767 | #ifdef DEBUG |
768 | if (i < whichconsole) | |
769 | continue; | |
770 | #endif | |
7b7da76f MH |
771 | ip->isw = &itesw[sw]; |
772 | ip->grf = gp; | |
773 | #ifdef hp300 | |
60f56dfc KM |
774 | if ((int)gp->g_display.gd_regaddr == GRFIADDR) { |
775 | pri = CN_INTERNAL; | |
776 | unit = i; | |
777 | } else if (unit < 0) { | |
778 | pri = CN_NORMAL; | |
779 | unit = i; | |
780 | } | |
7b7da76f MH |
781 | #endif |
782 | #ifdef hp800 | |
783 | /* XXX use the first one for now */ | |
784 | if (unit < 0) { | |
785 | pri = CN_INTERNAL; | |
786 | unit = i; | |
787 | } | |
788 | #endif | |
60f56dfc KM |
789 | } |
790 | ||
791 | /* initialize required fields */ | |
792 | cp->cn_dev = makedev(maj, unit); | |
793 | cp->cn_tp = &ite_tty[unit]; | |
794 | cp->cn_pri = pri; | |
795 | } | |
796 | ||
797 | itecninit(cp) | |
798 | struct consdev *cp; | |
799 | { | |
800 | int unit = UNIT(cp->cn_dev); | |
801 | struct ite_softc *ip = &ite_softc[unit]; | |
802 | ||
803 | ip->attrbuf = console_attributes; | |
804 | iteinit(cp->cn_dev); | |
805 | ip->flags |= (ITE_ACTIVE|ITE_ISCONS); | |
806 | kbd_tty = &ite_tty[unit]; | |
807 | } | |
808 | ||
809 | /*ARGSUSED*/ | |
810 | itecngetc(dev) | |
811 | dev_t dev; | |
812 | { | |
813 | register int c; | |
814 | int stat; | |
815 | ||
7b7da76f | 816 | c = kbdgetc(0, &stat); /* XXX always read from keyboard 0 for now */ |
60f56dfc KM |
817 | switch ((stat >> KBD_SSHIFT) & KBD_SMASK) { |
818 | case KBD_SHIFT: | |
819 | c = kbd_shiftmap[c & KBD_CHARMASK]; | |
820 | break; | |
821 | case KBD_CTRL: | |
822 | c = kbd_ctrlmap[c & KBD_CHARMASK]; | |
823 | break; | |
824 | case KBD_KEY: | |
825 | c = kbd_keymap[c & KBD_CHARMASK]; | |
826 | break; | |
827 | default: | |
828 | c = 0; | |
829 | break; | |
830 | } | |
831 | return(c); | |
832 | } | |
833 | ||
834 | itecnputc(dev, c) | |
835 | dev_t dev; | |
836 | int c; | |
837 | { | |
838 | static int paniced = 0; | |
839 | struct ite_softc *ip = &ite_softc[UNIT(dev)]; | |
60f56dfc KM |
840 | |
841 | if (panicstr && !paniced && | |
842 | (ip->flags & (ITE_ACTIVE|ITE_INGRF)) != ITE_ACTIVE) { | |
843 | (void) iteon(dev, 3); | |
844 | paniced = 1; | |
845 | } | |
846 | iteputchar(c, dev); | |
847 | } | |
848 | #endif |