summaryrefslogtreecommitdiffstats
path: root/sys
diff options
context:
space:
mode:
authored <ed@FreeBSD.org>2009-11-11 08:20:19 +0000
committered <ed@FreeBSD.org>2009-11-11 08:20:19 +0000
commitfcc8740e5f98d5a779e7925466919cb22d750137 (patch)
tree0727d54b551a5437ffd2abdee66ef48b4016605c /sys
parent74d077dc934272cd3839f573aeeb27a6c77c4273 (diff)
downloadFreeBSD-src-fcc8740e5f98d5a779e7925466919cb22d750137.zip
FreeBSD-src-fcc8740e5f98d5a779e7925466919cb22d750137.tar.gz
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.
Diffstat (limited to 'sys')
-rw-r--r--sys/dev/syscons/scterm-teken.c69
-rw-r--r--sys/dev/syscons/syscons.c20
-rw-r--r--sys/dev/syscons/syscons.h2
-rw-r--r--sys/pc98/cbus/scterm-sck.c25
-rw-r--r--sys/teken/teken.c77
-rw-r--r--sys/teken/teken.h40
-rw-r--r--sys/teken/teken_subr.h4
7 files changed, 199 insertions, 38 deletions
diff --git a/sys/dev/syscons/scterm-teken.c b/sys/dev/syscons/scterm-teken.c
index 5fafccd..12b040e 100644
--- a/sys/dev/syscons/scterm-teken.c
+++ b/sys/dev/syscons/scterm-teken.c
@@ -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, struct tty *tp)
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)
{
diff --git a/sys/dev/syscons/syscons.c b/sys/dev/syscons/syscons.c
index 836db55..99d4246 100644
--- a/sys/dev/syscons/syscons.c
+++ b/sys/dev/syscons/syscons.c
@@ -625,7 +625,7 @@ sckbdevent(keyboard_t *thiskbd, int event, void *arg)
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 event, void *arg)
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 event, void *arg)
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)) {
diff --git a/sys/dev/syscons/syscons.h b/sys/dev/syscons/syscons.h
index abac2ac..2f05755 100644
--- a/sys/dev/syscons/syscons.h
+++ b/sys/dev/syscons/syscons.h
@@ -381,6 +381,7 @@ typedef void sc_term_notify_t(scr_stat *scp, int event);
#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) \
diff --git a/sys/pc98/cbus/scterm-sck.c b/sys/pc98/cbus/scterm-sck.c
index ce2324f..b4bf70f 100644
--- a/sys/pc98/cbus/scterm-sck.c
+++ b/sys/pc98/cbus/scterm-sck.c
@@ -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, struct tty *tp)
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
diff --git a/sys/teken/teken.c b/sys/teken/teken.c
index 81b8ac0..d50edc8 100644
--- a/sys/teken/teken.c
+++ b/sys/teken/teken.c
@@ -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"
diff --git a/sys/teken/teken.h b/sys/teken/teken.h
index 22b5745..e129d47 100644
--- a/sys/teken/teken.h
+++ b/sys/teken/teken.h
@@ -89,15 +89,14 @@ typedef void tf_fill_t(void *, const teken_rect_t *, teken_char_t,
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 teken_attr_t *);
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 *);
diff --git a/sys/teken/teken_subr.h b/sys/teken/teken_subr.h
index 4caa500..6bad71e 100644
--- a/sys/teken/teken_subr.h
+++ b/sys/teken/teken_subr.h
@@ -903,7 +903,7 @@ teken_subr_reset_dec_mode(teken_t *t, unsigned int cmd)
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, unsigned int cmd)
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");
OpenPOWER on IntegriCloud