svn commit: r199171 - in head/sys: dev/syscons pc98/cbus teken

Ed Schouten ed at FreeBSD.org
Wed Nov 11 08:20:20 UTC 2009


Author: ed
Date: Wed Nov 11 08:20:19 2009
New Revision: 199171
URL: http://svn.freebsd.org/changeset/base/199171

Log:
  Allow Syscons terminal emulators to provide function key strings.
  
  xterm and cons25 have some incompatibilities when it comes to escape
  sequences for special keys, such as F1 to F12, home, end, etc. Add a new
  te_fkeystr() that can be used to override the strings.
  
  scterm-sck won't do anything with this, but scterm-teken will use
  teken_get_sequences() to obtain the proper sequence.

Modified:
  head/sys/dev/syscons/scterm-teken.c
  head/sys/dev/syscons/syscons.c
  head/sys/dev/syscons/syscons.h
  head/sys/pc98/cbus/scterm-sck.c
  head/sys/teken/teken.c
  head/sys/teken/teken.h
  head/sys/teken/teken_subr.h

Modified: head/sys/dev/syscons/scterm-teken.c
==============================================================================
--- head/sys/dev/syscons/scterm-teken.c	Wed Nov 11 08:11:21 2009	(r199170)
+++ head/sys/dev/syscons/scterm-teken.c	Wed Nov 11 08:20:19 2009	(r199171)
@@ -38,6 +38,7 @@ __FBSDID("$FreeBSD$");
 #include <sys/kernel.h>
 #include <sys/module.h>
 #include <sys/consio.h>
+#include <sys/kbio.h>
 
 #if defined(__sparc64__) || defined(__powerpc__)
 #include <machine/sc_machdep.h>
@@ -52,14 +53,15 @@ __FBSDID("$FreeBSD$");
 static void scteken_revattr(unsigned char, teken_attr_t *);
 static unsigned int scteken_attr(const teken_attr_t *);
 
-static sc_term_init_t	scteken_init;
-static sc_term_term_t	scteken_term;
-static sc_term_puts_t	scteken_puts;
-static sc_term_ioctl_t	scteken_ioctl;
-static sc_term_default_attr_t scteken_default_attr;
-static sc_term_clear_t	scteken_clear;
-static sc_term_input_t	scteken_input;
-static void		scteken_nop(void);
+static sc_term_init_t		scteken_init;
+static sc_term_term_t		scteken_term;
+static sc_term_puts_t		scteken_puts;
+static sc_term_ioctl_t		scteken_ioctl;
+static sc_term_default_attr_t	scteken_default_attr;
+static sc_term_clear_t		scteken_clear;
+static sc_term_input_t		scteken_input;
+static sc_term_fkeystr_t	scteken_fkeystr;
+static void			scteken_nop(void);
 
 typedef struct {
 	teken_t		ts_teken;
@@ -84,6 +86,7 @@ static sc_term_sw_t sc_term_scteken = {
 	scteken_clear,
 	(sc_term_notify_t *)scteken_nop,
 	scteken_input,
+	scteken_fkeystr,
 };
 
 SCTERM_MODULE(scteken, sc_term_scteken);
@@ -241,6 +244,56 @@ scteken_input(scr_stat *scp, int c, stru
 	return FALSE;
 }
 
+static const char *
+scteken_fkeystr(scr_stat *scp, int c)
+{
+	teken_stat *ts = scp->ts;
+	unsigned int k;
+
+	switch (c) {
+	case FKEY | F(1):  case FKEY | F(2):  case FKEY | F(3):
+	case FKEY | F(4):  case FKEY | F(5):  case FKEY | F(6):
+	case FKEY | F(7):  case FKEY | F(8):  case FKEY | F(9):
+	case FKEY | F(10): case FKEY | F(11): case FKEY | F(12):
+		k = TKEY_F1 + c - (FKEY | F(1));
+		break;
+	case FKEY | F(49):
+		k = TKEY_HOME;
+		break;
+	case FKEY | F(50):
+		k = TKEY_UP;
+		break;
+	case FKEY | F(51):
+		k = TKEY_PAGE_UP;
+		break;
+	case FKEY | F(53):
+		k = TKEY_LEFT;
+		break;
+	case FKEY | F(55):
+		k = TKEY_RIGHT;
+		break;
+	case FKEY | F(57):
+		k = TKEY_END;
+		break;
+	case FKEY | F(58):
+		k = TKEY_DOWN;
+		break;
+	case FKEY | F(59):
+		k = TKEY_PAGE_DOWN;
+		break;
+	case FKEY | F(60):
+		k = TKEY_INSERT;
+		break;
+	case FKEY | F(61):
+		k = TKEY_DELETE;
+		break;
+	default:
+		return (NULL);
+	}
+
+	return (teken_get_sequence(&ts->ts_teken, k));
+}
+
 static void
 scteken_nop(void)
 {

Modified: head/sys/dev/syscons/syscons.c
==============================================================================
--- head/sys/dev/syscons/syscons.c	Wed Nov 11 08:11:21 2009	(r199170)
+++ head/sys/dev/syscons/syscons.c	Wed Nov 11 08:20:19 2009	(r199171)
@@ -625,7 +625,7 @@ sckbdevent(keyboard_t *thiskbd, int even
     struct tty *cur_tty;
     int c, error = 0; 
     size_t len;
-    u_char *cp;
+    const u_char *cp;
 
     sc = (sc_softc_t *)arg;
     /* assert(thiskbd == sc->kbd) */
@@ -664,6 +664,11 @@ sckbdevent(keyboard_t *thiskbd, int even
 	    ttydisc_rint(cur_tty, KEYCHAR(c), 0);
 	    break;
 	case FKEY:  /* function key, return string */
+	    cp = (*sc->cur_scp->tsw->te_fkeystr)(sc->cur_scp, c);
+	    if (cp != NULL) {
+	    	ttydisc_rint_simple(cur_tty, cp, strlen(cp));
+		break;
+	    }
 	    cp = kbdd_get_fkeystr(thiskbd, KEYCHAR(c), &len);
 	    if (cp != NULL)
 	    	ttydisc_rint_simple(cur_tty, cp, len);
@@ -673,9 +678,7 @@ sckbdevent(keyboard_t *thiskbd, int even
 	    ttydisc_rint(cur_tty, KEYCHAR(c), 0);
 	    break;
 	case BKEY:  /* backtab fixed sequence (esc [ Z) */
-	    ttydisc_rint(cur_tty, 0x1b, 0);
-	    ttydisc_rint(cur_tty, '[', 0);
-	    ttydisc_rint(cur_tty, 'Z', 0);
+	    ttydisc_rint_simple(cur_tty, "\x1B[Z", 3);
 	    break;
 	}
 
@@ -1572,7 +1575,7 @@ sc_cngetc(struct consdev *cd)
     static struct fkeytab fkey;
     static int fkeycp;
     scr_stat *scp;
-    u_char *p;
+    const u_char *p;
     int cur_mode;
     int s = spltty();	/* block sckbdevent and scrn_timer while we poll */
     int c;
@@ -1621,6 +1624,13 @@ sc_cngetc(struct consdev *cd)
     case 0:	/* normal char */
 	return KEYCHAR(c);
     case FKEY:	/* function key */
+	p = (*scp->tsw->te_fkeystr)(scp, c);
+	if (p != NULL) {
+	    fkey.len = strlen(p);
+	    bcopy(p, fkey.str, fkey.len);
+	    fkeycp = 1;
+	    return fkey.str[0];
+	}
 	p = kbdd_get_fkeystr(scp->sc->kbd, KEYCHAR(c), (size_t *)&fkeycp);
 	fkey.len = fkeycp;
 	if ((p != NULL) && (fkey.len > 0)) {

Modified: head/sys/dev/syscons/syscons.h
==============================================================================
--- head/sys/dev/syscons/syscons.h	Wed Nov 11 08:11:21 2009	(r199170)
+++ head/sys/dev/syscons/syscons.h	Wed Nov 11 08:20:19 2009	(r199171)
@@ -381,6 +381,7 @@ typedef void	sc_term_notify_t(scr_stat *
 #define SC_TE_NOTIFY_VTSWITCH_IN	0
 #define SC_TE_NOTIFY_VTSWITCH_OUT	1
 typedef int	sc_term_input_t(scr_stat *scp, int c, struct tty *tp);
+typedef const char *sc_term_fkeystr_t(scr_stat *scp, int c);
 
 typedef struct sc_term_sw {
 	LIST_ENTRY(sc_term_sw)	link;
@@ -398,6 +399,7 @@ typedef struct sc_term_sw {
 	sc_term_clear_t		*te_clear;
 	sc_term_notify_t	*te_notify;
 	sc_term_input_t		*te_input;
+	sc_term_fkeystr_t	*te_fkeystr;
 } sc_term_sw_t;
 
 #define SCTERM_MODULE(name, sw)					\

Modified: head/sys/pc98/cbus/scterm-sck.c
==============================================================================
--- head/sys/pc98/cbus/scterm-sck.c	Wed Nov 11 08:11:21 2009	(r199170)
+++ head/sys/pc98/cbus/scterm-sck.c	Wed Nov 11 08:20:19 2009	(r199171)
@@ -94,15 +94,16 @@ typedef struct {
 	color_t		dflt_rev_color;		/* default reverse color */
 } term_stat;
 
-static sc_term_init_t	scterm_init;
-static sc_term_term_t	scterm_term;
-static sc_term_puts_t	scterm_puts;
-static sc_term_ioctl_t	scterm_ioctl;
-static sc_term_reset_t	scterm_reset;
+static sc_term_init_t		scterm_init;
+static sc_term_term_t		scterm_term;
+static sc_term_puts_t		scterm_puts;
+static sc_term_ioctl_t		scterm_ioctl;
+static sc_term_reset_t		scterm_reset;
 static sc_term_default_attr_t	scterm_default_attr;
-static sc_term_clear_t	scterm_clear;
-static sc_term_notify_t	scterm_notify;
-static sc_term_input_t	scterm_input;
+static sc_term_clear_t		scterm_clear;
+static sc_term_notify_t		scterm_notify;
+static sc_term_input_t		scterm_input;
+static sc_term_fkeystr_t	scterm_fkeystr;
 
 static sc_term_sw_t sc_term_sc = {
 	{ NULL, NULL },
@@ -120,6 +121,7 @@ static sc_term_sw_t sc_term_sc = {
 	scterm_clear,
 	scterm_notify,
 	scterm_input,
+	scterm_fkeystr,
 };
 
 SCTERM_MODULE(sc, sc_term_sc);
@@ -1191,6 +1193,13 @@ scterm_input(scr_stat *scp, int c, struc
 	return FALSE;
 }
 
+static const char *
+scterm_fkeystr(scr_stat *scp, int c)
+{
+
+	return (NULL);
+}
+
 /*
  * Calculate hardware attributes word using logical attributes mask and
  * hardware colors

Modified: head/sys/teken/teken.c
==============================================================================
--- head/sys/teken/teken.c	Wed Nov 11 08:11:21 2009	(r199170)
+++ head/sys/teken/teken.c	Wed Nov 11 08:20:19 2009	(r199171)
@@ -49,14 +49,15 @@ static FILE *df;
 #endif /* __FreeBSD__ && _KERNEL */
 
 /* Private flags for t_stateflags. */
-#define	TS_FIRSTDIGIT	0x01	/* First numeric digit in escape sequence. */
-#define	TS_INSERT	0x02	/* Insert mode. */
-#define	TS_AUTOWRAP	0x04	/* Autowrap. */
-#define	TS_ORIGIN	0x08	/* Origin mode. */
-#define	TS_WRAPPED	0x10	/* Next character should be printed on col 0. */
-#define	TS_8BIT		0x20	/* UTF-8 disabled. */
-#define	TS_CONS25	0x40	/* cons25 emulation. */
-#define	TS_INSTRING	0x80	/* Inside string. */
+#define	TS_FIRSTDIGIT	0x0001	/* First numeric digit in escape sequence. */
+#define	TS_INSERT	0x0002	/* Insert mode. */
+#define	TS_AUTOWRAP	0x0004	/* Autowrap. */
+#define	TS_ORIGIN	0x0008	/* Origin mode. */
+#define	TS_WRAPPED	0x0010	/* Next character should be printed on col 0. */
+#define	TS_8BIT		0x0020	/* UTF-8 disabled. */
+#define	TS_CONS25	0x0040	/* cons25 emulation. */
+#define	TS_INSTRING	0x0080	/* Inside string. */
+#define	TS_CURSORKEYS	0x0100	/* Cursor keys mode. */
 
 /* Character that blanks a cell. */
 #define	BLANK	' '
@@ -479,4 +480,64 @@ teken_256to8(teken_color_t c)
 	}
 }
 
+static const char * const special_strings_cons25[] = {
+	[TKEY_UP] = "\x1B[A",		[TKEY_DOWN] = "\x1B[B",
+	[TKEY_LEFT] = "\x1B[D",		[TKEY_RIGHT] = "\x1B[C",
+
+	[TKEY_INSERT] = "\x1B[L",	[TKEY_DELETE] = "\x7F",
+	[TKEY_HOME] = "\x1B[H",		[TKEY_END] = "\x1B[F",
+	[TKEY_PAGE_UP] = "\x1B[I",	[TKEY_PAGE_DOWN] = "\x1B[G",
+
+	[TKEY_F1] = "\x1B[M",		[TKEY_F2] = "\x1B[N",
+	[TKEY_F3] = "\x1B[O",		[TKEY_F4] = "\x1B[P",
+	[TKEY_F5] = "\x1B[Q",		[TKEY_F6] = "\x1B[R",
+	[TKEY_F7] = "\x1B[S",		[TKEY_F8] = "\x1B[T",
+	[TKEY_F9] = "\x1B[U",		[TKEY_F10] = "\x1B[V",
+	[TKEY_F11] = "\x1B[W",		[TKEY_F12] = "\x1B[X",
+};
+
+static const char * const special_strings_ckeys[] = {
+	[TKEY_UP] = "\x1BOA",		[TKEY_DOWN] = "\x1BOB",
+	[TKEY_LEFT] = "\x1BOD",		[TKEY_RIGHT] = "\x1BOC",
+
+	[TKEY_HOME] = "\x1BOH",		[TKEY_END] = "\x1BOF",
+};
+
+static const char * const special_strings_normal[] = {
+	[TKEY_UP] = "\x1B[A",		[TKEY_DOWN] = "\x1B[B",
+	[TKEY_LEFT] = "\x1B[D",		[TKEY_RIGHT] = "\x1B[C",
+
+	[TKEY_INSERT] = "\x1B[2~",	[TKEY_DELETE] = "\x1B[3~",
+	[TKEY_HOME] = "\x1B[H",		[TKEY_END] = "\x1B[F",
+	[TKEY_PAGE_UP] = "\x1B[5~",	[TKEY_PAGE_DOWN] = "\x1B[6~",
+
+	[TKEY_F1] = "\x1BOP",		[TKEY_F2] = "\x1BOQ",
+	[TKEY_F3] = "\x1BOR",		[TKEY_F4] = "\x1BOS",
+	[TKEY_F5] = "\x1B[15~",		[TKEY_F6] = "\x1B[17~",
+	[TKEY_F7] = "\x1B[18~",		[TKEY_F8] = "\x1B[19~",
+	[TKEY_F9] = "\x1B[20~",		[TKEY_F10] = "\x1B[21~",
+	[TKEY_F11] = "\x1B[23~",	[TKEY_F12] = "\x1B[24~",
+};
+
+const char *
+teken_get_sequence(teken_t *t, unsigned int k)
+{
+
+	/* Cons25 mode. */
+	if (t->t_stateflags & TS_CONS25 &&
+	    k < sizeof special_strings_cons25 / sizeof(char *))
+		return (special_strings_cons25[k]);
+
+	/* Cursor keys mode. */
+	if (t->t_stateflags & TS_CURSORKEYS &&
+	    k < sizeof special_strings_ckeys / sizeof(char *))
+		return (special_strings_ckeys[k]);
+
+	/* Default xterm sequences. */
+	if (k < sizeof special_strings_normal / sizeof(char *))
+		return (special_strings_normal[k]);
+	
+	return (NULL);
+}
+
 #include "teken_state.h"

Modified: head/sys/teken/teken.h
==============================================================================
--- head/sys/teken/teken.h	Wed Nov 11 08:11:21 2009	(r199170)
+++ head/sys/teken/teken.h	Wed Nov 11 08:20:19 2009	(r199171)
@@ -89,15 +89,14 @@ typedef void tf_fill_t(void *, const tek
 typedef void tf_copy_t(void *, const teken_rect_t *, const teken_pos_t *);
 typedef void tf_param_t(void *, int, unsigned int);
 #define	TP_SHOWCURSOR	0
-#define	TP_CURSORKEYS	1
-#define	TP_KEYPADAPP	2
-#define	TP_AUTOREPEAT	3
-#define	TP_SWITCHVT	4
-#define	TP_132COLS	5
-#define	TP_SETBELLPD	6
+#define	TP_KEYPADAPP	1
+#define	TP_AUTOREPEAT	2
+#define	TP_SWITCHVT	3
+#define	TP_132COLS	4
+#define	TP_SETBELLPD	5
 #define	TP_SETBELLPD_PITCH(pd)		((pd) >> 16)
 #define	TP_SETBELLPD_DURATION(pd)	((pd) & 0xffff)
-#define	TP_MOUSE	7
+#define	TP_MOUSE	6
 typedef void tf_respond_t(void *, const void *, size_t);
 
 typedef struct {
@@ -168,6 +167,33 @@ void	teken_set_curattr(teken_t *, const 
 void	teken_set_defattr(teken_t *, const teken_attr_t *);
 void	teken_set_winsize(teken_t *, const teken_pos_t *);
 
+/* Key input escape sequences. */
+#define	TKEY_UP		0x00
+#define	TKEY_DOWN	0x01
+#define	TKEY_LEFT	0x02
+#define	TKEY_RIGHT	0x03
+
+#define	TKEY_INSERT	0x04
+#define	TKEY_DELETE	0x05
+#define	TKEY_HOME	0x06
+#define	TKEY_END	0x07
+#define	TKEY_PAGE_UP	0x08
+#define	TKEY_PAGE_DOWN	0x09
+
+#define	TKEY_F1		0x0a
+#define	TKEY_F2		0x0b
+#define	TKEY_F3		0x0c
+#define	TKEY_F4		0x0d
+#define	TKEY_F5		0x0e
+#define	TKEY_F6		0x0f
+#define	TKEY_F7		0x10
+#define	TKEY_F8		0x11
+#define	TKEY_F9		0x12
+#define	TKEY_F10	0x13
+#define	TKEY_F11	0x14
+#define	TKEY_F12	0x15
+const char *teken_get_sequence(teken_t *, unsigned int);
+
 /* Legacy features. */
 void	teken_set_8bit(teken_t *);
 void	teken_set_cons25(teken_t *);

Modified: head/sys/teken/teken_subr.h
==============================================================================
--- head/sys/teken/teken_subr.h	Wed Nov 11 08:11:21 2009	(r199170)
+++ head/sys/teken/teken_subr.h	Wed Nov 11 08:20:19 2009	(r199171)
@@ -903,7 +903,7 @@ teken_subr_reset_dec_mode(teken_t *t, un
 
 	switch (cmd) {
 	case 1: /* Cursor keys mode. */
-		teken_funcs_param(t, TP_CURSORKEYS, 0);
+		t->t_stateflags &= ~TS_CURSORKEYS;
 		break;
 	case 2: /* DECANM: ANSI/VT52 mode. */
 		teken_printf("DECRST VT52\n");
@@ -1052,7 +1052,7 @@ teken_subr_set_dec_mode(teken_t *t, unsi
 
 	switch (cmd) {
 	case 1: /* Cursor keys mode. */
-		teken_funcs_param(t, TP_CURSORKEYS, 1);
+		t->t_stateflags |= TS_CURSORKEYS;
 		break;
 	case 2: /* DECANM: ANSI/VT52 mode. */
 		teken_printf("DECSET VT52\n");


More information about the svn-src-head mailing list