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");
_______________________________________________
svn-src-all@freebsd.org mailing list
http://lists.freebsd.org/mailman/listinfo/svn-src-all
To unsubscribe, send any mail to "svn-src-all-unsubscr...@freebsd.org"

Reply via email to