------------------------------------------------------------ revno: 4098 committer: Andreas Vogel branch nick: 01-menuentry_enhanced_hotkeys timestamp: Thu 2012-03-01 22:38:32 +0100 message: * grub-core/commands/menuentry.c: enhanced hotkey handling: - new static function parse_key() - hotkey aliases are now case insensitive - additional hotkey aliases - handling now and modifiers for hotkeys diff: === modified file 'grub-core/commands/menuentry.c' --- grub-core/commands/menuentry.c 2012-02-26 16:28:05 +0000 +++ grub-core/commands/menuentry.c 2012-03-01 21:38:32 +0000 @@ -45,24 +45,110 @@ int key; } hotkey_aliases[] = { - {"backspace", '\b'}, - {"tab", '\t'}, - {"delete", GRUB_TERM_KEY_DC}, - {"insert", GRUB_TERM_KEY_INSERT}, - {"f1", GRUB_TERM_KEY_F1}, - {"f2", GRUB_TERM_KEY_F2}, - {"f3", GRUB_TERM_KEY_F3}, - {"f4", GRUB_TERM_KEY_F4}, - {"f5", GRUB_TERM_KEY_F5}, - {"f6", GRUB_TERM_KEY_F6}, - {"f7", GRUB_TERM_KEY_F7}, - {"f8", GRUB_TERM_KEY_F8}, - {"f9", GRUB_TERM_KEY_F9}, - {"f10", GRUB_TERM_KEY_F10}, - {"f11", GRUB_TERM_KEY_F11}, - {"f12", GRUB_TERM_KEY_F12}, + { "backspace", '\b'}, + { "tab", '\t'}, + { "delete", GRUB_TERM_KEY_DC }, + { "insert", GRUB_TERM_KEY_INSERT }, + { "up", GRUB_TERM_KEY_UP }, + { "down", GRUB_TERM_KEY_DOWN }, + { "left", GRUB_TERM_KEY_LEFT }, + { "right", GRUB_TERM_KEY_RIGHT }, + { "prev", GRUB_TERM_KEY_PPAGE }, + { "next", GRUB_TERM_KEY_NPAGE }, + { "home", GRUB_TERM_KEY_HOME }, + { "end", GRUB_TERM_KEY_END }, + { "f1", GRUB_TERM_KEY_F1 }, + { "f2", GRUB_TERM_KEY_F2 }, + { "f3", GRUB_TERM_KEY_F3 }, + { "f4", GRUB_TERM_KEY_F4 }, + { "f5", GRUB_TERM_KEY_F5 }, + { "f6", GRUB_TERM_KEY_F6 }, + { "f7", GRUB_TERM_KEY_F7 }, + { "f8", GRUB_TERM_KEY_F8 }, + { "f9", GRUB_TERM_KEY_F9 }, + { "f10", GRUB_TERM_KEY_F10 }, + { "f11", GRUB_TERM_KEY_F11 }, + { "f12", GRUB_TERM_KEY_F12 }, }; + +/* Parse the given string and return a GRUB_TERM key. + The given string can be one of the predefined key names (aliases), + otherwise the first character of the given str is taken as key. + Modifiers like "" or "" are handled. They may appear + in any order but need to be in front of the alias or key. + Spaces between the modifiers and key are silently ignored. + Comparison with alias names is case independent. */ + +static int +parse_key (const char *string) +{ + char *str, *ptr, *keystr; + int key = 0; + int i; + + if (string == 0 || *string == 0) + return 0; + + str = grub_strdup (string); + if (!str) + return 0; + +#define STRING_CTRL "" +#define STRING_SHIFT "" + + /* check for CTRL modifier */ + ptr = grub_strstr (str, STRING_CTRL); + if (ptr) + { + /* replace modifier string with spaces */ + for (i = 0; i < grub_strlen (STRING_CTRL); i++) + *(ptr + i) = ' '; + key |= GRUB_TERM_CTRL; + } + + /* check for SHIFT modifier */ + ptr = grub_strstr (str, STRING_SHIFT); + if (ptr) + { + /* replace modifier string with spaces */ + for (i = 0; i < grub_strlen (STRING_SHIFT); i++) + *(ptr + i) = ' '; + key |= GRUB_TERM_SHIFT; + } + + /* remove/zero trailing spaces */ + for (ptr = str + grub_strlen (str) - 1; ptr >= str && *ptr == ' '; ptr--) + *ptr = 0; + + /* skip leading spaces */ + for (ptr = str; *ptr == ' '; ptr++) /*NOTHING*/; + + /* the remaining chars are the real key string */ + keystr = ptr; + + /* check if the key string is an alias name */ + for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++) + { + /* case is not significant for key aliases */ + if (grub_strcasecmp (keystr, hotkey_aliases[i].name) == 0) + { + key |= hotkey_aliases[i].key; + break; + } + } + + if (i == ARRAY_SIZE (hotkey_aliases)) + { + /* no alias matched, so use the first char in the given string as the key */ + key |= keystr[0]; + } + + grub_free (str); + + return key; +} + /* Add a menu entry to the current menu context (as given by the environment variable data slot `menu'). As the configuration file is read, the script parser calls this when a menu entry is to be created. */ @@ -117,17 +203,7 @@ } if (hotkey) - { - unsigned i; - for (i = 0; i < ARRAY_SIZE (hotkey_aliases); i++) - if (grub_strcmp (hotkey, hotkey_aliases[i].name) == 0) - { - menu_hotkey = hotkey_aliases[i].key; - break; - } - if (i == ARRAY_SIZE (hotkey_aliases)) - menu_hotkey = hotkey[0]; - } + menu_hotkey = parse_key (hotkey); if (! argc) {