]> git.llucax.com Git - software/mutt-debian.git/blobdiff - keymap.c
sidebar: don't overwrite the status if status_on_top is enabled (Closes: 494735)
[software/mutt-debian.git] / keymap.c
index ca23443d41690b31e151714239342a2874396818..70765b11191ea97a60bf4bfd4537c2121f99627e 100644 (file)
--- a/keymap.c
+++ b/keymap.c
@@ -26,6 +26,9 @@
 #include "keymap.h"
 #include "mapping.h"
 #include "mutt_crypt.h"
+#ifdef USE_IMAP
+#include "imap/imap.h"
+#endif
 
 #include <stdlib.h>
 #include <string.h>
@@ -44,7 +47,7 @@ struct mapping_t Menus[] = {
  { "postpone", MENU_POST },
  { "pgp",      MENU_PGP },
  { "smime",    MENU_SMIME },
-#ifdef HAVE_GPGME
+#ifdef CRYPT_BACKEND_GPGME
  { "key_select_pgp",   MENU_KEY_SELECT_PGP },
  { "key_select_smime", MENU_KEY_SELECT_SMIME },
 #endif
@@ -86,6 +89,39 @@ static struct mapping_t KeyNames[] = {
 #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 }
 };
 
@@ -131,17 +167,19 @@ static int parse_fkey(char *s)
  */
 static int parse_keycode (const char *s)
 {
-  if (isdigit ((unsigned char) s[1]) &&
-      isdigit ((unsigned char) s[2]) &&
-      isdigit ((unsigned char) s[3]) &&
-      s[4] == '>')
-  {
-    return (s[3] - '0') + (s[2] - '0') * 8 + (s[1] - '0') * 64;
-  }
-  return -1;
+    const char *endChar;
+    long int result = strtol(s+1, &endChar, 8);
+    /* allow trailing whitespace, eg.  < 1001 > */
+    while (ISSPACE(*endChar))
+       ++endChar;
+    /* negative keycodes don't make sense, also detect overflow */
+    if (*endChar != '>' || result < 0 || result == LONG_MAX) {
+       return -1;
+    }
+    return result;
 }
 
-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];
@@ -384,17 +422,39 @@ int km_dokey (int menu)
 
   FOREVER
   {
-    /* ncurses doesn't return on resized screen when timeout is set to zero */
-    if (menu != MENU_EDITOR)
-      timeout ((Timeout > 0 ? Timeout : 60) * 1000);
+    i = Timeout > 0 ? Timeout : 60;
+#ifdef USE_IMAP
+    /* keepalive may need to run more frequently than Timeout allows */
+    if (ImapKeepalive)
+    {
+      if (ImapKeepalive >= i)
+       imap_keepalive ();
+      else
+       while (ImapKeepalive && ImapKeepalive < i)
+       {
+         timeout (ImapKeepalive * 1000);
+         tmp = mutt_getch ();
+         timeout (-1);
+         if (tmp.ch != -2)
+           /* something other than timeout */
+           goto gotkey;
+         i -= ImapKeepalive;
+         imap_keepalive ();
+       }
+    }
+#endif
 
+    timeout (i * 1000);
     tmp = mutt_getch();
+    timeout (-1);
 
-    if (menu != MENU_EDITOR)
-      timeout (-1); /* restore blocking operation */
+    /* hide timeouts from line editor */
+    if (menu == MENU_EDITOR && tmp.ch == -2)
+      continue;
 
+  gotkey:
     LastKey = tmp.ch;
-    if (LastKey == -1)
+    if (LastKey < 0)
       return -1;
 
     /* do we have an op already? */
@@ -548,6 +608,97 @@ struct keymap_t *km_find_func (int menu, int func)
   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);
@@ -975,4 +1126,5 @@ void mutt_what_key (void)
   while (ch != ERR && ch != ctrl ('G'));
 
   mutt_flushinp();
+  mutt_clear_error();
 }