summaryrefslogtreecommitdiffstats
path: root/sys/dev/syscons
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/dev/syscons
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/dev/syscons')
-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
3 files changed, 78 insertions, 13 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) \
OpenPOWER on IntegriCloud