+static struct gopt_frame_widget gopt_g_widgets[__FIO_OPT_G_NR];
+
+static GtkWidget *gopt_get_group_frame(GtkWidget *box, unsigned int groupmask)
+{
+ unsigned int mask, group;
+ struct opt_group *og;
+ GtkWidget *frame, *hbox;
+ struct gopt_frame_widget *gfw;
+
+ if (!groupmask)
+ return 0;
+
+ mask = groupmask;
+ og = opt_group_cat_from_mask(&mask);
+ if (!og)
+ return NULL;
+
+ group = ffz(~groupmask);
+ gfw = &gopt_g_widgets[group];
+ if (!gfw->vbox[0]) {
+ frame = gtk_frame_new(og->name);
+ gtk_box_pack_start(GTK_BOX(box), frame, FALSE, FALSE, 3);
+ hbox = gtk_hbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(frame), hbox);
+ gfw->vbox[0] = gtk_vbox_new(TRUE, 5);
+ gfw->vbox[1] = gtk_vbox_new(TRUE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox), gfw->vbox[0], TRUE, TRUE, 5);
+ gtk_box_pack_start(GTK_BOX(hbox), gfw->vbox[1], TRUE, TRUE, 5);
+ }
+
+ hbox = gtk_hbox_new(FALSE, 3);
+ gtk_box_pack_start(GTK_BOX(gfw->vbox[gfw->nr++ & 1]), hbox, FALSE, FALSE, 5);
+ return hbox;
+}
+
+/*
+ * Mark children as invisible, if needed.
+ */
+static void gopt_set_children_visible(struct fio_option *parent, gboolean visible)
+{
+ struct fio_option *o;
+ int i;
+
+ /*
+ * This isn't super fast, but it should not be an issue. If it is, we
+ * can speed it up by caching the lookup at least. Or we can do it
+ * once, at init time.
+ */
+ for (i = 0; fio_options[i].name; i++) {
+ o = &fio_options[i];
+ if (!o->parent || !o->hide)
+ continue;
+
+ if (strcmp(parent->name, o->parent))
+ continue;
+
+ if (gopt_widgets[i])
+ gtk_widget_set_sensitive(gopt_widgets[i], visible);
+ }
+}
+
+static void gopt_str_changed(GtkEntry *entry, gpointer data)
+{
+ struct gopt_str *s = (struct gopt_str *) data;
+ struct fio_option *o = &fio_options[s->gopt.opt_index];
+ const gchar *text;
+ int set;
+
+ text = gtk_entry_get_text(GTK_ENTRY(s->entry));
+ set = strcmp(text, "") != 0;
+ gopt_set_children_visible(o, set);
+}
+
+static void gopt_mark_index(struct gopt *gopt, unsigned int idx)
+{
+ assert(!gopt_widgets[idx]);
+ gopt->opt_index = idx;
+ gopt_widgets[idx] = gopt->box;
+}