210-cmd-bootmenu-add-ability-to-select-item-by-shortkey.patch 4.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192
  1. From 26d4e2e58bf0007db74b47c783785c3305ea1fa0 Mon Sep 17 00:00:00 2001
  2. From: Weijie Gao <[email protected]>
  3. Date: Tue, 19 Jan 2021 10:58:48 +0800
  4. Subject: [PATCH 17/23] cmd: bootmenu: add ability to select item by shortkey
  5. Add ability to use shortkey to select item for bootmenu command
  6. Signed-off-by: Weijie Gao <[email protected]>
  7. ---
  8. cmd/bootmenu.c | 77 +++++++++++++++++++++++++++++++++++++++++++++-----
  9. 1 file changed, 70 insertions(+), 7 deletions(-)
  10. --- a/cmd/bootmenu.c
  11. +++ b/cmd/bootmenu.c
  12. @@ -11,6 +11,7 @@
  13. #include <menu.h>
  14. #include <watchdog.h>
  15. #include <malloc.h>
  16. +#include <linux/ctype.h>
  17. #include <linux/delay.h>
  18. #include <linux/string.h>
  19. @@ -38,6 +39,7 @@ struct bootmenu_data {
  20. int active; /* active menu entry */
  21. int count; /* total count of menu entries */
  22. struct bootmenu_entry *first; /* first menu entry */
  23. + bool last_choiced;
  24. };
  25. enum bootmenu_key {
  26. @@ -46,8 +48,27 @@ enum bootmenu_key {
  27. KEY_DOWN,
  28. KEY_SELECT,
  29. KEY_QUIT,
  30. + KEY_CHOICE,
  31. };
  32. +static const char choice_chars[] = {
  33. + '1', '2', '3', '4', '5', '6', '7', '8', '9',
  34. + 'a', 'b', 'c', 'd', 'e', 'f', 'g', 'h', 'i', 'j',
  35. + 'k', 'l', 'm', 'n', 'o', 'p', 'q', 'r', 's', 't',
  36. + 'u', 'v', 'w', 'x', 'y', 'z'
  37. +};
  38. +
  39. +static int find_choice(char choice)
  40. +{
  41. + int i;
  42. +
  43. + for (i = 0; i < ARRAY_SIZE(choice_chars); i++)
  44. + if (tolower(choice) == choice_chars[i])
  45. + return i;
  46. +
  47. + return -1;
  48. +}
  49. +
  50. static char *bootmenu_getoption(unsigned short int n)
  51. {
  52. char name[MAX_ENV_SIZE];
  53. @@ -82,7 +103,7 @@ static void bootmenu_print_entry(void *d
  54. }
  55. static void bootmenu_autoboot_loop(struct bootmenu_data *menu,
  56. - enum bootmenu_key *key, int *esc)
  57. + enum bootmenu_key *key, int *esc, int *choice)
  58. {
  59. int i, c;
  60. @@ -115,6 +136,19 @@ static void bootmenu_autoboot_loop(struc
  61. break;
  62. default:
  63. *key = KEY_NONE;
  64. + if (*esc)
  65. + break;
  66. +
  67. + *choice = find_choice(c);
  68. + if ((*choice >= 0 &&
  69. + *choice < menu->count - 1)) {
  70. + *key = KEY_CHOICE;
  71. + } else if (c == '0') {
  72. + *choice = menu->count - 1;
  73. + *key = KEY_CHOICE;
  74. + } else {
  75. + *key = KEY_NONE;
  76. + }
  77. break;
  78. }
  79. @@ -136,10 +170,16 @@ static void bootmenu_autoboot_loop(struc
  80. }
  81. static void bootmenu_loop(struct bootmenu_data *menu,
  82. - enum bootmenu_key *key, int *esc)
  83. + enum bootmenu_key *key, int *esc, int *choice)
  84. {
  85. int c;
  86. + if (menu->last_choiced) {
  87. + menu->last_choiced = false;
  88. + *key = KEY_SELECT;
  89. + return;
  90. + }
  91. +
  92. if (*esc == 1) {
  93. if (tstc()) {
  94. c = getchar();
  95. @@ -165,6 +205,14 @@ static void bootmenu_loop(struct bootmen
  96. if (c == '\e') {
  97. *esc = 1;
  98. *key = KEY_NONE;
  99. + } else {
  100. + *choice = find_choice(c);
  101. + if ((*choice >= 0 && *choice < menu->count - 1)) {
  102. + *key = KEY_CHOICE;
  103. + } else if (c == '0') {
  104. + *choice = menu->count - 1;
  105. + *key = KEY_CHOICE;
  106. + }
  107. }
  108. break;
  109. case 1:
  110. @@ -216,16 +264,17 @@ static char *bootmenu_choice_entry(void
  111. struct bootmenu_data *menu = data;
  112. struct bootmenu_entry *iter;
  113. enum bootmenu_key key = KEY_NONE;
  114. + int choice = -1;
  115. int esc = 0;
  116. int i;
  117. while (1) {
  118. if (menu->delay >= 0) {
  119. /* Autoboot was not stopped */
  120. - bootmenu_autoboot_loop(menu, &key, &esc);
  121. + bootmenu_autoboot_loop(menu, &key, &esc, &choice);
  122. } else {
  123. /* Some key was pressed, so autoboot was stopped */
  124. - bootmenu_loop(menu, &key, &esc);
  125. + bootmenu_loop(menu, &key, &esc, &choice);
  126. }
  127. switch (key) {
  128. @@ -239,6 +288,12 @@ static char *bootmenu_choice_entry(void
  129. ++menu->active;
  130. /* no menu key selected, regenerate menu */
  131. return NULL;
  132. + case KEY_CHOICE:
  133. + menu->active = choice;
  134. + if (!menu->last_choiced) {
  135. + menu->last_choiced = true;
  136. + return NULL;
  137. + }
  138. case KEY_SELECT:
  139. iter = menu->first;
  140. for (i = 0; i < menu->active; ++i)
  141. @@ -294,6 +349,7 @@ static struct bootmenu_data *bootmenu_cr
  142. menu->delay = delay;
  143. menu->active = 0;
  144. menu->first = NULL;
  145. + menu->last_choiced = false;
  146. default_str = env_get("bootmenu_default");
  147. if (default_str)
  148. @@ -311,12 +367,19 @@ static struct bootmenu_data *bootmenu_cr
  149. goto cleanup;
  150. len = sep-option;
  151. - entry->title = malloc(len + 1);
  152. + entry->title = malloc(len + 4);
  153. if (!entry->title) {
  154. free(entry);
  155. goto cleanup;
  156. }
  157. - memcpy(entry->title, option, len);
  158. +
  159. + if (i < ARRAY_SIZE(choice_chars)) {
  160. + len = sprintf(entry->title, "%c. %.*s", choice_chars[i],
  161. + len, option);
  162. + } else {
  163. + len = sprintf(entry->title, " %.*s", len, option);
  164. + }
  165. +
  166. entry->title[len] = 0;
  167. len = strlen(sep + 1);
  168. @@ -353,7 +416,7 @@ static struct bootmenu_data *bootmenu_cr
  169. if (!entry)
  170. goto cleanup;
  171. - entry->title = strdup("U-Boot console");
  172. + entry->title = strdup("0. U-Boot console");
  173. if (!entry->title) {
  174. free(entry);
  175. goto cleanup;