diff --git a/lib/tty/key.c b/lib/tty/key.c index 0d15a7960..ca9f1ac73 100644 --- a/lib/tty/key.c +++ b/lib/tty/key.c @@ -2,7 +2,7 @@ Keyboard support routines. Copyright (C) 1994, 1995, 1998, 1999, 2000, 2001, 2002, 2003, 2004, - 2005, 2006, 2007, 2009, 2010, 2011 + 2005, 2006, 2007, 2009, 2010, 2011, 2013 The Free Software Foundation, Inc. Written by: @@ -10,6 +10,8 @@ Janne Kukonlehto, 1994, 1995 Jakub Jelinek, 1995 Norbert Warmuth, 1997 + Denys Vlasenko , 2013 + Slava Zanko , 2013 This file is part of the Midnight Commander. @@ -1747,7 +1749,7 @@ get_key_code (int no_delay) int d; d = *pending_keys++; - while (d == ESC_CHAR && *pending_keys != '\0') + while (d == ESC_CHAR) d = ALT (*pending_keys++); if (*pending_keys == '\0') @@ -1828,49 +1830,12 @@ get_key_code (int no_delay) this = keys->child; } } + while (this != NULL) { if (c == this->ch) { - if (this->child) - { - if (!push_char (c)) - { - pending_keys = seq_buffer; - goto pend_send; - } - parent = this; - this = this->child; - if (parent->action == MCKEY_ESCAPE && old_esc_mode) - { - if (no_delay) - { - GET_TIME (esctime); - if (this == NULL) - { - /* Shouldn't happen */ - fputs ("Internal error\n", stderr); - exit (EXIT_FAILURE); - } - goto nodelay_try_again; - } - esctime.tv_sec = -1; - c = xgetch_second (); - if (c == -1) - { - pending_keys = seq_append = NULL; - this = NULL; - return ESC_CHAR; - } - } - else - { - if (no_delay) - goto nodelay_try_again; - c = tty_lowlevel_getch (); - } - } - else + if (!this->child) { /* We got a complete match, return and reset search */ int code; @@ -1880,36 +1845,67 @@ get_key_code (int no_delay) this = NULL; return correct_key_code (code); } - } - else - { - if (this->next != NULL) - this = this->next; - else + /* No match yet, but it may be a prefix for a valid seq */ + if (!push_char (c)) { - if ((parent != NULL) && (parent->action == MCKEY_ESCAPE)) - { - /* Convert escape-digits to F-keys */ - if (g_ascii_isdigit (c)) - c = KEY_F (c - '0'); - else if (c == ' ') - c = ESC_CHAR; - else - c = ALT (c); - - pending_keys = seq_append = NULL; - this = NULL; - return correct_key_code (c); - } - /* Did not find a match or {c} was changed in the if above, - so we have to return everything we had skipped - */ - push_char (c); pending_keys = seq_buffer; goto pend_send; } + parent = this; + this = this->child; + if (parent->action == MCKEY_ESCAPE && old_esc_mode) + { + if (no_delay) + { + GET_TIME (esctime); + goto nodelay_try_again; + } + esctime.tv_sec = -1; + c = xgetch_second (); + if (c == -1) + { + pending_keys = seq_append = NULL; + this = NULL; + return ESC_CHAR; + } + continue; + } + if (no_delay) + goto nodelay_try_again; + c = tty_lowlevel_getch (); + continue; } - } + + /* c != this->ch. Try other keys with this prefix */ + if (this->next != NULL) + { + this = this->next; + continue; + } + + /* No match found. Is it one of our ESC specials? */ + if ((parent != NULL) && (parent->action == MCKEY_ESCAPE)) + { + /* Convert escape-digits to F-keys */ + if (g_ascii_isdigit (c)) + c = KEY_F (c - '0'); + else if (c == ' ') + c = ESC_CHAR; + else + c = ALT (c); + + pending_keys = seq_append = NULL; + this = NULL; + return correct_key_code (c); + } + + /* Unknown sequence. Maybe a prefix of a longer one. Save it. */ + push_char (c); + pending_keys = seq_buffer; + goto pend_send; + + } /* while (this != NULL) */ + this = NULL; return correct_key_code (c); }