[PATCH 2/2] ui/ncurses: Add device hierarchy
Samuel Mendoza-Jonas
sam.mj at au1.ibm.com
Thu Jul 3 15:53:51 EST 2014
Boot options are now listed under their matching boot device in the
ncurses UI to help differentitate similar boot option names
Signed-off-by: Samuel Mendoza-Jonas <sam.mj at au1.ibm.com>
---
ui/ncurses/nc-cui.c | 119 +++++++++++++++++++++++++++++++++++++++++++++++++---
1 file changed, 114 insertions(+), 5 deletions(-)
diff --git a/ui/ncurses/nc-cui.c b/ui/ncurses/nc-cui.c
index 7200a81..9e71097 100644
--- a/ui/ncurses/nc-cui.c
+++ b/ui/ncurses/nc-cui.c
@@ -26,6 +26,7 @@
#include <string.h>
#include <locale.h>
#include <sys/ioctl.h>
+#include <util/util.h>
#include "log/log.h"
#include "pb-protocol/pb-protocol.h"
@@ -407,10 +408,13 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
{
struct cui *cui = cui_from_arg(arg);
struct cui_opt_data *cod;
- unsigned int insert_pt;
+ unsigned int insert_pt, j;
int result, rows, cols;
- struct pmenu_item *i;
+ int newdev = 1;
+ size_t len;
+ struct pmenu_item *i, *dev_hdr;
ITEM *selected;
+ char *shift;
pb_debug("%s: %p %s\n", __func__, opt, opt->id);
@@ -420,9 +424,96 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
if (cui->current == &cui->main->scr)
nc_scr_unpost(cui->current);
+
+ /* Check if device header exists */
+ for (j=0; j < cui->main->item_count; j++){
+ struct pmenu_item *item = item_userptr(cui->main->items[j]);
+ struct cui_opt_data *data = item->data;
+ /* boot entries will have this defined */
+ if(!data || data->opt)
+ continue;
+ if(!strcmp(data->name,opt->device_id)){
+ pb_debug("%s: %s fits under %s\n",__func__,
+ opt->name, opt->device_id);
+ newdev = 0;
+ break;
+ }
+ }
+
+ /* Create a dummy pmenu_item to represent the dev */
+ if (newdev) {
+ char *buf = talloc_array(cui->main, char, sizeof(char)*256);
+ struct system_info *sys = cui->sysinfo;
+ int matched;
+ switch (dev->type) {
+ case DEVICE_TYPE_OPTICAL:
+ case DEVICE_TYPE_DISK:
+ {
+ /* find block info */
+ for (j=0; sys && j < sys->n_blockdevs; j++){
+ struct blockdev_info *bd = sys->blockdevs[j];
+ if (!strcmp(opt->device_id,bd->name)){
+ snprintf(buf,sizeof(char)*256,"[%s: %s / %s]",
+ dev->type == DEVICE_TYPE_DISK ? "Disk" : "CD/DVD",
+ bd->name, bd->uuid);
+ matched = 1;
+ break;
+ }
+ }
+ break;
+ }
+ case DEVICE_TYPE_NETWORK:
+ {
+ /* find interface info */
+ char *hwaddr = talloc_array(cui->main, char, 32);
+ for (j=0; sys && j < sys->n_interfaces; j++){
+ struct interface_info *intf = sys->interfaces[j];
+ if (!strcmp(opt->device_id,intf->name)){
+ mac_str(intf->hwaddr, intf->hwaddr_size, hwaddr, 32);
+ snprintf(buf,sizeof(char)*256,"[Interface: %s / %s]",
+ intf->name, hwaddr);
+ matched = 1;
+ break;
+ }
+ }
+ talloc_free(hwaddr);
+ break;
+ }
+ default:
+ /* Assume it might be able to boot */
+ break;
+ }
+ if(!matched){
+ pb_debug("%s: No matching device found for %s (%s)\n",__func__,opt->device_id, dev->id);
+ snprintf(buf,sizeof(char)*256,"[Unknown Device: %s]",dev->id);
+ }
+
+ dev_hdr = pmenu_item_create(cui->main, buf);
+ dev_hdr->on_edit = NULL;
+ dev_hdr->on_execute = NULL;
+ item_opts_off(dev_hdr->nci, O_SELECTABLE);
+
+ /* We identify dev_hdr items as having a valid c->name,
+ * but a NULL c->opt */
+ struct cui_opt_data *c = talloc(dev_hdr, struct cui_opt_data);
+ c->name = talloc_strdup(dev_hdr, opt->device_id);
+ c->opt = NULL;
+ dev_hdr->data = c;
+ talloc_free(buf);
+ }
+
+ /* All actual boot entries are 'tabbed' across */
+ if(!opt->name)
+ len = sizeof(" Unknown Name");
+ else
+ len = strlen(opt->name) + sizeof(char)*5;
+ shift = talloc_array(cui->main, char, len);
+ snprintf(shift,len," %s",opt->name ? opt->name : "Unknown Name");
+
/* Save the item in opt->ui_info for cui_device_remove() */
- opt->ui_info = i = pmenu_item_create(cui->main, opt->name);
+ opt->ui_info = i = pmenu_item_create(cui->main, shift);
+ talloc_free(shift);
if (!i)
return -1;
@@ -448,8 +539,15 @@ static int cui_boot_option_add(struct device *dev, struct boot_option *opt,
pb_log("%s: set_menu_items failed: %d\n", __func__, result);
/* Insert new items at insert_pt. */
- insert_pt = pmenu_grow(cui->main, 1);
- pmenu_item_insert(cui->main, i, insert_pt);
+ if(newdev){
+ insert_pt = pmenu_grow(cui->main, 2);
+ pmenu_item_insert(cui->main, dev_hdr, insert_pt);
+ pb_log("%s: adding new device hierarchy %s\n",__func__,opt->device_id);
+ pmenu_item_insert(cui->main, i, insert_pt+1);
+ } else {
+ insert_pt = pmenu_grow(cui->main, 1);
+ pmenu_item_add(cui->main, i, insert_pt);
+ }
pb_log("%s: adding opt '%s'\n", __func__, cod->name);
pb_log(" image '%s'\n", cod->bd->image);
@@ -500,6 +598,7 @@ static void cui_device_remove(struct device *dev, void *arg)
{
struct cui *cui = cui_from_arg(arg);
int result;
+ unsigned int ind;
struct boot_option *opt;
pb_log("%s: %p %s\n", __func__, dev, dev->id);
@@ -521,6 +620,16 @@ static void cui_device_remove(struct device *dev, void *arg)
pmenu_remove(cui->main, i);
}
+ /* Manually remove remaining device hierarchy item */
+ for (ind=0; ind< cui->main->item_count; ind++) {
+ struct pmenu_item *i = item_userptr(cui->main->items[ind]);
+ if(i && i->data){
+ struct cui_opt_data *data = i->data;
+ if(data && data->name && !strcmp(data->name,dev->id))
+ pmenu_remove(cui->main,i);
+ }
+ }
+
/* Re-attach the items array. */
result = set_menu_items(cui->main->ncm, cui->main->items);
--
1.9.3
More information about the Petitboot
mailing list