menu: Add "menu hiddenkey" to make terminating menu hidden a command
authorH. Peter Anvin <hpa@linux.intel.com>
Mon, 11 Apr 2011 21:59:45 +0000 (14:59 -0700)
committerH. Peter Anvin <hpa@linux.intel.com>
Mon, 11 Apr 2011 22:06:38 +0000 (15:06 -0700)
Use "menu hiddenkey" together with "menu hidden" for a one-keystroke
action.

Signed-off-by: H. Peter Anvin <hpa@linux.intel.com>
com32/libutil/Makefile
com32/libutil/include/getkey.h
com32/libutil/keyname.c [new file with mode: 0644]
com32/menu/menu.h
com32/menu/menumain.c
com32/menu/readconfig.c
doc/menu.txt

index 02789ca..7a6b527 100644 (file)
@@ -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))
 
index 52312a2..a46de81 100644 (file)
 #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 (file)
index 0000000..6aebbd5
--- /dev/null
@@ -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 <stdbool.h>
+#include <stdio.h>
+#include <string.h>
+#include <errno.h>
+#include <unistd.h>
+#include <time.h>
+#include <sys/times.h>
+#include <getkey.h>
+#include <libutil.h>
+
+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;
+}
index 36c5669..1db4d7c 100644 (file)
@@ -26,6 +26,7 @@
 #include <unistd.h>
 #include <colortbl.h>
 #include <stdbool.h>
+#include <getkey.h>
 #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);
index 06725f3..df1eb18 100644 (file)
@@ -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;
        }
index f3b0f96..1d02120 100644 (file)
@@ -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))) {
index e2dd1e1..892de48 100644 (file)
@@ -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 <key>, 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