From owner-svn-src-head@FreeBSD.ORG Wed Nov 11 08:20:20 2009 Return-Path: Delivered-To: svn-src-head@freebsd.org Received: from mx1.freebsd.org (mx1.freebsd.org [IPv6:2001:4f8:fff6::34]) by hub.freebsd.org (Postfix) with ESMTP id 0E420106566B; Wed, 11 Nov 2009 08:20:20 +0000 (UTC) (envelope-from ed@FreeBSD.org) Received: from svn.freebsd.org (svn.freebsd.org [IPv6:2001:4f8:fff6::2c]) by mx1.freebsd.org (Postfix) with ESMTP id F07088FC17; Wed, 11 Nov 2009 08:20:19 +0000 (UTC) Received: from svn.freebsd.org (localhost [127.0.0.1]) by svn.freebsd.org (8.14.3/8.14.3) with ESMTP id nAB8KJO0087100; Wed, 11 Nov 2009 08:20:19 GMT (envelope-from ed@svn.freebsd.org) Received: (from ed@localhost) by svn.freebsd.org (8.14.3/8.14.3/Submit) id nAB8KJeu087092; Wed, 11 Nov 2009 08:20:19 GMT (envelope-from ed@svn.freebsd.org) Message-Id: <200911110820.nAB8KJeu087092@svn.freebsd.org> From: Ed Schouten Date: Wed, 11 Nov 2009 08:20:19 +0000 (UTC) To: src-committers@freebsd.org, svn-src-all@freebsd.org, svn-src-head@freebsd.org X-SVN-Group: head MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit Cc: Subject: svn commit: r199171 - in head/sys: dev/syscons pc98/cbus teken X-BeenThere: svn-src-head@freebsd.org X-Mailman-Version: 2.1.5 Precedence: list List-Id: SVN commit messages for the src tree for head/-current List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , X-List-Received-Date: Wed, 11 Nov 2009 08:20:20 -0000 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 #include #include +#include #if defined(__sparc64__) || defined(__powerpc__) #include @@ -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");