Message ID | 1496330742-18181-4-git-send-email-thuth@redhat.com |
---|---|
State | Superseded |
Headers | show |
Thomas Huth <thuth@redhat.com> writes: > Wait for a key and return the selected boot device on the Forth stack. > > Signed-off-by: Thomas Huth <thuth@redhat.com> > --- > lib/libbootmenu/bootmenu.c | 74 +++++++++++++++++++++++++++++++++++++++++++ > lib/libbootmenu/bootmenu.code | 2 +- > 2 files changed, 75 insertions(+), 1 deletion(-) > > diff --git a/lib/libbootmenu/bootmenu.c b/lib/libbootmenu/bootmenu.c > index 649e518..979cdc4 100644 > --- a/lib/libbootmenu/bootmenu.c > +++ b/lib/libbootmenu/bootmenu.c > @@ -12,10 +12,12 @@ > * Thomas Huth, Red Hat Inc. - initial implementation > *****************************************************************************/ > > +#include <stdbool.h> > #include <string.h> > #include <stdio.h> > #include <stdlib.h> > #include <paflof.h> > +#include <helpers.h> > #include "bootmenu.h" > > #define MAX_DEVS 36 /* Enough for 10 digits + 26 letters */ > @@ -93,15 +95,87 @@ static void bootmenu_show_devs(void) > } > } > > +static bool has_key(void) > +{ > + forth_eval("key?"); > + return forth_pop(); > +} > + > +static char get_key(void) > +{ > + forth_eval("key"); > + return forth_pop(); > +} > + > +/* Flush pending key presses */ > +static void flush_keys(void) > +{ > + uint32_t start; > + > + start = SLOF_GetTimer(); > + while (SLOF_GetTimer() - start < 10) { > + if (has_key()) { > + get_key(); > + start = SLOF_GetTimer(); > + } > + } > +} > + > +static int bootmenu_get_selection(void) > +{ > + char key = 0; > + int sel; > + > + do { > + sel = -1; > + if (!has_key()) > + continue; > + key = get_key(); > + switch (key) { > + case '0': > + return -1; > + case '1' ... '9': > + sel = key - '1'; > + break; > + case 'a' ... 'z': > + sel = key - 'a' + 9; > + break; > + case 'A' ... 'Z': > + sel = key - 'A' + 9; > + break; With this we can have 1-9, a-z and A-Z, 10 + 26 + 26 = 62 selection. Though displaying them on one screen is difficult. MAX_DEVS is set to 36 though. > + default: > + /* Might be another escape code (F12) ... skip it */ > + flush_keys(); > + break; > + } > + } while (sel < 0 || sel >= nr_devs); > + > + return sel; > +} > + > void bootmenu(void) > { > + int sel; > + > bootmenu_populate_devs(); > if (!nr_devs) { > puts("No available boot devices!"); > return; > } > > + puts("\nSelect boot device (or press '0' to abort):"); > bootmenu_show_devs(); > > + if (has_key()) /* In case the user hammered on F12 */ > + flush_keys(); > + > + sel = bootmenu_get_selection(); > + if (sel < 0) { > + forth_push(0); > + } else { > + forth_push((unsigned long)bootdevs[sel].alias); > + forth_push(strlen(bootdevs[sel].alias)); > + } > + > bootmenu_free_devs(); > } > diff --git a/lib/libbootmenu/bootmenu.code b/lib/libbootmenu/bootmenu.code > index f51784d..2a55c09 100644 > --- a/lib/libbootmenu/bootmenu.code > +++ b/lib/libbootmenu/bootmenu.code > @@ -14,7 +14,7 @@ > > #include "bootmenu.h" > > -// ( -- ) > +// ( -- [str] len|0 ) > PRIM(boot_X2d_menu) > bootmenu(); > MIRP > -- > 1.8.3.1
On 05.06.2017 07:42, Nikunj A Dadhania wrote: > Thomas Huth <thuth@redhat.com> writes: > >> Wait for a key and return the selected boot device on the Forth stack. >> >> Signed-off-by: Thomas Huth <thuth@redhat.com> >> --- >> lib/libbootmenu/bootmenu.c | 74 +++++++++++++++++++++++++++++++++++++++++++ >> lib/libbootmenu/bootmenu.code | 2 +- >> 2 files changed, 75 insertions(+), 1 deletion(-) >> >> diff --git a/lib/libbootmenu/bootmenu.c b/lib/libbootmenu/bootmenu.c >> index 649e518..979cdc4 100644 >> --- a/lib/libbootmenu/bootmenu.c >> +++ b/lib/libbootmenu/bootmenu.c >> @@ -12,10 +12,12 @@ >> * Thomas Huth, Red Hat Inc. - initial implementation >> *****************************************************************************/ >> >> +#include <stdbool.h> >> #include <string.h> >> #include <stdio.h> >> #include <stdlib.h> >> #include <paflof.h> >> +#include <helpers.h> >> #include "bootmenu.h" >> >> #define MAX_DEVS 36 /* Enough for 10 digits + 26 letters */ >> @@ -93,15 +95,87 @@ static void bootmenu_show_devs(void) >> } >> } >> >> +static bool has_key(void) >> +{ >> + forth_eval("key?"); >> + return forth_pop(); >> +} >> + >> +static char get_key(void) >> +{ >> + forth_eval("key"); >> + return forth_pop(); >> +} >> + >> +/* Flush pending key presses */ >> +static void flush_keys(void) >> +{ >> + uint32_t start; >> + >> + start = SLOF_GetTimer(); >> + while (SLOF_GetTimer() - start < 10) { >> + if (has_key()) { >> + get_key(); >> + start = SLOF_GetTimer(); >> + } >> + } >> +} >> + >> +static int bootmenu_get_selection(void) >> +{ >> + char key = 0; >> + int sel; >> + >> + do { >> + sel = -1; >> + if (!has_key()) >> + continue; >> + key = get_key(); >> + switch (key) { >> + case '0': >> + return -1; >> + case '1' ... '9': >> + sel = key - '1'; >> + break; >> + case 'a' ... 'z': >> + sel = key - 'a' + 9; >> + break; >> + case 'A' ... 'Z': >> + sel = key - 'A' + 9; >> + break; > > With this we can have 1-9, a-z and A-Z, 10 + 26 + 26 = 62 selection. > Though displaying them on one screen is difficult. MAX_DEVS is set to 36 > though. Right, currently I treat the letters case-insensitive. We could increase MAX_DEVS to 62 by treating the letters case-sensitive instead ... question is, do we want that, or are 36 possible boot devices enough (since 62 hardly fit on a screen anyway, as you noted)? Thomas
Thomas Huth <thuth@redhat.com> writes: > On 05.06.2017 07:42, Nikunj A Dadhania wrote: >> Thomas Huth <thuth@redhat.com> writes: >> >>> Wait for a key and return the selected boot device on the Forth stack. >>> >>> Signed-off-by: Thomas Huth <thuth@redhat.com> >>> --- >>> lib/libbootmenu/bootmenu.c | 74 +++++++++++++++++++++++++++++++++++++++++++ >>> lib/libbootmenu/bootmenu.code | 2 +- >>> 2 files changed, 75 insertions(+), 1 deletion(-) >>> >>> diff --git a/lib/libbootmenu/bootmenu.c b/lib/libbootmenu/bootmenu.c >>> index 649e518..979cdc4 100644 >>> --- a/lib/libbootmenu/bootmenu.c >>> +++ b/lib/libbootmenu/bootmenu.c >>> @@ -12,10 +12,12 @@ >>> * Thomas Huth, Red Hat Inc. - initial implementation >>> *****************************************************************************/ >>> >>> +#include <stdbool.h> >>> #include <string.h> >>> #include <stdio.h> >>> #include <stdlib.h> >>> #include <paflof.h> >>> +#include <helpers.h> >>> #include "bootmenu.h" >>> >>> #define MAX_DEVS 36 /* Enough for 10 digits + 26 letters */ >>> @@ -93,15 +95,87 @@ static void bootmenu_show_devs(void) >>> } >>> } >>> >>> +static bool has_key(void) >>> +{ >>> + forth_eval("key?"); >>> + return forth_pop(); >>> +} >>> + >>> +static char get_key(void) >>> +{ >>> + forth_eval("key"); >>> + return forth_pop(); >>> +} >>> + >>> +/* Flush pending key presses */ >>> +static void flush_keys(void) >>> +{ >>> + uint32_t start; >>> + >>> + start = SLOF_GetTimer(); >>> + while (SLOF_GetTimer() - start < 10) { >>> + if (has_key()) { >>> + get_key(); >>> + start = SLOF_GetTimer(); >>> + } >>> + } >>> +} >>> + >>> +static int bootmenu_get_selection(void) >>> +{ >>> + char key = 0; >>> + int sel; >>> + >>> + do { >>> + sel = -1; >>> + if (!has_key()) >>> + continue; >>> + key = get_key(); >>> + switch (key) { >>> + case '0': >>> + return -1; >>> + case '1' ... '9': >>> + sel = key - '1'; >>> + break; >>> + case 'a' ... 'z': >>> + sel = key - 'a' + 9; >>> + break; >>> + case 'A' ... 'Z': >>> + sel = key - 'A' + 9; >>> + break; >> >> With this we can have 1-9, a-z and A-Z, 10 + 26 + 26 = 62 selection. >> Though displaying them on one screen is difficult. MAX_DEVS is set to 36 >> though. > > Right, currently I treat the letters case-insensitive. Ah, i missed that part. > We could increase MAX_DEVS to 62 by treating the letters > case-sensitive instead ... question is, do we want that, or are 36 > possible boot devices enough (since 62 hardly fit on a screen anyway, > as you noted)? 36 should be good enough. Regards, Nikunj
On 02/06/17 01:25, Thomas Huth wrote: > Wait for a key and return the selected boot device on the Forth stack. > > Signed-off-by: Thomas Huth <thuth@redhat.com> > --- > lib/libbootmenu/bootmenu.c | 74 +++++++++++++++++++++++++++++++++++++++++++ > lib/libbootmenu/bootmenu.code | 2 +- > 2 files changed, 75 insertions(+), 1 deletion(-) > > diff --git a/lib/libbootmenu/bootmenu.c b/lib/libbootmenu/bootmenu.c > index 649e518..979cdc4 100644 > --- a/lib/libbootmenu/bootmenu.c > +++ b/lib/libbootmenu/bootmenu.c > @@ -12,10 +12,12 @@ > * Thomas Huth, Red Hat Inc. - initial implementation > *****************************************************************************/ > > +#include <stdbool.h> > #include <string.h> > #include <stdio.h> > #include <stdlib.h> > #include <paflof.h> > +#include <helpers.h> > #include "bootmenu.h" > > #define MAX_DEVS 36 /* Enough for 10 digits + 26 letters */ > @@ -93,15 +95,87 @@ static void bootmenu_show_devs(void) > } > } > > +static bool has_key(void) > +{ > + forth_eval("key?"); > + return forth_pop(); > +} > + > +static char get_key(void) > +{ > + forth_eval("key"); > + return forth_pop(); > +} > + > +/* Flush pending key presses */ > +static void flush_keys(void) > +{ > + uint32_t start; > + > + start = SLOF_GetTimer(); > + while (SLOF_GetTimer() - start < 10) { > + if (has_key()) { > + get_key(); > + start = SLOF_GetTimer(); > + } > + } > +} > + > +static int bootmenu_get_selection(void) > +{ > + char key = 0; > + int sel; > + > + do { > + sel = -1; > + if (!has_key()) > + continue; > + key = get_key(); > + switch (key) { > + case '0': > + return -1; > + case '1' ... '9': > + sel = key - '1'; > + break; > + case 'a' ... 'z': > + sel = key - 'a' + 9; > + break; > + case 'A' ... 'Z': > + sel = key - 'A' + 9; > + break; > + default: > + /* Might be another escape code (F12) ... skip it */ > + flush_keys(); > + break; > + } > + } while (sel < 0 || sel >= nr_devs); > + > + return sel; > +} > + > void bootmenu(void) > { > + int sel; > + > bootmenu_populate_devs(); > if (!nr_devs) { > puts("No available boot devices!"); > return; > } > > + puts("\nSelect boot device (or press '0' to abort):"); > bootmenu_show_devs(); > > + if (has_key()) /* In case the user hammered on F12 */ > + flush_keys(); > + > + sel = bootmenu_get_selection(); > + if (sel < 0) { > + forth_push(0); > + } else { > + forth_push((unsigned long)bootdevs[sel].alias); > + forth_push(strlen(bootdevs[sel].alias)); > + } > + > bootmenu_free_devs(); > } > diff --git a/lib/libbootmenu/bootmenu.code b/lib/libbootmenu/bootmenu.code > index f51784d..2a55c09 100644 > --- a/lib/libbootmenu/bootmenu.code > +++ b/lib/libbootmenu/bootmenu.code > @@ -14,7 +14,7 @@ > > #include "bootmenu.h" > > -// ( -- ) > +// ( -- [str] len|0 ) Changing lines which were just added in the very same patchset is not usually right, 2/4 should have done forth_push(0), at least. Or better just merge all patches into one as suggested in 2/4. > PRIM(boot_X2d_menu) > bootmenu(); > MIRP >
diff --git a/lib/libbootmenu/bootmenu.c b/lib/libbootmenu/bootmenu.c index 649e518..979cdc4 100644 --- a/lib/libbootmenu/bootmenu.c +++ b/lib/libbootmenu/bootmenu.c @@ -12,10 +12,12 @@ * Thomas Huth, Red Hat Inc. - initial implementation *****************************************************************************/ +#include <stdbool.h> #include <string.h> #include <stdio.h> #include <stdlib.h> #include <paflof.h> +#include <helpers.h> #include "bootmenu.h" #define MAX_DEVS 36 /* Enough for 10 digits + 26 letters */ @@ -93,15 +95,87 @@ static void bootmenu_show_devs(void) } } +static bool has_key(void) +{ + forth_eval("key?"); + return forth_pop(); +} + +static char get_key(void) +{ + forth_eval("key"); + return forth_pop(); +} + +/* Flush pending key presses */ +static void flush_keys(void) +{ + uint32_t start; + + start = SLOF_GetTimer(); + while (SLOF_GetTimer() - start < 10) { + if (has_key()) { + get_key(); + start = SLOF_GetTimer(); + } + } +} + +static int bootmenu_get_selection(void) +{ + char key = 0; + int sel; + + do { + sel = -1; + if (!has_key()) + continue; + key = get_key(); + switch (key) { + case '0': + return -1; + case '1' ... '9': + sel = key - '1'; + break; + case 'a' ... 'z': + sel = key - 'a' + 9; + break; + case 'A' ... 'Z': + sel = key - 'A' + 9; + break; + default: + /* Might be another escape code (F12) ... skip it */ + flush_keys(); + break; + } + } while (sel < 0 || sel >= nr_devs); + + return sel; +} + void bootmenu(void) { + int sel; + bootmenu_populate_devs(); if (!nr_devs) { puts("No available boot devices!"); return; } + puts("\nSelect boot device (or press '0' to abort):"); bootmenu_show_devs(); + if (has_key()) /* In case the user hammered on F12 */ + flush_keys(); + + sel = bootmenu_get_selection(); + if (sel < 0) { + forth_push(0); + } else { + forth_push((unsigned long)bootdevs[sel].alias); + forth_push(strlen(bootdevs[sel].alias)); + } + bootmenu_free_devs(); } diff --git a/lib/libbootmenu/bootmenu.code b/lib/libbootmenu/bootmenu.code index f51784d..2a55c09 100644 --- a/lib/libbootmenu/bootmenu.code +++ b/lib/libbootmenu/bootmenu.code @@ -14,7 +14,7 @@ #include "bootmenu.h" -// ( -- ) +// ( -- [str] len|0 ) PRIM(boot_X2d_menu) bootmenu(); MIRP
Wait for a key and return the selected boot device on the Forth stack. Signed-off-by: Thomas Huth <thuth@redhat.com> --- lib/libbootmenu/bootmenu.c | 74 +++++++++++++++++++++++++++++++++++++++++++ lib/libbootmenu/bootmenu.code | 2 +- 2 files changed, 75 insertions(+), 1 deletion(-)