Use balloc to extend Ifile.
[unix-history] / usr / src / sys / news3400 / bm / vt100.c
CommitLineData
af5295ff
KM
1/*
2 * Copyright (c) 1992 The Regents of the University of California.
3 * All rights reserved.
4 *
5 * This code is derived from software contributed to Berkeley by
6 * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
7 *
8 * %sccs.include.redist.c%
9 *
10 * from: $Hdr: vt100.c,v 4.300 91/06/09 06:14:56 root Rel41 $ SONY
11 *
6d429c8e 12 * @(#)vt100.c 7.2 (Berkeley) %G%
af5295ff
KM
13 */
14
15#include "../include/fix_machine_type.h"
16
17#include "types.h"
18#include "param.h"
6d429c8e 19#include "systm.h"
af5295ff
KM
20#include "../iop/framebuf.h"
21#include "../iop/kbreg.h"
22#include "../iop/keyboard.h"
23#include "../fb/fbdefs.h"
24#include "../bm/vt100.h"
25#include "../bm/bitmapif.h"
26
27#ifdef IPC_MRX
28#include "config.h"
29#define kbd_ioctl(chan, cmd, argp) { \
30 if (kb_ioctl) \
31 (*kb_ioctl)(chan, cmd, argp); \
32}
33#endif
34
35#ifdef IPC_MRX
36#include "mrx.h"
37#include "process.h"
38#include "object.h"
39#include "console.h"
40#endif
41
42#ifdef CPU_SINGLE
43#include "../sio/scc.h"
44#endif
45
46extern Key_string key_str;
47extern int tmode;
48static unsigned int first_code;
49
50#ifdef IPC_MRX
51#define SCC_KEYBOARD 0
52#endif
53
54SCREEN screen;
55struct cursor inner_buf_csr;
56int inner_buf_tstat;
57char c_pos_mess[C_MESS_SIZ];
58extern struct csr_buf local_csr_buf;
59
60#ifdef IPC_MRX
61int bitmap_use;
62#ifdef IPC_3CPU
63#include "../../ubdev/msgio.h"
64extern int ipc_ready;
65#endif /* IPC_3CPU */
66extern struct cons_devsw vt100_cons;
67#endif /* IPC_MRX */
68
69#ifdef CPU_DOUBLE
70int auto_dimmer();
71#endif
72
73#if CPU_SINGLE
74extern int hz;
75extern kbd_profun_init();
76#endif
77
78lRectangle char_r1;
79lRectangle font_r1;
80lRectangle char_r2;
81lRectangle font_r2;
82
83int font_len1;
84int font_len2;
85
86int fcolor;
87int bcolor;
88
89int font_w;
90int font_h;
91int char_w;
92int char_h;
93int scr_w;
94int scr_h;
95int ch_pos;
96int ul_pos;
97int x_ofst;
98int y_ofst;
99int rit_m;
100int btm_m;
101int bell_len;
102int dim_cnt;
103int a_dim_on;
104
105unsigned short fbuf[256];
106int fp;
107int fpn;
108lPoint fpp;
109int fpa;
110
111vt100init()
112{
113 register int i;
114 register SCREEN *sp = &screen;
115
116 sp->s_term_mode = 0;
117 sp->s_term_mode |= (SRM|DECSCLM|DECAWM|DECARM|DECCSR_ACTV);
118 sp->s_current_stat = 0;
119 sp->s_csr.csr_x = 1;
120 sp->s_csr.csr_y = 1;
121 sp->s_csr.csr_p.x = x_ofst;
122 sp->s_csr.csr_p.y = y_ofst;
123 sp->s_csr.csr_attributes = NORMALM;
124 sp->s_region.top_margin = TOP_M;
125 sp->s_region.btm_margin = btm_m;
126 sp->s_plane = consfb->planemask;
127 sp->s_bgcol = 0;
128 fcolor = sp->s_plane;
129 bcolor = sp->s_bgcol;
130 for (i = 0; i < RIT_M_MAX; i++)
131 sp->s_tab_pos[i] = 0;
132 for (i = 9; i < RIT_M_MAX; i +=8)
133 sp->s_tab_pos[i] = 1;
134
135 esc_store_csr(sp);
136 inner_buf_tstat = sp->s_term_mode & (DECOM|DECAWM);
137 local_csr_buf.csr_number = 1;
138
139 cursor_on(&sp->s_csr.csr_p);
140}
141
142ncp_str(p, q, n)
143 register char *p, *q;
144 register int n;
145{
146 while (n-- > 0)
147 *q++ = *p++;
148}
149
150/*
151 * default parameter set
152 */
153set_default_param()
154{
155 register struct fbdev *cfb = consfb;
156
157 font_w = cfb->font_w;
158 font_h = cfb->font_h;
159 char_w = cfb->char_w;
160 char_h = cfb->char_h;
161 scr_w = cfb->scr_w;
162 scr_h = cfb->scr_h;
163 ch_pos = cfb->ch_pos;
164 ul_pos = cfb->ul_pos;
165 x_ofst = cfb->x_offset;
166 y_ofst = cfb->y_offset;
167 rit_m = cfb->rit_m;
168 btm_m = cfb->btm_m;
169 a_dim_on = 1;
170
171 font_r1.extent.x = font_w;
172 font_r1.extent.y = font_h;
173 font_r2.extent.x = font_w * 2;
174 font_r2.extent.y = font_h;
175 font_len1 = (font_w + 0x0f) >> 4;
176 font_len2 = (font_w*2 + 0x0f) >> 4;
177 char_r1.extent.x = char_w;
178 char_r1.extent.y = char_h;
179 char_r2.extent.x = char_w * 2;
180 char_r2.extent.y = char_h;
181
182 dim_cnt = DIM_CNT_DFLT;
183 bell_len = BELL_LEN_DFLT;
184}
185
186vt100_open()
187{
188 static int only_one = 0;
189 extern char **ext_fnt_addr;
190
191 set_default_param();
192 vt100init();
193 bitmapinit();
194 if (only_one == 0) {
195#ifdef IPC_MRX
196#ifdef IPC_3CPU
197 while (ipc_ready == 0)
198 proc_sleep_self(100);
199#endif
200 while ((bitmap_use = object_query(BITMAP)) <= 0)
201 proc_sleep_self(100);
202
203 proc_create("auto_dimmer", auto_dimmer, 401, 512, 0);
204#endif /* IPC_MRX */
205 only_one = 1;
206 }
207#define INIT_STRING "\033[42;1H"
208 vt100_write(0, INIT_STRING, sizeof(INIT_STRING) - 1);
209#ifdef CPU_SINGLE
210 kbd_open(SCC_KEYBOARD);
211#endif
212}
213
214#ifdef IPC_MRX
215vt100_cons_setup()
216{
217 int vt100_open(), vt100_read(), vt100_write(), vt100_ioctl();
218
219 vt100_cons.open = vt100_open;
220 vt100_cons.read = vt100_read;
221 vt100_cons.write = vt100_write;
222 vt100_cons.ioctl = vt100_ioctl;
223}
224
225#define DIMMER_RESET 0
226#define DIMMER_ON 1
227#define DIMMER_OFF 2
228#define DIMMER_INTERVAL 60 /* sec */
229
230static int dimmer_stdport;
231
232auto_dimmer()
233{
234 register int select, i;
235 register int dimm_counter = DIM_CNT_DFLT;
236 register int dimm_level = 0;
237 int ports[2], *mode;
238
239 spl0();
240 ports[0] = dimmer_stdport = STDPORT;
241 ports[1] = port_create("auto_dimmer_sub");
242 register_interval(ports[1], DIMMER_INTERVAL);
243 for(;;) {
244 select = msg_select(2, ports);
245 if (select == 0) {
246 msg_recv(ports[0], NULL, &mode, NULL, 0);
247 switch (*mode) {
248 case DIMMER_RESET:
249 if (!a_dim_on)
250 break;
251 dimm_counter = dim_cnt;
252 if (dimm_level > 0) {
253 dimm_level =0;
254 for (i = 0; i < nfbdev; i++)
255 fbbm_set_dimmer(&fbdev[i], 0);
256 }
257 break;
258 case DIMMER_ON:
259 dimm_counter = dim_cnt;
260 dimm_level =0;
261 for (i = 0; i < nfbdev; i++)
262 fbbm_set_dimmer(&fbdev[i], dimm_level);
263 a_dim_on = 1;
264 break;
265 case DIMMER_OFF:
266 dimm_counter = dim_cnt;
267 dimm_level =0;
268 for (i = 0; i < nfbdev; i++)
269 fbbm_set_dimmer(&fbdev[i], dimm_level);
270 a_dim_on = 0;
271 break;
272 }
273 } else {
274 msg_recv(ports[1], NULL, NULL, NULL, 0);
275 if (a_dim_on && (dimm_counter-- <= 0)) {
276 if (dimm_level < 3) {
277 dimm_level++;
278 }
279 for (i = 0; i < nfbdev; i++)
280 fbbm_set_dimmer(&fbdev[i], dimm_level);
281 dimm_counter = dim_cnt;
282 }
283 }
284 }
285}
286
287rst_dimmer_cnt()
288{
289 register int diff;
290 static unsigned last_time;
291 extern unsigned sys_time;
292 int mode = DIMMER_RESET;
293
294 diff = sys_time - last_time;
295 if (diff > DIMMER_INTERVAL*HZ || diff < 0) {
296 dimmer(DIMMER_RESET);
297 last_time = sys_time;
298 }
299}
300
301auto_dimmer_on()
302{
303 dimmer(DIMMER_ON);
304}
305
306auto_dimmer_off()
307{
308 dimmer(DIMMER_OFF);
309}
310
311dimmer(mode)
312 int mode;
313{
314 if (dimmer_stdport)
315 msg_send(dimmer_stdport, 0, &mode, sizeof(mode), 0);
316}
317#else /* IPC_MRX */
318
319static int dimmer_counter = DIM_CNT_DFLT;
320static int dim_level = 0;
321
322#ifdef CPU_SINGLE
323auto_dimmer()
324{
325 register int s, i;
326
327 s = spl4();
328 if (a_dim_on && (dimmer_counter-- <= 0)) {
329 if (dim_level < 3)
330 dim_level++;
331 for (i = 0; i < nfbdev; i++)
332 fbbm_set_dimmer(&fbdev[i], dim_level);
333 dimmer_counter = dim_cnt;
334 }
335 splx(s);
336 timeout(auto_dimmer, (caddr_t) 0, 60 * hz);
337}
338#endif
339
340rst_dimmer_cnt()
341{
342 register int s, i;
343
344 if (!a_dim_on)
345 return;
346#ifdef CPU_SINGLE
347 s = spl4();
348#endif
349 dimmer_counter = dim_cnt;
350
351 if (dim_level > 0) {
352 dim_level =0;
353 for (i = 0; i < nfbdev; i++)
354 fbbm_set_dimmer(&fbdev[i], 0);
355 }
356 splx(s);
357}
358
359auto_dimmer_on()
360{
361 register int s, i;
362
363#ifdef CPU_SINGLE
364 s = spl4();
365#endif
366 dimmer_counter = dim_cnt;
367 dim_level =0;
368 for (i = 0; i < nfbdev; i++)
369 fbbm_set_dimmer(&fbdev[i], dim_level);
370 a_dim_on = 1;
371 splx(s);
372}
373
374auto_dimmer_off()
375{
376 register int s, i;
377
378#ifdef CPU_SINGLE
379 s = spl4();
380#endif
381 dimmer_counter = dim_cnt;
382 dim_level =0;
383 for (i = 0; i < nfbdev; i++)
384 fbbm_set_dimmer(&fbdev[i], dim_level);
385 a_dim_on = 0;
386 splx(s);
387}
388#endif /* IPC_MRX */
389/*
390 * The routine `_putc(sp, c)' only prints a character c with the cursor
391 * attributes by using `copy_char(x, y, c, attributes)'.
392 * And when IRM (terminal insertion-replacement mode) is set, the characters
393 * righthand side of the cursor are shifted right and lost when they passed
394 * beyond the right margin.
395 * The position is specified by the sp pointer of the structure SCREEN.
396 *
397 */
398static
399_putc(sp, c, kanji)
400 register SCREEN *sp;
401 unsigned int c;
402{
403 if (sp->s_term_mode & IRM) {
404 vt_flush(&(sp->s_csr));
405 move_chars(sp->s_csr.csr_x, sp->s_csr.csr_y,
406 rit_m - sp->s_csr.csr_x - ((kanji)? 1: 0),
407 sp->s_csr.csr_x + ((kanji) ? 2: 1));
408 copy_char(sp, c, kanji);
409 }
410 if (fp) {
411 fbuf[fp++] = c;
412 fpn += kanji + 1;
413 } else {
414 fbuf[fp++] = c;
415 fpp = sp->s_csr.csr_p;
416 fpa = sp->s_csr.csr_attributes;
417 fpn = kanji + 1;
418 }
419}
420
421/*
422 * Scroll up and down in the scroll region.
423 * New oriented line must be cleared with terminal mode, that is whether
424 * the screen is reverse mode or not.
425 */
426scroll_up(top, bottom, revsw, fcol, bcol)
427 int top;
428 int bottom;
429 int revsw;
430 int fcol;
431 int bcol;
432{
433 move_lines(top + 1, bottom - top, top);
434 clear_lines(bottom, 1, revsw, fcol, bcol);
435}
436
437scroll_down(top, bottom, revsw, fcol, bcol)
438 int top;
439 int bottom;
440 int revsw;
441 int fcol;
442 int bcol;
443{
444 move_lines(top, bottom - top, top + 1);
445 clear_lines(top, 1, revsw, fcol, bcol);
446}
447
448/*
449 * Back space
450 * back_space(sp) moves cursor next to left at current cursor position.
451 * The cursor can not move beyond left or right margin.
452 */
453back_space(sp)
454 register SCREEN *sp;
455{
456 register struct cursor *spc = &sp->s_csr;
457
458 cursor_off();
459 if (spc->csr_x > LFT_M) {
460 spc->csr_x -= 1;
461 spc->csr_p.x -= char_w;
462 }
463 cursor_on(&spc->csr_p);
464}
465
466/*
467 * Tab stop
468 * next_tab_stop(sp) moves cursor to next tab stop.
469 */
470next_tab_stop(sp)
471 register SCREEN *sp;
472{
473 register int i;
474
475 cursor_off();
476 for (i = sp->s_csr.csr_x + 1; i < rit_m; i++)
477 if (sp->s_tab_pos[i] == 1)
478 break;
6d429c8e 479 sp->s_csr.csr_x = min(i, rit_m);
af5295ff
KM
480 sp->s_csr.csr_p.x = (sp->s_csr.csr_x - 1) * char_w + x_ofst;
481 cursor_on(&sp->s_csr.csr_p);
482}
483
484/*
485 * Carriage return
486 * carriage_ret(sp) moves cursor at beginning of the current line.
487 */
488carriage_ret(sp)
489 register SCREEN *sp;
490{
491 cursor_off();
492 sp->s_csr.csr_x = LFT_M;
493 sp->s_csr.csr_p.x = x_ofst;
494 cursor_on(&sp->s_csr.csr_p);
495}
496
497/*
498 * Bell
499 */
500static
501bell()
502{
503#ifdef news1800
504 static int port;
505
506 if (port == 0)
507 port = port_create("port_cons_bell");
508 kbd_ioctl(port, KIOCBELL, &bell_len);
509#else
510 kbd_ioctl(SCC_KEYBOARD, KIOCBELL, &bell_len);
511#endif
512 return (0);
513}
514
515int
516Putchar(c, eob)
517 unsigned int c;
518{
519 register SCREEN *sp = &screen;
520 unsigned int sftjis_to_jis();
521
522 c &= 0xff;
523
524 if (eob) {
525 vt_flush(&(sp->s_csr));
526 return(0);
527 }
528
529 if (c == 0x1b) { /* c == esc */
530 vt_flush(&(sp->s_csr));
531 recover(sp);
532 sp->s_current_stat |= ESCAPE;
533 return;
534 } else if (sp->s_current_stat & ESCAPE) {
535 (*sp->s_esc_handler)(sp, c);
536 return;
537 } else if (sp->s_current_stat & SKANJI) {
538 c = sftjis_to_jis(first_code, c);
539 if (sp->s_current_stat & JKANJI) {
540 addch(sp, c);
541 } else {
542 sp->s_current_stat |= JKANJI;
543 addch(sp, c);
544 sp->s_current_stat &= ~JKANJI;
545 }
546 sp->s_current_stat &= ~SKANJI;
547 goto set_csr;
548 } else if (sp->s_current_stat & EKANJI) {
549 c = (c & 0x7f) | (first_code << 8);
550 if (sp->s_current_stat & JKANJI) {
551 addch(sp, c);
552 } else {
553 sp->s_current_stat |= JKANJI;
554 addch(sp, c);
555 sp->s_current_stat &= ~JKANJI;
556 }
557 sp->s_current_stat &= ~EKANJI;
558 goto set_csr;
559 } else if (sp->s_current_stat & JKANJI) {
560 jiskanji(sp, c);
561 goto set_csr;
562 } else if (sp->s_current_stat & EKANA) {
563 sp->s_current_stat &= ~EKANA;
564 addch(sp, c);
565 goto set_csr;
566 }
567 if (c < 0x20) { /* control code */
568 vt_flush(&(sp->s_csr));
569 switch (c) {
570 case 0x00: /* ignore */
571 break;
572 case 0x07: /* bell */
573 bell();
574 break;
575 case 0x08: /* back space */
576 back_space(sp);
577 break;
578 case 0x09: /* tabulation */
579 next_tab_stop(sp);
580 break;
581 case 0x0a: /* line feed */
582 case 0x0b: /* vertical feed */
583 case 0x0c: /* form feed */
584 esc_index(sp);
585 break;
586 case 0x0d: /* carriage return */
587 carriage_ret(sp);
588 break;
589 case 0x0e: /* shift out */
590 break;
591 case 0x0f: /* shift in */
592 break;
593 case 0x11: /* xon */
594 break;
595 case 0x13: /* xoff */
596 break;
597 case 0x18: /* cancel */
598 sp->s_current_stat &= ~ESCAPE;
599 break;
600 case 0x1b: /* escape */
601 /* NOT REACHED */
602 recover(sp);
603 sp->s_current_stat |= ESCAPE;
604 break;
605 case 0x7f: /* delete */
606 break;
607
608 default:
609 break;
610 }
611 } else {
612 switch (tmode) {
613#ifdef KM_SJIS
614 case KM_SJIS:
615 if ((c >= JVR1S && c <= JVR1E) ||
616 (c >= JVR2S && c <= JVR2E)) {
617 sp->s_current_stat |= SKANJI;
618 first_code = c;
619 }
620 else
621 addch(sp, c);
622 break;
623#endif
624#ifdef KM_EUC
625 case KM_EUC:
626 if (c >= CS1S && c <= CS1E) {
627 sp->s_current_stat |= EKANJI;
628 first_code = c & 0x7f;
629 }
630 else if (c == SS2)
631 sp->s_current_stat |= EKANA;
632 else
633 addch(sp, c);
634 break;
635#endif
636#ifdef KM_JIS
637 case KM_JIS:
638#endif
639#ifdef KM_ASCII
640 case KM_ASCII:
641#endif
642 default:
643 addch(sp, c);
644 }
645 }
646
647set_csr:
648 cursor_on(&sp->s_csr.csr_p);
649 /* altered */
650 return ;
651}
652
653/*
654 * A printable character is printed in this routine by using
655 * the routine `_putc()'.
656 * Anyway, a character is printed in replacement mode or insertion
657 * mode and if the terminal is autowrap then it takes place wrapping
658 * and if cursor is bottom margin of the scroll region then it takes
659 * place scroll up.
660 * The escape sequence handling is another routine.
661 *
662 */
663addch(sp, c)
664 register SCREEN *sp;
665 unsigned int c;
666{
667 register struct cursor *spc = &(sp->s_csr);
668 register struct region *spr = &(sp->s_region);
669
670 if (spc->csr_x >= rit_m ||
671 ((sp->s_current_stat & JKANJI) && (spc->csr_x >= rit_m - 1))) {
672 vt_flush(spc);
673 if (sp->s_term_mode & DECAWM) {
674 if ((sp->s_current_stat & WRAP) || (spc->csr_x == rit_m
675 && sp->s_current_stat & JKANJI)) {
676 if (spc->csr_y == spr->btm_margin) {
677 cursor_off();
678 scroll_up(spr->top_margin,
679 spr->btm_margin,
680 sp->s_term_mode & DECSCNM,
681 sp->s_plane, sp->s_bgcol);
682 cursor_on(&(spc->csr_p));
683 } else if (spc->csr_y < btm_m) {
684 spc->csr_y += 1;
685 spc->csr_p.y += char_h;
686 }
687 spc->csr_x = LFT_M;
688 spc->csr_p.x = x_ofst;
689 addch(sp, c);
690 return;
691 }
692 sp->s_current_stat |= WRAP;
693 }
694 if (sp->s_current_stat & JKANJI) {
695 if (spc->csr_x != rit_m) {
696 _putc(sp, c, 1);
697 }
698 } else {
699 _putc(sp, c, 0);
700 }
701 if (spc->csr_x < rit_m) {
702 spc->csr_x += 1;
703 spc->csr_p.x += char_w;
704 }
705
706 return ;
707 }
708 if (sp->s_current_stat & JKANJI) {
709 _putc(sp, c, 1);
710 spc->csr_x++;
711 spc->csr_p.x += char_w;
712 } else {
713 _putc(sp, c, 0);
714 }
715
716 spc->csr_x++; /* altered */
717 spc->csr_p.x += char_w;
718
719 sp->s_current_stat &= ~WRAP;
720 return ;
721}