Currently "all_disks" and "all_removables" are used for both populating the conversion dialog and collecting the configuration updates from the conversion dialog.
Going forward, we want to eliminate "all_disks" and "all_removables" as global variables. As one step in that direction, restrict the consumption of "all_disks" and "all_removables" to when we populate the conversion dialog. For this, introduce a new column to the list stores that back the "fixed disks" and "removable media drives" tree views, and copy "all_disks" and "all_removables" into the new columns, respectively. This new column is never displayed; it's only used as a lookaside buffer when we collect the disks / removables selections into the config structure. Note that both gtk_list_store_set() and gtk_tree_model_get() create deep copies of strings. No observable changes. Bugzilla: https://bugzilla.redhat.com/show_bug.cgi?id=2124538 Signed-off-by: Laszlo Ersek <ler...@redhat.com> --- gui.c | 90 +++++++++++++------- 1 file changed, 60 insertions(+), 30 deletions(-) diff --git a/gui.c b/gui.c index c40ed31a8bbc..82c297b0be4b 100644 --- a/gui.c +++ b/gui.c @@ -702,12 +702,14 @@ static uint64_t get_memory_from_conv_dlg (void); enum { DISKS_COL_CONVERT = 0, + DISKS_COL_HW_NAME, DISKS_COL_DEVICE, NUM_DISKS_COLS, }; enum { REMOVABLE_COL_CONVERT = 0, + REMOVABLE_COL_HW_NAME, REMOVABLE_COL_DEVICE, NUM_REMOVABLE_COLS, }; @@ -1103,7 +1105,8 @@ populate_disks (GtkTreeView *disks_list_p) size_t i; disks_store = gtk_list_store_new (NUM_DISKS_COLS, - G_TYPE_BOOLEAN, G_TYPE_STRING); + G_TYPE_BOOLEAN, G_TYPE_STRING, + G_TYPE_STRING); if (all_disks != NULL) { for (i = 0; all_disks[i] != NULL; ++i) { uint64_t size; @@ -1134,6 +1137,7 @@ populate_disks (GtkTreeView *disks_list_p) gtk_list_store_append (disks_store, &iter); gtk_list_store_set (disks_store, &iter, DISKS_COL_CONVERT, TRUE, + DISKS_COL_HW_NAME, all_disks[i], DISKS_COL_DEVICE, device_descr, -1); } @@ -1174,7 +1178,8 @@ populate_removable (GtkTreeView *removable_list_p) size_t i; removable_store = gtk_list_store_new (NUM_REMOVABLE_COLS, - G_TYPE_BOOLEAN, G_TYPE_STRING); + G_TYPE_BOOLEAN, G_TYPE_STRING, + G_TYPE_STRING); if (all_removable != NULL) { for (i = 0; all_removable[i] != NULL; ++i) { CLEANUP_FREE char *device_descr = NULL; @@ -1185,6 +1190,7 @@ populate_removable (GtkTreeView *removable_list_p) gtk_list_store_append (removable_store, &iter); gtk_list_store_set (removable_store, &iter, REMOVABLE_COL_CONVERT, TRUE, + REMOVABLE_COL_HW_NAME, all_removable[i], REMOVABLE_COL_DEVICE, device_descr, -1); } @@ -1397,52 +1403,76 @@ maybe_identify_click (GtkWidget *interfaces_list_p, GdkEventButton *event, } static void -set_from_ui_generic (char **all, char ***ret, GtkTreeView *list) +set_from_ui_generic (char ***ret, GtkTreeView *list) { GtkTreeModel *model; - GtkTreeIter iter; - gboolean b, v; - size_t i, j; + enum { COUNT, COPY, DONE } mode; guestfs_int_free_string_list (*ret); - if (all == NULL) { - *ret = NULL; - return; - } + *ret = NULL; model = gtk_tree_view_get_model (list); - *ret = malloc ((1 + guestfs_int_count_strings (all)) * sizeof (char *)); - if (*ret == NULL) - error (EXIT_FAILURE, errno, "malloc"); - i = j = 0; - - b = gtk_tree_model_get_iter_first (model, &iter); - while (b) { - gtk_tree_model_get (model, &iter, 0 /* CONVERT */, &v, -1); - if (v) { - assert (all[i] != NULL); - (*ret)[j++] = strdup (all[i]); + for (mode = COUNT; mode != DONE; mode++) { + size_t found; + gboolean avail; + GtkTreeIter iter; + + found = 0; + avail = gtk_tree_model_get_iter_first (model, &iter); + while (avail) { + gboolean active; + + gtk_tree_model_get (model, &iter, 0 /* CONVERT */, &active, -1); + if (active) { + if (mode == COPY) { + gchar *hw_name; + + gtk_tree_model_get (model, &iter, 1 /* HW_NAME */, &hw_name, -1); + + /* gtk_tree_model_get() outputs a deep copy, so no need for an + * strdup() here + */ + (*ret)[found] = hw_name; + } + + found++; + } + + avail = gtk_tree_model_iter_next (model, &iter); + } /* iteration over entries of "model" */ + + switch (mode) { + case COUNT: + if (found == 0) + return; + + *ret = malloc ((found + 1) * sizeof (char *)); + if (*ret == NULL) + error (EXIT_FAILURE, errno, "malloc"); + + break; + + case COPY: + (*ret)[found] = NULL; + break; + + default: + assert (0); } - b = gtk_tree_model_iter_next (model, &iter); - ++i; - } - - (*ret)[j] = NULL; + } /* "mode" loop */ } static void set_disks_from_ui (struct config *config) { - set_from_ui_generic (all_disks, &config->disks, - GTK_TREE_VIEW (disks_list)); + set_from_ui_generic (&config->disks, GTK_TREE_VIEW (disks_list)); } static void set_removable_from_ui (struct config *config) { - set_from_ui_generic (all_removable, &config->removable, - GTK_TREE_VIEW (removable_list)); + set_from_ui_generic (&config->removable, GTK_TREE_VIEW (removable_list)); } static void _______________________________________________ Libguestfs mailing list Libguestfs@redhat.com https://listman.redhat.com/mailman/listinfo/libguestfs