#include "keymap.h"
#include "mapping.h"
#include "mutt_crypt.h"
+#ifdef USE_IMAP
+#include "imap/imap.h"
+#endif
#include <stdlib.h>
#include <string.h>
{ "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
#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 }
};
*/
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];
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? */
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);
while (ch != ERR && ch != ctrl ('G'));
mutt_flushinp();
+ mutt_clear_error();
}