xref: /csrg-svn/sys/news3400/bm/vt100esc.c (revision 57177)
153889Smckusick /*
253889Smckusick  * Copyright (c) 1992 The Regents of the University of California.
353889Smckusick  * All rights reserved.
453889Smckusick  *
553889Smckusick  * This code is derived from software contributed to Berkeley by
653889Smckusick  * Sony Corp. and Kazumasa Utashiro of Software Research Associates, Inc.
753889Smckusick  *
853889Smckusick  * %sccs.include.redist.c%
953889Smckusick  *
1053889Smckusick  * from: $Hdr: vt100esc.c,v 4.300 91/06/09 06:14:59 root Rel41 $ SONY
1153889Smckusick  *
12*57177Sutashiro  *	@(#)vt100esc.c	7.4 (Berkeley) 12/17/92
1353889Smckusick  */
1453889Smckusick 
1553889Smckusick /*
1653889Smckusick  *  vt100 escape sequence handler
1753889Smckusick  */
1853889Smckusick 
19*57177Sutashiro #include <machine/fix_machine_type.h>
2053889Smckusick 
2153889Smckusick #ifdef IPC_MRX
2253889Smckusick #include "../../h/param.h"
2355762Sbostic #include "../../h/systm.h"
2453889Smckusick #include "../../iop/framebuf.h"
2553889Smckusick #else
26*57177Sutashiro #include <sys/param.h>
27*57177Sutashiro #include <sys/systm.h>
28*57177Sutashiro #include <news3400/iop/framebuf.h>
2953889Smckusick #endif
3053889Smckusick 
31*57177Sutashiro #include <news3400/bm/vt100.h>
32*57177Sutashiro #include <news3400/bm/bitmapif.h>
3353889Smckusick 
34*57177Sutashiro #include <news3400/fb/fbdefs.h>
3553889Smckusick 
3653889Smckusick #ifdef IPC_MRX
3753889Smckusick #include "../../iop/kbreg.h"
3853889Smckusick #include "../../iop/keyboard.h"
3953889Smckusick #else
40*57177Sutashiro #include <news3400/iop/kbreg.h>
41*57177Sutashiro #include <news3400/iop/keyboard.h>
4253889Smckusick #endif
4353889Smckusick 
4453889Smckusick #if CPU_SINGLE
45*57177Sutashiro #include <news3400/sio/scc.h>
4653889Smckusick #endif
4753889Smckusick 
4853889Smckusick #ifdef IPC_MRX
4953889Smckusick #include "config.h"
5053889Smckusick #define kbd_ioctl(chan, cmd, argp) { \
5153889Smckusick 	if (kb_ioctl) \
5253889Smckusick 		(*kb_ioctl)(chan, cmd, argp); \
5353889Smckusick }
5453889Smckusick #endif
5553889Smckusick 
5653889Smckusick /*
5753889Smckusick  *  escape sequece functions
5853889Smckusick  */
5953889Smckusick int	esc_csi();
6053889Smckusick int	esc_csi_ansi();
6153889Smckusick int	esc_csi_dec();
6253889Smckusick int	esc_store_csr();
6353889Smckusick int	esc_restore_csr();
6453889Smckusick int	esc_index();
6553889Smckusick int	esc_next_line();
6653889Smckusick int	esc_tab_set();
6753889Smckusick int	esc_rev_index();
6853889Smckusick int	esc_numeric_kpad();
6953889Smckusick int	esc_application_kpad();
7053889Smckusick int	esc_line_size();
7153889Smckusick int	esc_char_setr();
7253889Smckusick int	esc_char_setl();
7353889Smckusick int	esc_kanji_set();
7453889Smckusick int	esc_parm_set();
7553889Smckusick int	esc_pf_define();
7653889Smckusick int	esc_ignore();
7753889Smckusick 
7853889Smckusick struct  esc_sequence esc_seq_table[] = {
7953889Smckusick 	{'[', "ABCDfgHhJKLlMmnPr", esc_csi},
8053889Smckusick 	{'7', "", esc_store_csr},
8153889Smckusick 	{'8', "", esc_restore_csr},
8253889Smckusick 	{'D', "", esc_index},
8353889Smckusick 	{'E', "", esc_next_line},
8453889Smckusick 	{'H', "", esc_tab_set},
8553889Smckusick 	{'M', "", esc_rev_index},
8653889Smckusick 	{'=', "", esc_application_kpad},
8753889Smckusick 	{'>', "", esc_numeric_kpad},
8853889Smckusick 	{'#', "34568", esc_line_size},
8953889Smckusick 	{'(', "0ABJH", esc_char_setr},
9053889Smckusick 	{')', "0AB", esc_char_setl},
9153889Smckusick 	{'$', "B@", esc_kanji_set},
9253889Smckusick 	{'~', "fcpsomdbDiGCBTtE", esc_parm_set},
9353889Smckusick 	{'P', "pPZiI", esc_pf_define},
9453889Smckusick 	{'\0', "", esc_ignore},
9553889Smckusick };
9653889Smckusick 
9753889Smckusick struct	key_pad	key_pad[] = {
9853889Smckusick 	{ '0', 'p' },	/*	0	*/
9953889Smckusick 	{ '1', 'q' },	/*	1	*/
10053889Smckusick 	{ '2', 'r' },	/*	2	*/
10153889Smckusick 	{ '3', 's' },	/*	3	*/
10253889Smckusick 	{ '4', 't' },	/*	4	*/
10353889Smckusick 	{ '5', 'u' },	/*	5	*/
10453889Smckusick 	{ '6', 'v' },	/*	6	*/
10553889Smckusick 	{ '7', 'w' },	/*	7	*/
10653889Smckusick 	{ '8', 'x' },	/*	8	*/
10753889Smckusick 	{ '9', 'y' },	/*	9	*/
10853889Smckusick 	{ '.', 'n' },	/*  period	*/
10953889Smckusick 	{ '-', 'm' },	/*  minus	*/
11053889Smckusick 	{ '+', 'k' },	/*  plus	*/
11153889Smckusick 	{ ',', 'l' },	/*  comma	*/
11253889Smckusick 	{ '\n', 'M' },	/*  enter	*/
11353889Smckusick 	{ 'A', 'A' },	/*  cursor up	*/
11453889Smckusick 	{ 'B', 'B' },	/*  cursor down	*/
11553889Smckusick 	{ 'C', 'C' },	/*  cursor right */
11653889Smckusick 	{ 'D', 'D' },	/*  cursor left	*/
11753889Smckusick 	{ '\0', '\0' }	/*	*/
11853889Smckusick };
11953889Smckusick 
12053889Smckusick static	char	esc_buf[ESC_BUF_SIZ];
12153889Smckusick static	char	*esc_bp = esc_buf;
12253889Smckusick extern	char	c_pos_mess[];
12353889Smckusick 
12457166Sutashiro static change_csr_key_pad(), change_aux_key_pad(), itoa();
12557166Sutashiro 
12653889Smckusick Key_string	key_str;
12753889Smckusick Pfk_string	pfk_str;
12853889Smckusick 
12953889Smckusick unsigned  int	first_jcode;
13053889Smckusick 
13153889Smckusick /*
13253889Smckusick  *  put out jis-code kanji
13353889Smckusick  */
13453889Smckusick jiskanji(sp, c)
13553889Smckusick 	register SCREEN *sp;
13653889Smckusick 	register unsigned int c;
13753889Smckusick {
13853889Smckusick 	if (first_jcode) {
13953889Smckusick 		addch(sp, c | (first_jcode << 8));
14053889Smckusick 		first_jcode = 0;
14153889Smckusick 	} else {
14253889Smckusick 		first_jcode = c;
14353889Smckusick 	}
14453889Smckusick }
14553889Smckusick 
14653889Smckusick /*
14753889Smckusick  *  This routine is the command analiser using second character.
14853889Smckusick  *  If a command has found then switch to particular escape handling
14953889Smckusick  *  routine, and directly called by mother routine.
15053889Smckusick  *  The arguments are passed through the routine.
15153889Smckusick  */
15253889Smckusick esc_top_level(sp, c)
15353889Smckusick 	register SCREEN	*sp;
15453889Smckusick 	char c;
15553889Smckusick {
15653889Smckusick 	register  struct  esc_sequence	*estp;
15753889Smckusick 
15853889Smckusick 	for (estp = esc_seq_table; estp->command ; estp++) {
15953889Smckusick 		if (estp->command == c) {
16053889Smckusick 					/* command found  */
16153889Smckusick 			sp->s_estp = estp;
16253889Smckusick 			if (*estp->terminators == '\0') {
16353889Smckusick 				(*estp->esc_func)(sp);
16453889Smckusick 				sp->s_current_stat &= ~ESCAPE;
16553889Smckusick 			} else {
16653889Smckusick 				sp->s_esc_handler = estp->esc_func;
16753889Smckusick 			}
16853889Smckusick 			return;
16953889Smckusick 		}
17053889Smckusick 	}
17153889Smckusick 	sp->s_current_stat &= ~ESCAPE;
17253889Smckusick }
17353889Smckusick 
17453889Smckusick /*
17553889Smckusick  *  Undo the ESCAPE flag, escape buffer
17653889Smckusick  *  and the esc_handler routine
17753889Smckusick  *  This routine has to be called when escape sequence has started.
17853889Smckusick  */
17953889Smckusick recover(sp)
18053889Smckusick 	register SCREEN *sp;
18153889Smckusick {
18253889Smckusick 	register int *ip = (int *) esc_buf;
18353889Smckusick 	register int *sup = (int *) (esc_buf + ESC_BUF_SIZ);
18453889Smckusick 
18553889Smckusick 	sp->s_current_stat &= ~ESCAPE;
18653889Smckusick 	sp->s_esc_handler = esc_top_level;
18753889Smckusick 	while (ip < sup)
18853889Smckusick 		*ip++ = 0;
18953889Smckusick 	esc_bp = esc_buf;
19053889Smckusick }
19153889Smckusick 
19253889Smckusick /*
19353889Smckusick  *  This routine in_str(c, string) returns
19453889Smckusick  *  if string contains c then TRUE (1) else FALSE (0)
19553889Smckusick  */
19653889Smckusick in_str(c, string)
19753889Smckusick 	char c;
19853889Smckusick 	register char *string;
19953889Smckusick {
20053889Smckusick 	while(*string)
20153889Smckusick 		if (c == *string++)
20253889Smckusick 			return(TRUE);
20353889Smckusick 	return(FALSE);
20453889Smckusick }
20553889Smckusick 
20653889Smckusick /*
20753889Smckusick  *  Control sequence introducer (CSI)
20853889Smckusick  *  Which begins `^[[' and terminates one of `ABCDfgHhJKLlMmPr'
20953889Smckusick  */
21053889Smckusick esc_csi(sp, c)
21153889Smckusick 	register SCREEN *sp;
21253889Smckusick 	unsigned int c;
21353889Smckusick {
21453889Smckusick 	static int bufc = 0;
21553889Smckusick 
21653889Smckusick 	if (in_str(c, sp->s_estp->terminators)) {
21753889Smckusick 		esc_csi_ansi(sp, esc_bp, c);
21853889Smckusick 		sp->s_current_stat &= ~ESCAPE;
21953889Smckusick 		bufc = 0;
22053889Smckusick 		return;
22153889Smckusick 	}
22253889Smckusick 	/*  buffering arguments  */
22353889Smckusick 	if (bufc < ESC_BUF_SIZ) {
22453889Smckusick 		if (c >= '0' && c <= '9') {
22553889Smckusick 			*esc_bp = *esc_bp *10 + (c - '0');
22653889Smckusick 		} else if (c == ';') {
22753889Smckusick 			esc_bp++;
22853889Smckusick 			bufc++;
22953889Smckusick 		} else if (c == '?') {
23053889Smckusick 			if (esc_bp == esc_buf) {
23153889Smckusick 				sp->s_esc_handler = esc_csi_dec;
23253889Smckusick 			} else {
23353889Smckusick 				esc_buf[0] = INVALID;
23453889Smckusick 			}
23553889Smckusick 		} else {
23653889Smckusick 			sp->s_current_stat &= ~ESCAPE;
23753889Smckusick 			bufc = 0;
23853889Smckusick 		}
23953889Smckusick 	}
24053889Smckusick }
24153889Smckusick 
24253889Smckusick #ifdef IPC_MRX
24353889Smckusick #define SCC_KEYBOARD	0
24453889Smckusick #endif
24553889Smckusick 
24653889Smckusick /*
24753889Smckusick  *  Ansi standard csi handler
24853889Smckusick  */
24953889Smckusick esc_csi_ansi(sp, esc_bp, terminator)
25053889Smckusick 	register SCREEN *sp;
25153889Smckusick 	char *esc_bp;
25253889Smckusick 	char terminator;
25353889Smckusick {
25453889Smckusick 	register char *cp = esc_buf;
25553889Smckusick 	register struct cursor *spc = &sp->s_csr;
25653889Smckusick 	register char *p;
25753889Smckusick 	register int i;
25853889Smckusick 
25953889Smckusick 	if (*cp == INVALID)
26053889Smckusick 		return;
26153889Smckusick 
26253889Smckusick 	cursor_off();
26353889Smckusick 	switch (terminator) {
26453889Smckusick 	case 'A':		/*  CUU	 */
26553889Smckusick 		if (spc->csr_y < sp->s_region.top_margin) {
26655762Sbostic 			spc->csr_y = max(spc->csr_y - max(*cp, 1)
26753889Smckusick 					,TOP_M);
26853889Smckusick 		} else {
26955762Sbostic 			spc->csr_y = max(spc->csr_y - max(*cp, 1)
27053889Smckusick 					,sp->s_region.top_margin);
27153889Smckusick 		}
27253889Smckusick 		spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst;
27353889Smckusick 		sp->s_current_stat &= ~WRAP;
27453889Smckusick 		break;
27553889Smckusick 	case 'B':		/*  CUD	 */
27653889Smckusick 		if (spc->csr_y > sp->s_region.btm_margin) {
27755762Sbostic 			spc->csr_y = min(spc->csr_y + max(*cp, 1)
27853889Smckusick 					,btm_m);
27953889Smckusick 		} else {
28055762Sbostic 			spc->csr_y = min(spc->csr_y + max(*cp, 1)
28153889Smckusick 					,sp->s_region.btm_margin);
28253889Smckusick 		}
28353889Smckusick 		spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst;
28453889Smckusick 		sp->s_current_stat &= ~WRAP;
28553889Smckusick 		break;
28653889Smckusick 	case 'C':		/*  CUF	 */
28755762Sbostic 		spc->csr_x = min(spc->csr_x + max(*cp, 1), rit_m);
28853889Smckusick 		spc->csr_p.x = (spc->csr_x - 1) * char_w + x_ofst;
28953889Smckusick 		sp->s_current_stat &= ~WRAP;
29053889Smckusick 		break;
29153889Smckusick 	case 'D':		/*  CUB	 */
29255762Sbostic 		spc->csr_x = max(spc->csr_x - max(*cp, 1), LFT_M);
29353889Smckusick 		spc->csr_p.x = (spc->csr_x - 1) * char_w + x_ofst;
29453889Smckusick 		sp->s_current_stat &= ~WRAP;
29553889Smckusick 		break;
29653889Smckusick 	case 'g':		/*  TBC	 */
29753889Smckusick 		switch (*cp) {
29853889Smckusick 		case 0:
29953889Smckusick 			sp->s_tab_pos[spc->csr_x] = 0;
30053889Smckusick 			break;
30153889Smckusick 		case 3:
30253889Smckusick 			for (i = 0; i <= rit_m; i++)
30353889Smckusick 				sp->s_tab_pos[i] = 0;
30453889Smckusick 			break;
30553889Smckusick 		default:
30653889Smckusick 			break;
30753889Smckusick 		}
30853889Smckusick 		break;
30953889Smckusick 	case 'f':		/*  HVP	 */
31053889Smckusick 	case 'H':		/*  CUP  same as HVP	*/
31153889Smckusick 		csr_pos(sp, cp[1], cp[0]);
31253889Smckusick 		sp->s_current_stat &= ~WRAP;
31353889Smckusick 		break;
31453889Smckusick 	case 'J':		/*  ED	*/
31553889Smckusick 		erase_disp(sp, cp[0]);
31653889Smckusick 		sp->s_current_stat &= ~WRAP;
31753889Smckusick 		break;
31853889Smckusick 	case 'K':		/*  EL	*/
31953889Smckusick 		erase_line(sp, cp[0]);
32053889Smckusick 		sp->s_current_stat &= ~WRAP;
32153889Smckusick 		break;
32253889Smckusick 	case 'L':		/*  IL	*/
32353889Smckusick 		insert_line(sp, cp[0]);
32453889Smckusick 		break;
32553889Smckusick 	case 'M':		/*  DL	*/
32653889Smckusick 		delete_line(sp, cp[0]);
32753889Smckusick 		break;
32853889Smckusick 	case 'P':		/*  DCH	 */
32953889Smckusick 		delete_char(sp, cp[0]);
33053889Smckusick 		sp->s_current_stat &= ~WRAP;
33153889Smckusick 		break;
33253889Smckusick 	case 'r':		/*  DECSTBM	*/
33355762Sbostic 		cp[2] = max(cp[0] == 0 ? TOP_M: cp[0], TOP_M);
33455762Sbostic 		cp[3] = min(cp[1] == 0 ? btm_m: cp[1], btm_m);
33553889Smckusick 		if (cp[2] >= cp[3])
33653889Smckusick 			break;
33753889Smckusick 
33853889Smckusick 		sp->s_region.top_margin = cp[2];
33953889Smckusick 		sp->s_region.btm_margin = cp[3];
34053889Smckusick 
34153889Smckusick 		spc->csr_x = LFT_M;
34253889Smckusick 		spc->csr_p.x = x_ofst;
34353889Smckusick 		if (sp->s_term_mode & DECOM) {
34453889Smckusick 			spc->csr_y = sp->s_region.top_margin;
34553889Smckusick 			spc->csr_p.y = (spc->csr_y - 1) * char_h + y_ofst;
34653889Smckusick 		} else {
34753889Smckusick 			spc->csr_y = TOP_M;
34853889Smckusick 			spc->csr_p.y = y_ofst;
34953889Smckusick 		}
35053889Smckusick 		break;
35153889Smckusick 	case 'm':		/*  CRA	 */
35253889Smckusick 		while (cp <= esc_bp) {
35353889Smckusick 			switch (*cp++) {
35453889Smckusick 			case 0:
35553889Smckusick 				spc->csr_attributes &= NORMALM;
35653889Smckusick 				if (sp->s_term_mode & DECSCNM) {
35753889Smckusick 					fcolor = sp->s_bgcol;
35853889Smckusick 					bcolor = sp->s_plane;
35953889Smckusick 				}
36053889Smckusick 				else {
36153889Smckusick 					fcolor = sp->s_plane;
36253889Smckusick 					bcolor = sp->s_bgcol;
36353889Smckusick 				}
36453889Smckusick 				break;
36553889Smckusick 			case 1:		/*  bold	*/
36653889Smckusick 				spc->csr_attributes |= BOLD;
36753889Smckusick 				break;
36853889Smckusick 			case 4:		/*  under score	 */
36953889Smckusick 				spc->csr_attributes |= USCORE;
37053889Smckusick 				break;
37153889Smckusick 			case 5:		/*  blinking	*/
37253889Smckusick 				spc->csr_attributes |= BLINK;
37353889Smckusick 				break;
37453889Smckusick 			case 7:		/*  reverse	*/
37553889Smckusick 				spc->csr_attributes |= REVERSE;
37653889Smckusick 				if (sp->s_term_mode & DECSCNM) {
37753889Smckusick 					fcolor = sp->s_plane;
37853889Smckusick 					bcolor = sp->s_bgcol;
37953889Smckusick 				}
38053889Smckusick 				else {
38153889Smckusick 					fcolor = sp->s_bgcol;
38253889Smckusick 					bcolor = sp->s_plane;
38353889Smckusick 				}
38453889Smckusick 				break;
38553889Smckusick 			case 22:	/*  unbold	*/
38653889Smckusick 				spc->csr_attributes &= ~BOLD;
38753889Smckusick 				break;
38853889Smckusick 			case 24:	/*  no under score	*/
38953889Smckusick 				spc->csr_attributes &= ~USCORE;
39053889Smckusick 				break;
39153889Smckusick 			case 25:	/*  no blinking	 */
39253889Smckusick 				spc->csr_attributes &= ~BLINK;
39353889Smckusick 				break;
39453889Smckusick 			case 27:	/*  re-reverse	*/
39553889Smckusick 				spc->csr_attributes &= ~REVERSE;
39653889Smckusick 				if (sp->s_term_mode & DECSCNM) {
39753889Smckusick 					fcolor = sp->s_bgcol;
39853889Smckusick 					bcolor = sp->s_plane;
39953889Smckusick 				}
40053889Smckusick 				else {
40153889Smckusick 					fcolor = sp->s_plane;
40253889Smckusick 					bcolor = sp->s_bgcol;
40353889Smckusick 				}
40453889Smckusick 				break;
40553889Smckusick 			default:
40653889Smckusick 				break;
40753889Smckusick 			}
40853889Smckusick 		}
40953889Smckusick 		break;
41053889Smckusick 	case 'n':
41153889Smckusick 		while (cp <= esc_bp) {	/*  DSR(status request)	*/
41253889Smckusick 			switch (*cp++) {
41353889Smckusick 			case 6:		/*  inquiry cursor position	*/
41453889Smckusick 				key_str.key_string = c_pos_mess;
41553889Smckusick 				key_str.key_length = spr(c_pos_mess,
41653889Smckusick 				    "\033[%d;%dR", (sp->s_term_mode & DECOM) ?
41753889Smckusick 				    spc->csr_y - sp->s_region.top_margin + 1:
41853889Smckusick 				    spc->csr_y, spc->csr_x);
41953889Smckusick 				kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
42053889Smckusick 				break;
42153889Smckusick 			default:
42253889Smckusick 				break;
42353889Smckusick 			}
42453889Smckusick 		}
42553889Smckusick 		break;
42653889Smckusick 	case 'h':		/*  SM	*/
42753889Smckusick 		while (cp <= esc_bp) {
42853889Smckusick 			switch (*cp++) {
42953889Smckusick 			case 2:		/*  Keyboard Action	*/
43053889Smckusick 				sp->s_term_mode |= KAM;
43153889Smckusick 				break;
43253889Smckusick 			case 4:		/*  Insert Replace	*/
43353889Smckusick 				sp->s_term_mode |= IRM;
43453889Smckusick 				break;
43553889Smckusick 			case 12:	/*  Local echo disable	*/
43653889Smckusick 				sp->s_term_mode |= SRM;
43753889Smckusick 				break;
43853889Smckusick 			case 20:	/*  Linefeed newline	*/
43953889Smckusick 				sp->s_term_mode |= LNM;
44053889Smckusick 				break;
44153889Smckusick 			default:
44253889Smckusick 				break;
44353889Smckusick 			}
44453889Smckusick 		}
44553889Smckusick 		break;
44653889Smckusick 	case 'l':		/*  RM	*/
44753889Smckusick 		while (cp <= esc_bp) {
44853889Smckusick 			switch (*cp++) {
44953889Smckusick 			case 2:		/*  Keyboard Action	*/
45053889Smckusick 				sp->s_term_mode &= ~KAM;
45153889Smckusick 				break;
45253889Smckusick 			case 4:		/*  Insert Replace	*/
45353889Smckusick 				sp->s_term_mode &= ~IRM;
45453889Smckusick 				break;
45553889Smckusick 			case 12:	/*  Local echo disable	*/
45653889Smckusick 				sp->s_term_mode &= ~SRM;
45753889Smckusick 				break;
45853889Smckusick 			case 20:	/*  Linefeed newline	*/
45953889Smckusick 				sp->s_term_mode &= ~LNM;
46053889Smckusick 				break;
46153889Smckusick 			default:
46253889Smckusick 				break;
46353889Smckusick 			}
46453889Smckusick 		}
46553889Smckusick 		break;
46653889Smckusick 	default:
46753889Smckusick 		break;
46853889Smckusick 	}
46953889Smckusick 	cursor_on(&spc->csr_p);
47053889Smckusick 	sp->s_current_stat &= ~ESCAPE;
47153889Smckusick }
47253889Smckusick 
47353889Smckusick 
47453889Smckusick /*
47553889Smckusick  *  Cursor position.
47653889Smckusick  *  csr_pos(sp, x, y) moves the cursor to (x, y).
47753889Smckusick  */
47853889Smckusick csr_pos(sp, x, y)
47953889Smckusick 	register SCREEN *sp;
48053889Smckusick 	register int x, y;
48153889Smckusick {
48253889Smckusick 	if (sp->s_term_mode & DECOM) {
48355762Sbostic 		sp->s_csr.csr_y = min(sp->s_region.top_margin +
48455762Sbostic 				max(y, 1) - 1, sp->s_region.btm_margin);
48553889Smckusick 	} else {
48655762Sbostic 		sp->s_csr.csr_y = min(TOP_M + max(y, 1) - 1, btm_m);
48753889Smckusick 	}
48855762Sbostic 	sp->s_csr.csr_x = max(min(x, rit_m), LFT_M);
48953889Smckusick 	sp->s_csr.csr_p.x = (sp->s_csr.csr_x -1) * char_w + x_ofst;
49053889Smckusick 	sp->s_csr.csr_p.y = (sp->s_csr.csr_y -1) * char_h + y_ofst;
49153889Smckusick }
49253889Smckusick 
49353889Smckusick 
49453889Smckusick /*
49553889Smckusick  *  Erase in display.
49653889Smckusick  *  erase_disp(sp, pn) erases display from the cursor to the end, from
49753889Smckusick  *  the beginning to the cursor or completely according to pn = 0, 1 or 2
49853889Smckusick  *  respectively.
49953889Smckusick  */
50053889Smckusick erase_disp(sp, pn)
50153889Smckusick 	register SCREEN *sp;
50253889Smckusick 	register int pn;
50353889Smckusick {
50453889Smckusick 	register  struct  cursor  *spc = &sp->s_csr;
50553889Smckusick 
50653889Smckusick 	switch (pn) {
50753889Smckusick 	case 0:		/*  cursor to end	*/
50853889Smckusick 		erase_line(sp, 0);
50955762Sbostic 		clear_lines(min(spc->csr_y + 1, btm_m),
51053889Smckusick 			btm_m - spc->csr_y, sp->s_term_mode & DECSCNM,
51153889Smckusick 			sp->s_plane, sp->s_bgcol);
51253889Smckusick 		break;
51353889Smckusick 	case 1:		/*  beginning to cursor	*/
51453889Smckusick 		erase_line(sp, 1);
51553889Smckusick 		clear_lines(TOP_M, spc->csr_y - TOP_M, sp->s_term_mode & DECSCNM,
51653889Smckusick 			sp->s_plane, sp->s_bgcol);
51753889Smckusick 		break;
51853889Smckusick 	case 2:		/*  whole	*/
51953889Smckusick 		clear_lines(TOP_M, btm_m - TOP_M + 1,
52053889Smckusick 			sp->s_term_mode & DECSCNM,
52153889Smckusick 			sp->s_plane, sp->s_bgcol);
52253889Smckusick 		break;
52353889Smckusick 	default:
52453889Smckusick 		break;
52553889Smckusick 	}
52653889Smckusick }
52753889Smckusick 
52853889Smckusick 
52953889Smckusick 
53053889Smckusick /*
53153889Smckusick  *  Erase in line.
53253889Smckusick  *  erase_line(sp, pn) erases line from the cursor to the end, from the
53353889Smckusick  *  beginning to the cursor or completely according to pn = 0, 1 or 2
53453889Smckusick  *  respectively.
53553889Smckusick  */
53653889Smckusick erase_line(sp, pn)
53753889Smckusick 	register SCREEN *sp;
53853889Smckusick 	register int pn;
53953889Smckusick {
54053889Smckusick 	register struct cursor *spc = &sp->s_csr;
54153889Smckusick 
54253889Smckusick 	switch(pn) {
54353889Smckusick 	case 0:
54453889Smckusick 		clear_chars(spc->csr_x, spc->csr_y,
54553889Smckusick 			rit_m - spc->csr_x + 1, sp->s_term_mode & DECSCNM,
54653889Smckusick 			sp->s_plane, sp->s_bgcol);
54753889Smckusick 		break;
54853889Smckusick 	case 1:
54953889Smckusick 		clear_chars(LFT_M, spc->csr_y,
55053889Smckusick 			spc->csr_x - LFT_M + 1, sp->s_term_mode & DECSCNM,
55153889Smckusick 			sp->s_plane, sp->s_bgcol);
55253889Smckusick 		break;
55353889Smckusick 	case 2:
55453889Smckusick 		clear_lines(spc->csr_y, 1, sp->s_term_mode & DECSCNM,
55553889Smckusick 			sp->s_plane, sp->s_bgcol);
55653889Smckusick 		break;
55753889Smckusick 	default:
55853889Smckusick 		break;
55953889Smckusick 	}
56053889Smckusick }
56153889Smckusick 
56253889Smckusick /*
56353889Smckusick  *  Insert line.
56453889Smckusick  *  insert_line(sp, pn) inserts pn lines in scroll region
56553889Smckusick  */
56653889Smckusick insert_line(sp, pn)
56753889Smckusick 	register SCREEN *sp;
56853889Smckusick 	register int pn;
56953889Smckusick {
57053889Smckusick 	register struct cursor *spc = &sp->s_csr;
57153889Smckusick 	register struct region *spr = &sp->s_region;
57253889Smckusick 
57355762Sbostic 	pn = max(pn, 1);
57453889Smckusick 	if (spc->csr_y < spr->top_margin || spc->csr_y > spr->btm_margin)
57553889Smckusick 		return;
57653889Smckusick 	if (pn <= spr->btm_margin - spc->csr_y) {
57753889Smckusick 		move_lines(spc->csr_y, spr->btm_margin - pn - spc->csr_y + 1,
57853889Smckusick 			spc->csr_y + pn);
57953889Smckusick 	}
58053889Smckusick 	clear_lines(spc->csr_y,
58155762Sbostic 		min(spc->csr_y + pn - 1, spr->btm_margin) - spc->csr_y + 1,
58253889Smckusick 		sp->s_term_mode & DECSCNM, sp->s_plane, sp->s_bgcol);
58353889Smckusick 	spc->csr_x = LFT_M;
58453889Smckusick 	spc->csr_p.x = x_ofst;
58553889Smckusick }
58653889Smckusick 
58753889Smckusick /*
58853889Smckusick  *  Delete line.
58953889Smckusick  *  delete_line(sp, pn) deletes pn lines in scroll region
59053889Smckusick  */
59153889Smckusick delete_line(sp, pn)
59253889Smckusick 	register SCREEN *sp;
59353889Smckusick 	register int pn;
59453889Smckusick {
59553889Smckusick 	register struct cursor *spc = &sp->s_csr;
59653889Smckusick 	register struct region *spr = &sp->s_region;
59753889Smckusick 	register int aux;
59853889Smckusick 
59955762Sbostic 	pn = max(pn, 1);
60053889Smckusick 	if (spc->csr_y < spr->top_margin || spc->csr_y > spr->btm_margin)
60153889Smckusick 		return;
60253889Smckusick 	if (pn <= spr->btm_margin - spc->csr_y) {
60353889Smckusick 		aux = spc->csr_y + pn;
60453889Smckusick 		move_lines(aux, spr->btm_margin - aux + 1, spc->csr_y);
60553889Smckusick 	}
60655762Sbostic 	aux = max(spr->btm_margin - pn + 1, spc->csr_y);
60753889Smckusick 	clear_lines(aux, spr->btm_margin - aux + 1, sp->s_term_mode & DECSCNM,
60853889Smckusick 		sp->s_plane, sp->s_bgcol);
60953889Smckusick 	spc->csr_x = LFT_M;
61053889Smckusick 	spc->csr_p.x = x_ofst;
61153889Smckusick }
61253889Smckusick 
61353889Smckusick /*
61453889Smckusick  *  Delete character.
61553889Smckusick  *  delete_char(sp, pn) deletes pn characters right side of the cursor.
61653889Smckusick  */
61753889Smckusick delete_char(sp, pn)
61853889Smckusick 	register SCREEN *sp;
61953889Smckusick 	register int pn;
62053889Smckusick {
62153889Smckusick 	register struct cursor *spc = &sp->s_csr;
62253889Smckusick 	register int aux;
62353889Smckusick 
62455762Sbostic 	pn = max(pn, 1);
62553889Smckusick 	if (pn < rit_m - spc->csr_x + 1) {
62653889Smckusick 		move_chars(spc->csr_x + pn, spc->csr_y,
62753889Smckusick 			rit_m - spc->csr_x - pn + 1 ,spc->csr_x);
62853889Smckusick 	}
62955762Sbostic 	aux = max(rit_m - pn + 1, spc->csr_x);
63053889Smckusick 	clear_chars(aux, spc->csr_y, rit_m - aux + 1,
63153889Smckusick 		sp->s_term_mode & DECSCNM, sp->s_plane, sp->s_bgcol);
63253889Smckusick }
63353889Smckusick 
63453889Smckusick /*
63553889Smckusick  *  This escape control sequence begins `^[[?' and ends `h' or `l'
63653889Smckusick  */
63753889Smckusick esc_csi_dec(sp, c)
63853889Smckusick 	register SCREEN *sp;
63953889Smckusick 	char c;
64053889Smckusick {
64153889Smckusick 	register char *cp;
64253889Smckusick 
64353889Smckusick 	if (in_str(c, sp->s_estp->terminators)) {
64453889Smckusick 		if (esc_buf[0] != INVALID) {
64553889Smckusick 			cursor_off();
64653889Smckusick 			switch (c) {
64753889Smckusick 			case 'h':	/*  set mode	*/
64853889Smckusick 			for (cp = esc_buf; cp <= esc_bp; cp++) {
64953889Smckusick 				switch (*cp) {
65053889Smckusick 				case 1:		/*  cursor key application  */
65153889Smckusick 					sp->s_term_mode |= DECCKM;
65253889Smckusick 					change_csr_key_pad(APPLIC);
65353889Smckusick 					break;
65453889Smckusick 				case 3:		/*  132 column mode	*/
65553889Smckusick 					sp->s_term_mode |= DECCOLM;
65653889Smckusick 					break;
65753889Smckusick 				case 4:		/*  jump scroll	*/
65853889Smckusick 					sp->s_term_mode |= DECSCLM;
65953889Smckusick 					break;
66053889Smckusick 				case 5:		/*  reverse	*/
66153889Smckusick 					if ((sp->s_term_mode & DECSCNM) == 0)
66253889Smckusick 						reverse_rec(sp->s_bgcol,
66353889Smckusick 							sp->s_plane);
66453889Smckusick 					sp->s_term_mode |= DECSCNM;
66553889Smckusick 					if (sp->s_csr.csr_attributes & REVERSE)
66653889Smckusick 					{
66753889Smckusick 						fcolor = sp->s_plane;
66853889Smckusick 						bcolor = sp->s_bgcol;
66953889Smckusick 					} else {
67053889Smckusick 						fcolor = sp->s_bgcol;
67153889Smckusick 						bcolor = sp->s_plane;
67253889Smckusick 					}
67353889Smckusick 					break;
67453889Smckusick 				case 6:		/*  origin	*/
67553889Smckusick 					sp->s_term_mode |= DECOM;
67653889Smckusick 					sp->s_csr.csr_x = LFT_M;
67753889Smckusick 					sp->s_csr.csr_y =
67853889Smckusick 						sp->s_region.top_margin;
67953889Smckusick 					sp->s_csr.csr_p.x = x_ofst;
68053889Smckusick 					sp->s_csr.csr_p.y =
68153889Smckusick 					   (sp->s_csr.csr_y - 1) * char_h +
68253889Smckusick 						y_ofst;
68353889Smckusick 					break;
68453889Smckusick 				case 7:		/*  auto wrap	*/
68553889Smckusick 					sp->s_term_mode |= DECAWM;
68653889Smckusick 					break;
68753889Smckusick 				case 8:		/*  auto repeat	 */
68853889Smckusick 					if ((sp->s_term_mode & DECARM) == 0) {
68953889Smckusick 						kbd_ioctl(SCC_KEYBOARD, KIOCREPT,
69053889Smckusick 							  (int *)0);
69153889Smckusick 					}
69253889Smckusick 					sp->s_term_mode |= DECARM;
69353889Smckusick 					break;
69453889Smckusick 				case 25:	/* cursor active */
69553889Smckusick 					sp->s_term_mode |= DECCSR_ACTV;
69653889Smckusick 					break;
69753889Smckusick 				default:
69853889Smckusick 					break;
69953889Smckusick 				}
70053889Smckusick 			}
70153889Smckusick 			break;
70253889Smckusick 			case 'l':	/*  reset mode	*/
70353889Smckusick 			for (cp = esc_buf; cp <= esc_bp; cp++) {
70453889Smckusick 				switch (*cp) {
70553889Smckusick 				case 1:		/*  cursor key application  */
70653889Smckusick 					sp->s_term_mode &= ~DECCKM;
70753889Smckusick 					change_csr_key_pad(NUMERIC);
70853889Smckusick 					break;
70953889Smckusick 				case 3:		/*  132 column mode	*/
71053889Smckusick 					sp->s_term_mode &= ~DECCOLM;
71153889Smckusick 					break;
71253889Smckusick 				case 4:		/*  jump scroll	*/
71353889Smckusick 					sp->s_term_mode &= ~DECSCLM;
71453889Smckusick 					break;
71553889Smckusick 				case 5:		/*  reverse	*/
71653889Smckusick 					if (sp->s_term_mode & DECSCNM)
71753889Smckusick 						reverse_rec(sp->s_plane,
71853889Smckusick 							sp->s_bgcol);
71953889Smckusick 					sp->s_term_mode &= ~DECSCNM;
72053889Smckusick 					if (sp->s_csr.csr_attributes & REVERSE)
72153889Smckusick 					{
72253889Smckusick 						fcolor = sp->s_bgcol;
72353889Smckusick 						bcolor = sp->s_plane;
72453889Smckusick 					} else {
72553889Smckusick 						fcolor = sp->s_plane;
72653889Smckusick 						bcolor = sp->s_bgcol;
72753889Smckusick 					}
72853889Smckusick 					break;
72953889Smckusick 				case 6:		/*  origin	*/
73053889Smckusick 					sp->s_term_mode &= ~DECOM;
73153889Smckusick 					sp->s_csr.csr_x = LFT_M;
73253889Smckusick 					sp->s_csr.csr_y = TOP_M;
73353889Smckusick 					sp->s_csr.csr_p.x = x_ofst;
73453889Smckusick 					sp->s_csr.csr_p.y = y_ofst;
73553889Smckusick 					break;
73653889Smckusick 				case 7:		/*  auto wrap	*/
73753889Smckusick 					sp->s_term_mode &= ~DECAWM;
73853889Smckusick 					break;
73953889Smckusick 				case 8:		/*  auto repeat	 */
74053889Smckusick 					if (sp->s_term_mode & DECARM) {
74153889Smckusick 						kbd_ioctl(SCC_KEYBOARD, KIOCNRPT,
74253889Smckusick 							(int *) 0);
74353889Smckusick 					}
74453889Smckusick 					sp->s_term_mode &= ~DECARM;
74553889Smckusick 					break;
74653889Smckusick 				case 25:	/* cursor non-active */
74753889Smckusick 					sp->s_term_mode &= ~DECCSR_ACTV;
74853889Smckusick 					break;
74953889Smckusick 				default:
75053889Smckusick 					break;
75153889Smckusick 				}
75253889Smckusick 			}
75353889Smckusick 			break;
75453889Smckusick 			default:
75553889Smckusick 				break;
75653889Smckusick 			}
75753889Smckusick 			cursor_on(&sp->s_csr.csr_p);
75853889Smckusick 		}
75953889Smckusick 		sp->s_current_stat &= ~ESCAPE;
76053889Smckusick 	} else {	/*  buffering  arguments	*/
76153889Smckusick 		if (c >= '0' && c <= '9') {
76253889Smckusick 			*esc_bp = *esc_bp * 10 + (c - '0');
76353889Smckusick 		} else if (c == ';') {
76453889Smckusick 			esc_bp++;
76553889Smckusick 		} else if (c == '?') {
76653889Smckusick 			esc_buf[0] = INVALID;
76753889Smckusick 		} else {
76853889Smckusick 			sp->s_current_stat &= ~ESCAPE;
76953889Smckusick 		}
77053889Smckusick 	}
77153889Smckusick }
77253889Smckusick 
77353889Smckusick /*
77453889Smckusick  *  changes cursor key pad to ansi_ctl
77553889Smckusick  */
77653889Smckusick static
77753889Smckusick change_csr_key_pad(applic)
77853889Smckusick 	register int applic;
77953889Smckusick {
78053889Smckusick 	char pad[4];
78153889Smckusick 	register Pfk_string *pfk = &pfk_str;
78253889Smckusick 	register Key_string *kys = &pfk_str.pfk_string;
78353889Smckusick 	register struct key_pad  *kpd;
78453889Smckusick 	register int i;
78553889Smckusick 
78653889Smckusick 	kpd = &key_pad[UP-N0];
78753889Smckusick 	pad[0] = '\033';
78853889Smckusick 	pad[1] = (applic) ? 'O': '[';
78953889Smckusick 	for (i = UP; i <= LEFT; i++) {
79053889Smckusick 		pfk->pfk_num = i;
79153889Smckusick 		kys->key_length = (applic) ? 3: 3;
79253889Smckusick 		pad[2] = (applic) ? kpd->kpd_applic: kpd->kpd_numeric;
79353889Smckusick 		kys->key_string = pad;
79453889Smckusick 		kpd++;
79553889Smckusick 		pfk->pfk_shift = PF_NORMAL;
79653889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk);
79753889Smckusick 		pfk->pfk_shift = PF_SHIFT;
79853889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk);
79953889Smckusick 	}
80053889Smckusick }
80153889Smckusick 
80253889Smckusick extern struct cursor inner_buf_csr;
80353889Smckusick extern int inner_buf_tstat;
80453889Smckusick /*
80553889Smckusick  *  Store cursor position and attributes.
80653889Smckusick  *  The SCREEN structure is stored inner structure.
80753889Smckusick  */
80853889Smckusick esc_store_csr(sp)
80953889Smckusick 	register SCREEN *sp;
81053889Smckusick {
81153889Smckusick 	inner_buf_csr = sp->s_csr;
81253889Smckusick 	inner_buf_tstat = (DECOM|DECAWM) & sp->s_term_mode;
81353889Smckusick }
81453889Smckusick 
81553889Smckusick /*
81653889Smckusick  *  Restore cursor position and attributes.
81753889Smckusick  *  The SCREEN structure  is restored from inner structure.
81853889Smckusick  *  Prevail error from unexpected use of this command, inner structure
81953889Smckusick  *  must be initialized.
82053889Smckusick  */
82153889Smckusick esc_restore_csr(sp)
82253889Smckusick 	register SCREEN *sp;
82353889Smckusick {
82453889Smckusick 	cursor_off();
82553889Smckusick 	sp->s_csr = inner_buf_csr;
82653889Smckusick 	sp->s_term_mode = (sp->s_term_mode & ~(DECOM|DECAWM)) | inner_buf_tstat;
82753889Smckusick 	cursor_on(&sp->s_csr.csr_p);
82853889Smckusick }
82953889Smckusick 
83053889Smckusick /*
83153889Smckusick  *  index()
83253889Smckusick  *  esc_index(sp) moves the cursor down if the cursor is not at
83353889Smckusick  *  bottom margin. If the cursor is at the bottom margin then
83453889Smckusick  *  scroll up.
83553889Smckusick  */
83653889Smckusick esc_index(sp)
83753889Smckusick 	register SCREEN *sp;
83853889Smckusick {
83953889Smckusick 	cursor_off();
84053889Smckusick 	if (sp->s_csr.csr_y == sp->s_region.btm_margin)
84153889Smckusick 		scroll_up(sp->s_region.top_margin,
84253889Smckusick 			sp->s_region.btm_margin, sp->s_term_mode & DECSCNM,
84353889Smckusick 			sp->s_plane, sp->s_bgcol);
84453889Smckusick 	else {
84553889Smckusick 		if (sp->s_csr.csr_y < btm_m) {
84653889Smckusick 			sp->s_csr.csr_y += 1;
84753889Smckusick 			sp->s_csr.csr_p.y += char_h;
84853889Smckusick 		}
84953889Smckusick 	}
85053889Smckusick 	sp->s_current_stat &= ~WRAP;
85153889Smckusick 	cursor_on(&sp->s_csr.csr_p);
85253889Smckusick }
85353889Smckusick 
85453889Smckusick /*
85553889Smckusick  *  next line
85653889Smckusick  *  esc_next_line(sp) moves the cursor down like index but the cursor
85753889Smckusick  *  position is the beginning of the next line.
85853889Smckusick  */
85953889Smckusick esc_next_line(sp)
86053889Smckusick 	register SCREEN *sp;
86153889Smckusick {
86253889Smckusick 	sp->s_csr.csr_x = LFT_M;
86353889Smckusick 	sp->s_csr.csr_p.x = x_ofst;
86453889Smckusick 	esc_index(sp);
86553889Smckusick }
86653889Smckusick 
86753889Smckusick /*
86853889Smckusick  *  tabulation set
86953889Smckusick  *  esc_tab_set(sp) sets tabulation stop at the current cursor point.
87053889Smckusick  */
87153889Smckusick esc_tab_set(sp)
87253889Smckusick 	register SCREEN *sp;
87353889Smckusick {
87453889Smckusick 	sp->s_tab_pos[sp->s_csr.csr_x] = 1;
87553889Smckusick }
87653889Smckusick 
87753889Smckusick /*
87853889Smckusick  *  reverse index
87953889Smckusick  *  esc_rev_index(sp) moves the cursor up if the cursor is not at the top
88053889Smckusick  *  margin. If the cursor is at the top margin then the screen takes place
88153889Smckusick  *  scroll down.
88253889Smckusick  */
88353889Smckusick esc_rev_index(sp)
88453889Smckusick 	register SCREEN *sp;
88553889Smckusick {
88653889Smckusick 	cursor_off();
88753889Smckusick 	if (sp->s_csr.csr_y == sp->s_region.top_margin)
88853889Smckusick 		scroll_down(sp->s_region.top_margin,
88953889Smckusick 			sp->s_region.btm_margin, sp->s_term_mode & DECSCNM,
89053889Smckusick 			sp->s_plane, sp->s_bgcol);
89153889Smckusick 	else {
89253889Smckusick 		if (sp->s_csr.csr_y > TOP_M) {
89353889Smckusick 			sp->s_csr.csr_y -= 1;
89453889Smckusick 			sp->s_csr.csr_p.y -= char_h;
89553889Smckusick 		}
89653889Smckusick 	}
89753889Smckusick 	sp->s_current_stat &= ~WRAP;
89853889Smckusick 	cursor_on(&sp->s_csr.csr_p);
89953889Smckusick }
90053889Smckusick 
90153889Smckusick /*
90253889Smckusick  *  numeric key pad
90353889Smckusick  *  esc_numeric_kpad(sp) changes key pad of cursor to numeric one.
90453889Smckusick  *  This sequence is used in vi.
90553889Smckusick  *  currently not supported
90653889Smckusick  */
90753889Smckusick esc_numeric_kpad(sp)
90853889Smckusick 	register SCREEN *sp;
90953889Smckusick {
91053889Smckusick 	change_aux_key_pad(NUMERIC);
91153889Smckusick 	sp->s_current_stat &= ~ESCAPE;
91253889Smckusick }
91353889Smckusick 
91453889Smckusick /*
91553889Smckusick  *  application key pad
91653889Smckusick  *  esc_application_kpad(sp) changes key pad of cursor to application one.
91753889Smckusick  *  This sequence is also used in vi.
91853889Smckusick  *  currently not supported.
91953889Smckusick  */
92053889Smckusick esc_application_kpad(sp)
92153889Smckusick 	register SCREEN *sp;
92253889Smckusick {
92353889Smckusick 	change_aux_key_pad(APPLIC);
92453889Smckusick 	sp->s_current_stat &= ~ESCAPE;
92553889Smckusick }
92653889Smckusick 
92753889Smckusick /*
92853889Smckusick  *  change auxiliary keypad
92953889Smckusick  */
93053889Smckusick static
93153889Smckusick change_aux_key_pad(applic)
93253889Smckusick 	register int applic;
93353889Smckusick {
93453889Smckusick 	char pad[4];
93553889Smckusick 	register Pfk_string *pfk = &pfk_str;
93653889Smckusick 	register Key_string *kys = &pfk_str.pfk_string;
93753889Smckusick 	register struct key_pad *kpd;
93853889Smckusick 	register int i;
93953889Smckusick 
94053889Smckusick 	kpd = &key_pad[0];
94153889Smckusick 	if (applic) {
94253889Smckusick 		pad[0] = '\033';
94353889Smckusick 		pad[1] = 'O';
94453889Smckusick 	}
94553889Smckusick 	for (i = N0; i <= NENTER; i++) {
94653889Smckusick 
94753889Smckusick 		pfk->pfk_num = i;
94853889Smckusick 		kys->key_length = (applic) ? 3: 1;
94953889Smckusick 		if (applic) {
95053889Smckusick 			pad[2] = kpd->kpd_applic;
95153889Smckusick 		} else {
95253889Smckusick 			pad[0] = kpd->kpd_numeric;
95353889Smckusick 		}
95453889Smckusick 		kys->key_string = pad;
95553889Smckusick 		kpd++;
95653889Smckusick 		pfk->pfk_shift = PF_NORMAL;
95753889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk);
95853889Smckusick 		pfk->pfk_shift = PF_SHIFT;
95953889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk);
96053889Smckusick 	}
96153889Smckusick 	if (!applic) {
96253889Smckusick 		pfk->pfk_shift = PF_SHIFT;
96353889Smckusick 		kys->key_length = 1;
96453889Smckusick 
96553889Smckusick 		pfk->pfk_num = MINUS;
96653889Smckusick 		kys->key_string = "/";
96753889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk);
96853889Smckusick 
96953889Smckusick 		pfk->pfk_num = PLUS;
97053889Smckusick 		kys->key_string = "*";
97153889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk);
97253889Smckusick 
97353889Smckusick 		pfk->pfk_num = COMMA;
97453889Smckusick 		kys->key_string = "=";
97553889Smckusick  		kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk);
97653889Smckusick 	}
97753889Smckusick }
97853889Smckusick 
97953889Smckusick extern	struct	csr_buf	local_csr_buf;
98053889Smckusick /*
98153889Smckusick  *  change line size
98253889Smckusick  *  esc_line_size(sp, pn) changes line size.
98353889Smckusick  *	c = `3'	double side double height(top half)
98453889Smckusick  *	c = `4'	double side double height(bottom half)
98553889Smckusick  *	c = `5'	sigle width line
98653889Smckusick  *	c = `6'	double width line
98753889Smckusick  *  currently not supported
98853889Smckusick  */
98953889Smckusick esc_line_size(sp, c)
99053889Smckusick 	register SCREEN *sp;
99153889Smckusick 	char c;
99253889Smckusick {
99353889Smckusick 	register int i;
99453889Smckusick 	register int j;
99553889Smckusick 	int save_f, save_b;
99653889Smckusick 
99753889Smckusick 	cursor_off();
99853889Smckusick 	switch (c) {
99953889Smckusick 	case '5':
100053889Smckusick 		local_csr_buf.csr_number = 1;
100153889Smckusick 		break;
100253889Smckusick 	case '6':
100353889Smckusick 		local_csr_buf.csr_number = 2;
100453889Smckusick 		break;
100553889Smckusick 	case '8':
100653889Smckusick 		sp->s_region.top_margin = TOP_M;
100753889Smckusick 		sp->s_region.btm_margin = btm_m;
100853889Smckusick 		save_f = fcolor;
100953889Smckusick 		save_b = bcolor;
101053889Smckusick 		fcolor = sp->s_bgcol;
101153889Smckusick 		bcolor = sp->s_plane;
101253889Smckusick 		sp->s_csr.csr_p.y = y_ofst;
101353889Smckusick 		for (i = TOP_M; i <= btm_m; i++) {
101453889Smckusick 			sp->s_csr.csr_p.x = x_ofst;
101553889Smckusick 			sp->s_csr.csr_y = i;
101653889Smckusick 			for (j = LFT_M; j <= rit_m; j++) {
101753889Smckusick 				sp->s_csr.csr_x = j;
101853889Smckusick 				copy_char(sp, 'E', 0);
101953889Smckusick 				sp->s_csr.csr_p.x += char_w;
102053889Smckusick 			}
102153889Smckusick 			sp->s_csr.csr_p.y += char_h;
102253889Smckusick 		}
102353889Smckusick 		sp->s_csr.csr_x = LFT_M;
102453889Smckusick 		sp->s_csr.csr_y = TOP_M;
102553889Smckusick 		sp->s_csr.csr_p.x = x_ofst;
102653889Smckusick 		sp->s_csr.csr_p.y = y_ofst;
102753889Smckusick 		fcolor = save_f;
102853889Smckusick 		bcolor = save_b;
102953889Smckusick 		break;
103053889Smckusick 	default:
103153889Smckusick 		break;
103253889Smckusick 	}
103353889Smckusick 	cursor_on(&sp->s_csr.csr_p);
103453889Smckusick 	sp->s_current_stat &= ~ESCAPE;
103553889Smckusick }
103653889Smckusick 
103753889Smckusick /*
103853889Smckusick  *  character set
103953889Smckusick  *  esc_char_setr sets which character set you use in right graphic set.
104053889Smckusick  *  currently not supported
104153889Smckusick  */
104253889Smckusick esc_char_setr(sp, c)
104353889Smckusick 	register SCREEN *sp;
104453889Smckusick 	int c;
104553889Smckusick {
104653889Smckusick #if defined(IPC_MRX) || defined(CPU_SINGLE)
104753889Smckusick 	switch (c) {
104853889Smckusick 	case 'J':
104953889Smckusick 	case 'H':
105053889Smckusick 		font_jisroman();
105153889Smckusick #ifdef CPU_SINGLE
105253889Smckusick 		font_jisroman24();
105353889Smckusick #endif
105453889Smckusick 		sp->s_current_stat &= ~JKANJI;
105553889Smckusick 		break;
105653889Smckusick 	case 'B':
105753889Smckusick 		font_ascii();
105853889Smckusick #ifdef CPU_SINGLE
105953889Smckusick 		font_ascii24();
106053889Smckusick #endif
106153889Smckusick 		sp->s_current_stat &= ~JKANJI;
106253889Smckusick 		break;
106353889Smckusick 	}
106453889Smckusick #else /* IPC_MRX || CPU_SINGLE */
106553889Smckusick 	if (c == 'B' || c == 'J' || c == 'H') {
106653889Smckusick 		sp->s_current_stat &= ~JKANJI;
106753889Smckusick 	}
106853889Smckusick #endif /* IPC_MRX || CPU_SINGLE */
106953889Smckusick 	sp->s_current_stat &= ~ESCAPE;
107053889Smckusick }
107153889Smckusick 
107253889Smckusick /*
107353889Smckusick  *  character set to left graphic set
107453889Smckusick  *  esc_char_setl sets which character set you use in left graphic set.
107553889Smckusick  *  currently not supported
107653889Smckusick  */
107753889Smckusick esc_char_setl(sp, c)
107853889Smckusick 	register SCREEN *sp;
107953889Smckusick 	int c;
108053889Smckusick {
108153889Smckusick 	sp->s_current_stat &= ~ESCAPE;
108253889Smckusick }
108353889Smckusick 
108453889Smckusick extern tmode;
108553889Smckusick extern  unsigned  int	first_jcode;
108653889Smckusick /*
108753889Smckusick  *  character set to kanji
108853889Smckusick  *  esc_kanji_set sets kanji
108953889Smckusick  */
109053889Smckusick esc_kanji_set(sp, c)
109153889Smckusick 	register SCREEN *sp;
109253889Smckusick 	int c;
109353889Smckusick {
109453889Smckusick 
109553889Smckusick #ifdef KM_JIS
109653889Smckusick 	if (tmode == KM_JIS && (c == 'B' || c == '@')) {
109753889Smckusick 		sp->s_current_stat |= JKANJI;
109853889Smckusick 		first_jcode = 0;
109953889Smckusick 	}
110053889Smckusick #endif
110153889Smckusick 	sp->s_current_stat &= ~ESCAPE;
110253889Smckusick }
110353889Smckusick 
110453889Smckusick static short parm_buf[PARM_BUF_SIZ];
110553889Smckusick static short *parm_bp = parm_buf;
110653889Smckusick static int sensitive = 0;
110753889Smckusick static int pval = 0;
110853889Smckusick /*
110953889Smckusick  *  terminal parameter set command
111053889Smckusick  *  esc_parm_set(sp, c)  sets terminal parameters such as font-width,
111153889Smckusick  *  font-height, character-width, character-height, character-position,
111253889Smckusick  *  underlind-position, screen-width, screen-height, x-offset, y-offset,
111353889Smckusick  *  right-mergin, bottom-mergin, dimmer-count, bell-length.
111453889Smckusick  */
111553889Smckusick esc_parm_set(sp, c)
111653889Smckusick 	register SCREEN *sp;
111753889Smckusick 	register unsigned int c;
111853889Smckusick {
111953889Smckusick 	static int bufc = 0;
112053889Smckusick 
112153889Smckusick 	if (in_str(c, sp->s_estp->terminators)) {
112253889Smckusick 		if (sensitive) {
112353889Smckusick 			*parm_bp++ = pval;
112453889Smckusick 		} else {
112553889Smckusick 			*parm_bp++ = -1;
112653889Smckusick 		}
112753889Smckusick 		*parm_bp++ = -1;
112853889Smckusick 		parm_set(sp, parm_buf, c);
112953889Smckusick 		sp->s_current_stat &= ~ESCAPE;
113053889Smckusick 		sensitive = pval = 0;
113153889Smckusick 		parm_bp = parm_buf;
113253889Smckusick 		bufc = 0;
113353889Smckusick 		return;
113453889Smckusick 	}
113553889Smckusick 	/*  buffering arguments  */
113653889Smckusick 	if (bufc < PARM_BUF_SIZ) {
113753889Smckusick 		if (c >= '0' && c <= '9') {
113853889Smckusick 			pval = pval *10 + (c - '0');
113953889Smckusick 			sensitive = 1;
114053889Smckusick 		} else if (c == ';') {
114153889Smckusick 			if (sensitive) {
114253889Smckusick 				*parm_bp++ = pval;
114353889Smckusick 			} else {
114453889Smckusick 				*parm_bp++ = -1;
114553889Smckusick 			}
114653889Smckusick 			sensitive = pval = 0;
114753889Smckusick 			bufc++;
114853889Smckusick 		} else {
114953889Smckusick 			sp->s_current_stat &= ~ESCAPE;
115053889Smckusick 			sensitive = pval = 0;
115153889Smckusick 			parm_bp = parm_buf;
115253889Smckusick 			bufc = 0;
115353889Smckusick 		}
115453889Smckusick 	}
115553889Smckusick }
115653889Smckusick 
115753889Smckusick static	char	an_buf[AN_BUF_SIZ];
115853889Smckusick 
115953889Smckusick parm_set(sp, parm, terminator)
116053889Smckusick 	SCREEN *sp;
116153889Smckusick 	short *parm;
116253889Smckusick 	unsigned int terminator;
116353889Smckusick {
116453889Smckusick 	register char *bp = an_buf;
116553889Smckusick 	register char *p;
116653889Smckusick 
116753889Smckusick 	switch (terminator) {
116853889Smckusick 	case 'f':
116953889Smckusick 		if (parm[0] >= FONT_W_MIN && parm[0] <= consfb->font_w &&
117053889Smckusick 							parm[0] < char_w)
117153889Smckusick 			font_w =  parm[0];
117253889Smckusick 
117353889Smckusick 		if (parm[1] >= FONT_H_MIN && parm[1] <= consfb->font_h &&
117453889Smckusick 					parm[1] <= (char_h - ch_pos))
117553889Smckusick 			font_h = parm[1];
117653889Smckusick 		break;
117753889Smckusick 	case 'c':
117853889Smckusick 		if (parm[0] >= CHAR_W_MIN && parm[0] > font_w &&
117953889Smckusick 						parm[0] <= CHAR_W_MAX)
118053889Smckusick 			char_w = parm[0];
118153889Smckusick 
118253889Smckusick 		if (parm[1] >= CHAR_H_MIN && parm[1] >= (font_h + ch_pos) &&
118353889Smckusick 				parm[1] > ul_pos && parm[1] <= CHAR_H_MAX)
118453889Smckusick 			char_h = parm[1];
118553889Smckusick 
118653889Smckusick 		break;
118753889Smckusick 	case 'p':
118853889Smckusick 		if (parm[0] >= UL_POS_MIN && parm[0] <= UL_POS_MAX &&
118953889Smckusick 						parm[0] < char_h) {
119053889Smckusick 			ul_pos = parm[0];
119153889Smckusick 		}
119253889Smckusick 		if (parm[1] >= CH_POS_MIN && parm[1] <= CH_POS_MAX &&
119353889Smckusick 					parm[1] < (char_h - font_h)) {
119453889Smckusick 			ch_pos = parm[1];
119553889Smckusick 		}
119653889Smckusick 		break;
119753889Smckusick 	case 's':
119853889Smckusick 		if (parm[0] > SCR_W_MIN && parm[0] <= consfb->scr_w)
119953889Smckusick 			scr_w = (parm[0] < char_w) ? char_w: parm[0];
120053889Smckusick 		if (parm[1] > SCR_H_MIN && parm[1] <= consfb->scr_h)
120153889Smckusick 			scr_h = (parm[1] < char_h) ? char_h: parm[1];
120253889Smckusick 		break;
120353889Smckusick 	case 'o':
120453889Smckusick 		if (parm[0] >= X_OFST_MIN && parm[0] <= X_OFST_MAX)
120553889Smckusick 			x_ofst = (parm[0] > scr_w - char_w) ?
120653889Smckusick 				(scr_w - char_w): parm[0];
120753889Smckusick 		if (parm[1] >= Y_OFST_MIN && parm[1] <= Y_OFST_MAX)
120853889Smckusick 			y_ofst = (parm[1] > scr_h - char_h) ?
120953889Smckusick 				(scr_h - char_h): parm[1];
121053889Smckusick 		break;
121153889Smckusick 	case 'm':
121253889Smckusick 		if (parm[0] >= RIT_M_MIN) {
121353889Smckusick 			if (parm[0] > RIT_M_MAX /* consfb->rit_m */) {
121453889Smckusick 				parm[0] = consfb->rit_m;
121553889Smckusick 			}
121653889Smckusick 			rit_m = (parm[0] > (scr_w - x_ofst)/char_w) ?
121753889Smckusick 				(scr_w - x_ofst)/char_w: parm[0];
121853889Smckusick 		}
121953889Smckusick 		if (parm[1] >= BTM_M_MIN) {
122053889Smckusick 			if (parm[1] > BTM_M_MAX /* consfb->btm_m */) {
122153889Smckusick 				parm[1] = consfb->btm_m;
122253889Smckusick 			}
122353889Smckusick 			btm_m = (parm[1] > (scr_h - y_ofst)/char_h) ?
122453889Smckusick 				(scr_h - y_ofst)/char_h: parm[1];
122553889Smckusick 		}
122653889Smckusick 		break;
122753889Smckusick 	case 'd':
122853889Smckusick 		if (parm[0] >= DIM_CNT_MIN && parm[0] <= DIM_CNT_MAX)
122953889Smckusick 			dim_cnt = a_dim_on = parm[0];
123053889Smckusick 		else
123153889Smckusick 			a_dim_on = 0;
123253889Smckusick 		break;
123353889Smckusick 	case 'b':
123453889Smckusick 		if (parm[0] >= BELL_LEN_MIN && parm[0] <= BELL_LEN_MAX)
123553889Smckusick 			bell_len = parm[0];
123653889Smckusick 		break;
123753889Smckusick 	case 'D':
123853889Smckusick 		set_default_param();
123953889Smckusick 		vt100init();
124053889Smckusick 		bitmapinit();
124153889Smckusick 		break;
124253889Smckusick 	case 'i':
124353889Smckusick 		cursor_off();
124453889Smckusick 		csr_pos(sp, LFT_M, TOP_M);
124553889Smckusick 		key_str.key_string = c_pos_mess;
124653889Smckusick 		key_str.key_length = spr(c_pos_mess, "f=(%d,%d), ",
124753889Smckusick 							font_w, font_h);
124853889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
124953889Smckusick 
125053889Smckusick 		key_str.key_length = spr(c_pos_mess, "c=(%d,%d), ",
125153889Smckusick 							char_w, char_h);
125253889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
125353889Smckusick 
125453889Smckusick 		csr_pos(sp, LFT_M, (TOP_M - 1));
125553889Smckusick 		key_str.key_string = c_pos_mess;
125653889Smckusick 		key_str.key_length = spr(c_pos_mess, "p=(%d,%d), ",
125753889Smckusick 							ul_pos, ch_pos);
125853889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
125953889Smckusick 		key_str.key_length = spr(c_pos_mess, "s=(%d,%d), ",
126053889Smckusick 							scr_w, scr_h);
126153889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
126253889Smckusick 
126353889Smckusick 		csr_pos(sp, LFT_M, (TOP_M - 2));
126453889Smckusick 		key_str.key_string = c_pos_mess;
126553889Smckusick 		key_str.key_length = spr(c_pos_mess, "o=(%d,%d), ",
126653889Smckusick 							x_ofst, y_ofst);
126753889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
126853889Smckusick 		key_str.key_length = spr(c_pos_mess, "m=(%d,%d)",
126953889Smckusick 							rit_m, btm_m);
127053889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
127153889Smckusick 
127253889Smckusick 		cursor_on(&sp->s_csr.csr_p);
127353889Smckusick 		return;
127453889Smckusick 	case 'G':
127553889Smckusick 		line(parm);
127653889Smckusick 		return;
127753889Smckusick 	case 'C':
127853889Smckusick 		if (parm[0] >= 0) {
127953889Smckusick 			sp->s_plane = fbbm_get_pixel(consfb, parm[0]);
128053889Smckusick 		}
128153889Smckusick 		if (parm[1] >= 0) {
128253889Smckusick 			sp->s_bgcol = fbbm_get_pixel(consfb, parm[1]);
128353889Smckusick 		}
128453889Smckusick 		cursor_off();
128553889Smckusick 		if ((sp->s_csr.csr_attributes & REVERSE) ^
128653889Smckusick 			(sp->s_term_mode & DECSCNM)) {
128753889Smckusick 			fcolor = sp->s_bgcol;
128853889Smckusick 			bcolor = sp->s_plane;
128953889Smckusick 		}
129053889Smckusick 		else {
129153889Smckusick 			fcolor = sp->s_plane;
129253889Smckusick 			bcolor = sp->s_bgcol;
129353889Smckusick 		}
129453889Smckusick 		cursor_on(&sp->s_csr.csr_p);
129553889Smckusick 		return;
129653889Smckusick 	case 'T':
129753889Smckusick 		if (parm[0] < 0 || consfb->Mono)
129853889Smckusick 			return;
129953889Smckusick 		/*
130053889Smckusick 		 *  what value is defined on pallet N?
130153889Smckusick 		 *    put string in an_buf
130253889Smckusick 		 */
130353889Smckusick 		*bp++ = '\033';
130453889Smckusick 		*bp++ = '~';
130553889Smckusick 		bp += itoa(bm_pallet_read(parm[0]), 10, bp);
130653889Smckusick 		*bp++ = 'a';
130753889Smckusick 		key_str.key_length = bp - an_buf;
130853889Smckusick 		key_str.key_string = an_buf;
130953889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
131053889Smckusick 		return;
131153889Smckusick 	case 't':
131253889Smckusick 		if (parm[0] >= 0 && !consfb->Mono) {
131353889Smckusick 			bm_pallet_write(parm[0],
131453889Smckusick 					(unsigned) parm[1] << 16
131553889Smckusick 					| (unsigned) parm[2] << 8
131653889Smckusick 					| (unsigned) parm[3]
131753889Smckusick 			);
131853889Smckusick 		}
131953889Smckusick 		return;
132053889Smckusick 	default:
132153889Smckusick 		return;
132253889Smckusick 	}
132353889Smckusick 	if (char_w < font_w) char_w = font_w;
132453889Smckusick 	if (char_h < font_h) char_h = font_h;
132553889Smckusick 	if (ch_pos > char_h - font_h) {
132653889Smckusick 		ch_pos = char_h - font_h;
132753889Smckusick 		ul_pos = char_h - 1;
132853889Smckusick 	}
132953889Smckusick 	if (rit_m > (scr_w - x_ofst)/char_w)
133053889Smckusick 		rit_m = (scr_w - x_ofst)/char_w;
133153889Smckusick 	if (btm_m > (scr_h - y_ofst)/char_h)
133253889Smckusick 		btm_m = (scr_h - y_ofst)/char_h;
133353889Smckusick 	sp->s_region.top_margin = TOP_M;
133453889Smckusick 	sp->s_region.btm_margin = btm_m;
133553889Smckusick 	font_r1.extent.x = font_w;
133653889Smckusick 	font_r1.extent.y = font_h;
133753889Smckusick 	font_r2.extent.x = font_w * 2;
133853889Smckusick 	font_r2.extent.y = font_h;
133953889Smckusick 	font_len1 = (font_w + 0x0f)>>4;
134053889Smckusick 	font_len2 = (font_w*2 + 0x0f)>>4;
134153889Smckusick 	cursor_off();
134253889Smckusick 	char_r1.extent.x = char_w;
134353889Smckusick 	char_r1.extent.y = char_h;
134453889Smckusick 	char_r2.extent.x = char_w * 2;
134553889Smckusick 	char_r2.extent.y = char_h;
134653889Smckusick 	csr_pos(sp, sp->s_csr.csr_x, sp->s_csr.csr_y);
134753889Smckusick 	sp->s_csr.csr_p.x = (sp->s_csr.csr_x - 1) * char_w + x_ofst;
134853889Smckusick 	sp->s_csr.csr_p.y = (sp->s_csr.csr_y - 1) * char_h + y_ofst;
134953889Smckusick 	cursor_on(&sp->s_csr.csr_p);
135053889Smckusick }
135153889Smckusick 
135253889Smckusick /* VARARGS */
135353889Smckusick spr(s, fmt, ad, dummy)
135453889Smckusick 	register char *s, *fmt;
135553889Smckusick 	u_int ad;
135653889Smckusick {
135753889Smckusick 	register int b, c;
135853889Smckusick 	register u_int *adx = &ad;
135953889Smckusick 	char *base = s;
136053889Smckusick 
136153889Smckusick 	for (;;) {
136253889Smckusick 		while ((c = *fmt++) != '%') {
136353889Smckusick 			*s++ = c;
136453889Smckusick 			if (c == '\0')
136553889Smckusick 				return (s - base - 1);
136653889Smckusick 		}
136753889Smckusick 
136853889Smckusick 		c = *fmt++;
136953889Smckusick 		switch (c) {
137053889Smckusick 
137153889Smckusick 		case 'x': case 'X':
137253889Smckusick 			b = 16;
137353889Smckusick 			goto number;
137453889Smckusick 		case 'd': case 'D':
137553889Smckusick 			b = 10;
137653889Smckusick 			goto number;
137753889Smckusick 		case 'o': case 'O':
137853889Smckusick 			b = 8;
137953889Smckusick number:
138053889Smckusick 			s += itoa(*adx, b, s);
138153889Smckusick 			break;
138253889Smckusick 
138353889Smckusick 		case 'c':
138453889Smckusick 			*s++ = *adx;
138553889Smckusick 			break;
138653889Smckusick 
138753889Smckusick 		case '%':
138853889Smckusick 			*s++ = c;
138953889Smckusick 			break;
139053889Smckusick 		}
139153889Smckusick 		adx++;
139253889Smckusick 	}
139353889Smckusick }
139453889Smckusick 
139553889Smckusick static int pfn = -1;
139653889Smckusick static int active_buf = 0;
139753889Smckusick /*
139853889Smckusick  *  define the programable function keys and answer back message.
139953889Smckusick  *  the vt100 facilities do not contain this command!
140053889Smckusick  *  command sequence is as follows:
140153889Smckusick  *       "^[Pn|n1;n2;...;nmp"		(normal mode)
140253889Smckusick  *  or
140353889Smckusick  *       "^[Pn|n1;n2;...;nmP"		(shift mode)
140453889Smckusick  *  or
140553889Smckusick  *       "^[Pn|n1;n2;...;nmZ"		(answer backe message)
140653889Smckusick  *  where, `n' denotes the decimal number asigned to function key,
140753889Smckusick  *          from `n1' to `nm' denote hexa number, finally,
140853889Smckusick  *	    `p' , `E' or `Z' tells that the sequence has terminated.
140953889Smckusick  *  remark:
141053889Smckusick  *	  when the terminator is `Z', the function number `n' can be omitted,
141153889Smckusick  *	  and even though the number is specified, there is no affection to
141253889Smckusick  *	  the result.
141353889Smckusick  *
141453889Smckusick  *
141553889Smckusick  *  ADDITION:
141653889Smckusick  *	  there is a question: what strings are defined in programable function
141753889Smckusick  *	  key of key-number n?
141853889Smckusick  *	  in order to anwer this question, another escape sequence has appended.
141953889Smckusick  *	  command sequence is as follows:
142053889Smckusick  *
142153889Smckusick  *	   "^[Pn|i"			(normal mode)
142253889Smckusick  *  or
142353889Smckusick  *	   "^[Pn|I"			(shift	mode)
142453889Smckusick  *
142553889Smckusick  *	  then the answer is
142653889Smckusick  *
142753889Smckusick  *	   "^[Pn|n1;n2;...;nmr"		(normal	mode)
142853889Smckusick  *  or
142953889Smckusick  *	   "^[Pn|n1;n2;...;nmR"		(shift	mode)
143053889Smckusick  *
143153889Smckusick  */
143253889Smckusick esc_pf_define(sp, c)
143353889Smckusick 	SCREEN *sp;
143453889Smckusick 	unsigned int c;
143553889Smckusick {
143653889Smckusick 	static bufc = 0;
143753889Smckusick 
143853889Smckusick 	if (in_str(c, sp->s_estp->terminators)) {
143953889Smckusick 		pf_define(pfn, esc_bp - esc_buf + active_buf, c);
144053889Smckusick 		sp->s_current_stat &= ~ESCAPE;
144153889Smckusick 		active_buf = 0;
144253889Smckusick 		pfn = -1;
144353889Smckusick 		bufc = 0;
144453889Smckusick 		return;
144553889Smckusick 	}
144653889Smckusick 	/*  buffering arguments  */
144753889Smckusick 	if (bufc < ESC_BUF_SIZ) {
144853889Smckusick 		if (pfn < 0) {
144953889Smckusick 			if (c >= '0' && c <= '9') {
145053889Smckusick 				*esc_bp = *esc_bp *10 + (c - '0');
145153889Smckusick 			} else if (c == '|') {
145253889Smckusick 				pfn = *esc_bp;
145353889Smckusick 				*esc_bp = 0;
145453889Smckusick 			} else {
145553889Smckusick 				sp->s_current_stat &= ~ESCAPE;
145653889Smckusick 				active_buf = 0;
145753889Smckusick 				pfn = -1;
145853889Smckusick 			}
145953889Smckusick 		} else {
146053889Smckusick 			active_buf = 1;
146153889Smckusick 			if (c >= '0' && c <= '9') {
146253889Smckusick 				*esc_bp = *esc_bp * 16 + (c - '0');
146353889Smckusick 			} else if (c >= 'a' && c <= 'f') {
146453889Smckusick 				*esc_bp = *esc_bp * 16 + (c - 'a' + 10);
146553889Smckusick 			} else if (c >= 'A' && c <= 'F') {
146653889Smckusick 				*esc_bp = *esc_bp * 16 + (c - 'A' + 10);
146753889Smckusick 			} else if (c == ';') {
146853889Smckusick 				esc_bp++;
146953889Smckusick 				bufc++;
147053889Smckusick 			} else {
147153889Smckusick 				sp->s_current_stat &= ~ESCAPE;
147253889Smckusick 				pfn = -1;
147353889Smckusick 				active_buf = 0;
147453889Smckusick 				bufc = 0;
147553889Smckusick 			}
147653889Smckusick 		}
147753889Smckusick 	} else {
147853889Smckusick 		active_buf = 0;
147953889Smckusick 	}
148053889Smckusick }
148153889Smckusick 
148253889Smckusick pf_define(pfn, length, terminator)
148353889Smckusick 	int pfn;
148453889Smckusick 	int length;
148553889Smckusick 	unsigned int terminator;
148653889Smckusick {
148753889Smckusick 	register Pfk_string *pfk = &pfk_str;
148853889Smckusick 	register Key_string *kys = &pfk_str.pfk_string;
148953889Smckusick 
149053889Smckusick 	if (terminator == 'Z')
149153889Smckusick 		return;
149253889Smckusick 
149353889Smckusick 	if (pfn < 0 || pfn > N_PFK)
149453889Smckusick 		return;
149553889Smckusick 	if (terminator == 'i' || terminator == 'I') {
149653889Smckusick 		pf_answer(pfn, terminator);
149753889Smckusick 		return;
149853889Smckusick 	}
149953889Smckusick 	pfk->pfk_num = pfn ? pfn: 1;
150053889Smckusick 	pfk->pfk_shift = (terminator == 'p') ? PF_NORMAL: PF_SHIFT;
150153889Smckusick 	kys->key_length = length;
150253889Smckusick 	kys->key_string = esc_buf;
150353889Smckusick  	kbd_ioctl(SCC_KEYBOARD, KIOCSETS, pfk);
150453889Smckusick }
150553889Smckusick 
150653889Smckusick /*
150753889Smckusick  *  pf_answer(pfn, terminator)
150853889Smckusick  *  this routine answers what strings defined on pfn.
150953889Smckusick  */
151053889Smckusick 
151153889Smckusick char def_seq[ESC_BUF_SIZ];
151253889Smckusick 
151353889Smckusick pf_answer(pfn, terminator)
151453889Smckusick 	int pfn;
151553889Smckusick 	unsigned int terminator;
151653889Smckusick {
151753889Smckusick 	register Pfk_string *pfk = &pfk_str;
151853889Smckusick 	register Key_string *kys = &pfk_str.pfk_string;
151953889Smckusick 	register char *bp = an_buf;
152053889Smckusick 	register char *p = def_seq;
152153889Smckusick 	register int length;
152253889Smckusick 	register int j;
152353889Smckusick 
152453889Smckusick 	/*
152553889Smckusick 	 *  function key inquiry
152653889Smckusick 	 *    get string in def_seq
152753889Smckusick 	 */
152853889Smckusick 	pfk->pfk_num = pfn ? pfn: 1;
152953889Smckusick 	pfk->pfk_shift = (terminator == 'i') ? PF_NORMAL: PF_SHIFT;
153053889Smckusick 	kys->key_length = ESC_BUF_SIZ;
153153889Smckusick 	kys->key_string = def_seq;
153253889Smckusick 	kbd_ioctl(SCC_KEYBOARD, KIOCGETS, pfk);
153353889Smckusick 	length = kys->key_length;
153453889Smckusick 
153553889Smckusick 	/*
153653889Smckusick 	 *  function key answer
153753889Smckusick 	 *    put string in an_buf
153853889Smckusick 	 */
153953889Smckusick 	*bp++ = '\033';
154053889Smckusick 	*bp++ = 'P';
154153889Smckusick 	bp += itoa(pfn, 10, bp);
154253889Smckusick 	*bp++ = '|';
154353889Smckusick 	key_str.key_length = bp - an_buf;
154453889Smckusick 	key_str.key_string = an_buf;
154553889Smckusick 	kbd_ioctl(SCC_KEYBOARD, KIOCBACK, &key_str);
154653889Smckusick 
154753889Smckusick 	bp = an_buf;
154853889Smckusick 	if (length--) {
154953889Smckusick 		bp += itoa(*p++ & 0xff, 16, bp);
155053889Smckusick 	}
155153889Smckusick 	while (length > 0) {
155253889Smckusick 		for (j = 0; (j < 10) && (length-- > 0); j++) {
155353889Smckusick 			*bp++ = ';';
155453889Smckusick 			bp += itoa(*p++ & 0xff, 16, bp);
155553889Smckusick 		}
155653889Smckusick 		key_str.key_length = bp - an_buf;
155753889Smckusick 		kbd_ioctl(SCC_KEYBOARD, KIOCBACK, (int *)&key_str);
155853889Smckusick 		bp = an_buf;
155953889Smckusick 	}
156053889Smckusick 	*bp++ = (terminator == 'i') ? 'r': 'R';
156153889Smckusick 	key_str.key_length = bp - an_buf;
156253889Smckusick 	kbd_ioctl(SCC_KEYBOARD, KIOCBACK, (int *)&key_str);
156353889Smckusick }
156453889Smckusick 
156553889Smckusick /*
156653889Smckusick  *  ignore
156753889Smckusick  *  esc_ignore(sp) is not called ordinally work.
156853889Smckusick  */
156953889Smckusick esc_ignore(sp)
157053889Smckusick 	register SCREEN *sp;
157153889Smckusick {
157253889Smckusick 	sp->s_current_stat &= ~ESCAPE;
157353889Smckusick }
157453889Smckusick 
157553889Smckusick static  char	*nmr = "0123456789abcdef";
157653889Smckusick /*
157753889Smckusick  *  itoa
157853889Smckusick  *  this routine converts binary to ascii decimal or hexa number
157953889Smckusick  *  according to mod.
158053889Smckusick  */
158153889Smckusick static
158253889Smckusick itoa(n, mod, buf)
158353889Smckusick 	register int n;
158453889Smckusick 	register int mod;
158553889Smckusick 	register char *buf;
158653889Smckusick {
158753889Smckusick 	register  int	i = 0;
158853889Smckusick 	register  int	cnt;
158953889Smckusick 	int	first = 1;
159053889Smckusick 	int	k;
159153889Smckusick 
159253889Smckusick 	n &= 0xffff;
159353889Smckusick 	for (cnt = mod*mod*mod*mod*mod*mod*mod; cnt > 0; cnt /= mod) {
159453889Smckusick 		k = n / cnt;
159553889Smckusick 		n -= k * cnt;
159653889Smckusick 		if (k == 0) {
159753889Smckusick 			if (first == 0) {
159853889Smckusick 				*buf++ = nmr[k];
159953889Smckusick 				i++;
160053889Smckusick 			}
160153889Smckusick 		} else {
160253889Smckusick 			*buf++ = nmr[k];
160353889Smckusick 			i++;
160453889Smckusick 			first = 0;
160553889Smckusick 		}
160653889Smckusick 	}
160753889Smckusick 	if (first == 1) {
160853889Smckusick 		*buf++ = '0';
160953889Smckusick 		i++;
161053889Smckusick 	}
161153889Smckusick 	return(i);
161253889Smckusick }
1613