diff options
Diffstat (limited to 'sys/dev/syscons')
-rw-r--r-- | sys/dev/syscons/scterm-teken.c | 69 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.c | 20 | ||||
-rw-r--r-- | sys/dev/syscons/syscons.h | 2 |
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) \ |