From: H. Peter Anvin Date: Mon, 11 Apr 2011 21:59:45 +0000 (-0700) Subject: menu: Add "menu hiddenkey" to make terminating menu hidden a command X-Git-Tag: syslinux-4.04~10 X-Git-Url: http://review.tizen.org/git/?a=commitdiff_plain;h=a8e74b2834664543166744cf0832e1d6db36347f;p=profile%2Fivi%2Fsyslinux.git menu: Add "menu hiddenkey" to make terminating menu hidden a command Use "menu hiddenkey" together with "menu hidden" for a one-keystroke action. Signed-off-by: H. Peter Anvin --- diff --git a/com32/libutil/Makefile b/com32/libutil/Makefile index 02789ca..7a6b527 100644 --- a/com32/libutil/Makefile +++ b/com32/libutil/Makefile @@ -32,7 +32,8 @@ topdir = ../.. include ../MCONFIG -LIBOBJS = ansiline.o ansiraw.o get_key.o sha1hash.o unbase64.o \ +LIBOBJS = ansiline.o ansiraw.o get_key.o keyname.o \ + sha1hash.o unbase64.o \ md5.o crypt-md5.o sha256crypt.o sha512crypt.o base64.o LNXLIBOBJS = $(patsubst %.o,%.lo,$(LIBOBJS)) diff --git a/com32/libutil/include/getkey.h b/com32/libutil/include/getkey.h index 52312a2..a46de81 100644 --- a/com32/libutil/include/getkey.h +++ b/com32/libutil/include/getkey.h @@ -75,6 +75,10 @@ #define KEY_INSERT 0x0128 #define KEY_DELETE 0x0129 +#define KEY_MAX 0x012a + int get_key(FILE *, clock_t); +int key_name_to_code(const char *); +const char *key_code_to_name(int); #endif /* LIBUTIL_GETKEY_H */ diff --git a/com32/libutil/keyname.c b/com32/libutil/keyname.c new file mode 100644 index 0000000..6aebbd5 --- /dev/null +++ b/com32/libutil/keyname.c @@ -0,0 +1,133 @@ +/* ----------------------------------------------------------------------- * + * + * Copyright 2011 Intel Corporation; author: H. Peter Anvin + * + * Permission is hereby granted, free of charge, to any person + * obtaining a copy of this software and associated documentation + * files (the "Software"), to deal in the Software without + * restriction, including without limitation the rights to use, + * copy, modify, merge, publish, distribute, sublicense, and/or + * sell copies of the Software, and to permit persons to whom + * the Software is furnished to do so, subject to the following + * conditions: + * + * The above copyright notice and this permission notice shall + * be included in all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, + * EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES + * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND + * NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT + * HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, + * WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING + * FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR + * OTHER DEALINGS IN THE SOFTWARE. + * + * ----------------------------------------------------------------------- */ + +/* + * keyname.c + * + * Conversion between strings and get_key() key numbers. + */ + +#include +#include +#include +#include +#include +#include +#include +#include +#include + +struct keyname { + const char *string; + int key; +}; + +static const struct keyname key_names[] = { + { "Backspace", KEY_BACKSPACE }, + { "Tab", KEY_TAB }, + { "Enter", KEY_ENTER }, + { "Esc", KEY_ESC }, + { "Escape", KEY_ESC }, + { "Space", ' ' }, + { "^?", KEY_DEL }, + { "F1", KEY_F1 }, + { "F2", KEY_F2}, + { "F3", KEY_F3 }, + { "F4", KEY_F4 }, + { "F5", KEY_F5 }, + { "F6", KEY_F6 }, + { "F7", KEY_F7 }, + { "F8", KEY_F8 }, + { "F9", KEY_F9 }, + { "F10", KEY_F10 }, + { "F11", KEY_F11 }, + { "F12", KEY_F12 }, + { "Up", KEY_UP }, + { "Down", KEY_DOWN }, + { "Left", KEY_LEFT }, + { "Right", KEY_RIGHT }, + { "PgUp", KEY_PGUP }, + { "PgDn", KEY_PGDN }, + { "Home", KEY_HOME }, + { "End", KEY_END }, + { "Insert", KEY_INSERT }, + { "Delete", KEY_DELETE }, + { NULL, KEY_NONE } +}; + +int key_name_to_code(const char *code) +{ + const struct keyname *name; + + if (code[0] && !code[1]) { + /* Single character */ + return (unsigned char)code[0]; + } else if (code[0] == '^' && code[1] && !code[2]) { + /* Control character */ + if (code[1] == '?') + return 0x7f; + else + return (unsigned char)code[1] & 0x9f; + } + + + for (name = key_names; name->string; name++) { + if (!strcasecmp(name->string, code)) + break; + } + return name->key; /* KEY_NONE at end of array */ +} + +const char *key_code_to_name(int key) +{ + static char buf[4]; + const struct keyname *name; + + if (key < 0) + return NULL; + + if (key < 0x100 && key != ' ') { + if (key == 0x7f) { + return "^?"; + } else if (key & 0x60) { + buf[0] = key; + buf[1] = '\0'; + } else { + buf[0] = '^'; + buf[1] = key | 0x40; + buf[2] = '\0'; + } + return buf; + } + + for (name = key_names; name->string; name++) { + if (key == name->key) + return name->string; + } + + return NULL; +} diff --git a/com32/menu/menu.h b/com32/menu/menu.h index 36c5669..1db4d7c 100644 --- a/com32/menu/menu.h +++ b/com32/menu/menu.h @@ -26,6 +26,7 @@ #include #include #include +#include #include "refstr.h" /* #define DEBUG 1 */ @@ -186,6 +187,7 @@ extern int shiftkey; extern int hiddenmenu; extern int clearmenu; extern long long totaltimeout; +extern const char *hide_key[KEY_MAX]; void parse_configs(char **argv); int draw_background(const char *filename); diff --git a/com32/menu/menumain.c b/com32/menu/menumain.c index 06725f3..df1eb18 100644 --- a/com32/menu/menumain.c +++ b/com32/menu/menumain.c @@ -727,7 +727,7 @@ static const char *do_hidden_menu(void) key = mygetkey(this_timeout); if (key != KEY_NONE) - return NULL; /* Key pressed */ + return hide_key[key]; /* NULL if no MENU HIDEKEY in effect */ timeout_left -= this_timeout; } diff --git a/com32/menu/readconfig.c b/com32/menu/readconfig.c index f3b0f96..1d02120 100644 --- a/com32/menu/readconfig.c +++ b/com32/menu/readconfig.c @@ -1,7 +1,7 @@ /* ----------------------------------------------------------------------- * * * Copyright 2004-2009 H. Peter Anvin - All Rights Reserved - * Copyright 2009-2010 Intel Corporation; author: H. Peter Anvin + * Copyright 2009-2011 Intel Corporation; author: H. Peter Anvin * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -37,6 +37,7 @@ int shiftkey = 0; /* Only display menu if shift key pressed */ int hiddenmenu = 0; int clearmenu = 0; long long totaltimeout = 0; +const char *hide_key[KEY_MAX]; /* Keep track of global default */ static int has_ui = 0; /* DEFAULT only counts if UI is found */ @@ -141,6 +142,22 @@ static char *looking_at(char *line, const char *kwd) return my_isspace(*p) ? p : NULL; /* Must be EOL or whitespace */ } +/* Get a single word into a new refstr; advances the input pointer */ +static char *get_word(char *str, const char **word) +{ + char *p = str; + char *q; + + while (*p && !my_isspace(*p)) + p++; + + *word = q = refstr_alloc(p - str + 1); + memcpy(q, str, p - str); + /* refstr_alloc() already inserted a terminating NUL */ + + return p; +} + static struct menu *new_menu(struct menu *parent, struct menu_entry *parent_entry, const char *label) { @@ -703,6 +720,18 @@ static void parse_config_file(FILE * f) m->menu_background = refdup_word(&p); } else if ((ep = looking_at(p, "hidden"))) { hiddenmenu = 1; + } else if (looking_at(p, "hiddenkey")) { + const char *key_name; + int key; + p = skipspace(p + 7); + p = get_word(p, &key_name); + p = skipspace(p); + key = key_name_to_code(key_name); + refstr_put(key_name); + if (key >= 0) { + refstr_put(hide_key[key]); + hide_key[key] = refstrdup(skipspace(p)); + } } else if ((ep = looking_at(p, "clear"))) { clearmenu = 1; } else if ((ep = is_message_name(p, &msgnr))) { diff --git a/doc/menu.txt b/doc/menu.txt index e2dd1e1..892de48 100644 --- a/doc/menu.txt +++ b/doc/menu.txt @@ -48,6 +48,22 @@ MENU HIDDEN All that is displayed is a timeout message. +MENU HIDDENKEY key command... + + If they key used to interrupt MENU HIDDEN is , then + execute the specified command instead of displaying the menu. + + Currently, the following key names are recognized: + + Backspace, Tab, Enter, Esc, Space, F1..F12, Up, Down, Left, + Right, PgUp, PgDn, Home, End, Insert, Delete + + ... in addition to all single characters plus the syntax ^X + for Ctrl-X. Note that single characters are treated as case + sensitive, so a different command can be bound to "A" than + "a". + + MENU CLEAR Clear the screen when exiting the menu, instead of leaving the