<<< Date Index >>>     <<< Thread Index >>>

Re: [PATCH] experimental support for ncurses extended keys



This looks pretty non-disruptive and useful. I'm for it.

On Tuesday, 06 April 2010 at 18:13, Michael Elkins wrote:
> On Sun, Apr 04, 2010 at 11:47:05AM -0700, Michael Elkins wrote:
> > Note that at least under Ubuntu 9.10, the terminfo entry for xterm-new
> > doesn't seem to include definition for the Shift-ed versions, so they
> > end up showing as some high numbered function key.
> 
> Updated patch to fix the shift-ed function keys.  (thx: Thomas Dickey
> for pointing out my error).
> 
> me

> diff -r 889aa698cc49 keymap.c
> +++ b/keymap.c        Tue Apr 06 18:11:00 2010 -0700
> @@ -89,6 +89,39 @@
>  #ifdef KEY_NEXT
>    { "<Next>",    KEY_NEXT },
>  #endif  
> +#ifdef NCURSES_VERSION
> +  /* extensions supported by ncurses.  values are filled in during 
> initialization */
> +
> +  /* CTRL+key */
> +  { "<C-Up>",        -1 },
> +  { "<C-Down>",      -1 },
> +  { "<C-Left>", -1 },
> +  { "<C-Right>",     -1 },
> +  { "<C-Home>",      -1 },
> +  { "<C-End>",       -1 },
> +  { "<C-Next>",      -1 },
> +  { "<C-Prev>",      -1 },
> +
> +  /* SHIFT+key */
> +  { "<S-Up>",        -1 },
> +  { "<S-Down>",      -1 },
> +  { "<S-Left>", -1 },
> +  { "<S-Right>",     -1 },
> +  { "<S-Home>",      -1 },
> +  { "<S-End>",       -1 },
> +  { "<S-Next>",      -1 },
> +  { "<S-Prev>",      -1 },
> +
> +  /* ALT+key */
> +  { "<A-Up>",        -1 },
> +  { "<A-Down>",      -1 },
> +  { "<A-Left>", -1 },
> +  { "<A-Right>",     -1 },
> +  { "<A-Home>",      -1 },
> +  { "<A-End>",       -1 },
> +  { "<A-Next>",      -1 },
> +  { "<A-Prev>",      -1 },
> +#endif /* NCURSES_VERSION */
>    { NULL,    0 }
>  };
>  
> @@ -144,7 +177,7 @@
>    return -1;
>  }
>  
> -static int parsekeys (char *str, keycode_t *d, int max)
> +static int parsekeys (const char *str, keycode_t *d, int max)
>  {
>    int n, len = max;
>    char buff[SHORT_STRING];
> @@ -573,6 +606,97 @@
>    return (map);
>  }
>  
> +#ifdef NCURSES_VERSION
> +struct extkey {
> +  const char *name;
> +  const char *sym;
> +};
> +
> +static const struct extkey ExtKeys[] = {
> +  { "<c-up>", "kUP5" },
> +  { "<s-up>", "kUP" },
> +  { "<a-up>", "kUP3" },
> +
> +  { "<s-down>", "kDN" },
> +  { "<a-down>", "kDN3" },
> +  { "<c-down>", "kDN5" },
> +
> +  { "<c-right>", "kRIT5" },
> +  { "<s-right>", "kRIT" },
> +  { "<a-right>", "kRIT3" },
> +
> +  { "<s-left>", "kLFT" },
> +  { "<a-left>", "kLFT3" },
> +  { "<c-left>", "kLFT5" },
> +
> +  { "<s-home>", "kHOM" },
> +  { "<a-home>", "kHOM3" },
> +  { "<c-home>", "kHOM5" },
> +
> +  { "<s-end>", "kEND" },
> +  { "<a-end>", "kEND3" },
> +  { "<c-end>", "kEND5" },
> +
> +  { "<s-next>", "kNXT" },
> +  { "<a-next>", "kNXT3" },
> +  { "<c-next>", "kNXT5" },
> +
> +  { "<s-prev>", "kPRV" },
> +  { "<a-prev>", "kPRV3" },
> +  { "<c-prev>", "kPRV5" },
> +
> +  { 0, 0 }
> +};
> +
> +/* Look up Mutt's name for a key and find the ncurses extended name for it */
> +static const char *find_ext_name(const char *key)
> +{
> +  int j;
> +
> +  for (j = 0; ExtKeys[j].name; ++j)
> +  {
> +    if (strcasecmp(key, ExtKeys[j].name) == 0)
> +      return ExtKeys[j].sym;
> +  }
> +  return 0;
> +}
> +#endif /* NCURSES_VERSION */
> +
> +/* Determine the keycodes for ncurses extended keys and fill in the KeyNames 
> array.
> + *
> + * This function must be called *after* initscr(), or tigetstr() returns -1. 
>  This
> + * creates a bit of a chicken-and-egg problem because km_init() is called 
> prior to
> + * start_curses().  This means that the default keybindings can't include 
> any of the
> + * extended keys because they won't be defined until later.
> + */
> +void init_extended_keys(void)
> +{
> +#ifdef NCURSES_VERSION
> +  int j;
> +
> +  use_extended_names(TRUE);
> +
> +  for (j = 0; KeyNames[j].name; ++j)
> +  {
> +    if (KeyNames[j].value == -1)
> +    {
> +      const char *keyname = find_ext_name(KeyNames[j].name);
> +
> +      if (keyname)
> +      {
> +     char *s = tigetstr(keyname);
> +     if (s && (long)(s) != -1)
> +     {
> +       int code = key_defined(s);
> +       if (code > 0)
> +         KeyNames[j].value = code;
> +     }
> +      }
> +    }
> +  }
> +#endif
> +}
> +
>  void km_init (void)
>  {
>    memset (Keymaps, 0, sizeof (struct keymap_t *) * MENU_MAX);
> diff -r 889aa698cc49 keymap.h
> +++ b/keymap.h        Tue Apr 06 18:11:00 2010 -0700
> @@ -31,6 +31,8 @@
>  void km_bindkey (char *, int, int);
>  int km_dokey (int);
>  
> +void init_extended_keys(void);
> +
>  /* entry in the keymap tree */
>  struct keymap_t
>  {
> diff -r 889aa698cc49 main.c
> +++ b/main.c  Tue Apr 06 18:11:00 2010 -0700
> @@ -515,6 +515,7 @@
>  #if HAVE_META
>    meta (stdscr, TRUE);
>  #endif
> +init_extended_keys();
>  }
>  
>  #define M_IGNORE  (1<<0)     /* -z */