struct gopt_frame_widget g_widgets[__FIO_OPT_G_NR];
GtkWidget *widgets[FIO_MAX_OPTS];
GtkWidget *vboxes[__FIO_OPT_C_NR];
+ GtkWidget *dialog;
+ struct gfio_client *client;
struct flist_head changed_list;
struct thread_options *o;
};
gjv->widgets[idx] = gopt->box;
}
+static void gopt_dialog_update_apply(struct gopt_job_view *gjv)
+{
+ GtkDialog *dialog = GTK_DIALOG(gjv->dialog);
+ gboolean set;
+
+ set = !flist_empty(&gjv->changed_list);
+ gtk_dialog_set_response_sensitive(dialog, GTK_RESPONSE_APPLY, set);
+}
+
static void gopt_changed(struct gopt *gopt)
{
struct gopt_job_view *gjv = gopt->gjv;
* Add to changed list. This also prevents the option from being
* freed when the widget is destroyed.
*/
- if (flist_empty(&gopt->changed_list))
+ if (flist_empty(&gopt->changed_list)) {
flist_add_tail(&gopt->changed_list, &gjv->changed_list);
+ gopt_dialog_update_apply(gjv);
+ }
}
static void gopt_str_changed(GtkEntry *entry, gpointer data)
{
struct gopt_str *s = (struct gopt_str *) data;
- if (flist_empty(&s->gopt.changed_list))
- free(s);
-
+ free(s);
gtk_widget_destroy(w);
}
gopt_mark_index(gjv, &s->gopt, idx, GOPT_STR);
if (text)
gtk_entry_set_text(GTK_ENTRY(s->entry), text);
- gtk_entry_set_editable(GTK_ENTRY(s->entry), 1);
+ gtk_editable_set_editable(GTK_EDITABLE(s->entry), 1);
if (o->def)
gtk_entry_set_text(GTK_ENTRY(s->entry), o->def);
{
struct gopt_combo *c = (struct gopt_combo *) data;
- if (flist_empty(&c->gopt.changed_list))
- free(c);
-
+ free(c);
gtk_widget_destroy(w);
}
else
label = gtk_label_new(o->lname);
- c->combo = gtk_combo_box_new_text();
+ c->combo = gtk_combo_box_text_new();
gopt_mark_index(gjv, &c->gopt, idx, type);
g_signal_connect(G_OBJECT(c->combo), "destroy", G_CALLBACK(gopt_combo_destroy), c);
i = 0;
vp = &o->posval[0];
while (vp->ival) {
- gtk_combo_box_append_text(GTK_COMBO_BOX(c->combo), vp->ival);
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(c->combo), vp->ival);
if (o->def && !strcmp(vp->ival, o->def))
active = i;
if (text && !strcmp(vp->ival, text))
i = 0;
vp = &o->posval[0];
while (vp->ival) {
- gtk_combo_box_append_text(GTK_COMBO_BOX(c->combo), vp->ival);
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(c->combo), vp->ival);
if (ip && vp->oval == *ip)
active = i;
vp++;
gopt_changed(&m->gopt);
}
+static void gopt_str_multi_destroy(GtkWidget *w, gpointer data)
+{
+ struct gopt_str_multi *m = (struct gopt_str_multi *) data;
+
+ free(m);
+ gtk_widget_destroy(w);
+}
+
static struct gopt *gopt_new_str_multi(struct gopt_job_view *gjv,
struct fio_option *o, unsigned int idx)
{
m->checks[i] = gtk_check_button_new_with_label(vp->ival);
gtk_widget_set_tooltip_text(m->checks[i], vp->help);
gtk_box_pack_start(GTK_BOX(hbox), m->checks[i], FALSE, FALSE, 3);
- vp++;
g_signal_connect(G_OBJECT(m->checks[i]), "toggled", G_CALLBACK(gopt_str_multi_toggled), m);
+ vp++;
+ i++;
}
+ g_signal_connect(G_OBJECT(m->gopt.box), "destroy", G_CALLBACK(gopt_str_multi_destroy), m);
return &m->gopt;
}
{
struct gopt_int *i = (struct gopt_int *) data;
- if (flist_empty(&i->gopt.changed_list))
- free(i);
-
+ free(i);
gtk_widget_destroy(w);
}
{
struct gopt_bool *b = (struct gopt_bool *) data;
- if (flist_empty(&b->gopt.changed_list))
- free(b);
-
+ free(b);
gtk_widget_destroy(w);
}
{
struct gopt_range *r = (struct gopt_range *) data;
- if (flist_empty(&r->gopt.changed_list))
- free(r);
-
+ free(r);
gtk_widget_destroy(w);
}
{
struct gopt_str_val *g = (struct gopt_str_val *) data;
- if (flist_empty(&g->gopt.changed_list))
- free(g);
-
+ free(g);
gtk_widget_destroy(w);
}
g_signal_connect(G_OBJECT(g->spin), "wrapped", G_CALLBACK(gopt_str_val_spin_wrapped), g);
g_signal_connect(G_OBJECT(g->spin), "changed", G_CALLBACK(gopt_str_val_changed), g);
- g->combo = gtk_combo_box_new_text();
+ g->combo = gtk_combo_box_text_new();
i = 0;
while (strlen(postfix[i])) {
- gtk_combo_box_append_text(GTK_COMBO_BOX(g->combo), postfix[i]);
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(g->combo), postfix[i]);
i++;
}
g->maxindex = i - 1;
struct fio_option *o)
{
unsigned int *ip = td_var(gjv->o, o->off1);
+ struct value_pair *vp;
gboolean set;
guint val = 0;
int i;
i = 0;
- while (o->posval[i].ival) {
+ vp = &o->posval[0];
+ while (vp->ival) {
if (!m->checks[i])
break;
set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(m->checks[i]));
if (set) {
- if (o->posval[i].or)
- val |= o->posval[i].oval;
+ if (vp->or)
+ val |= vp->oval;
else
- val = o->posval[i].oval;
+ val = vp->oval;
}
i++;
+ vp++;
}
if (o->off1)
if (*p)
free(*p);
- *p = strdup(gtk_combo_box_get_active_text(GTK_COMBO_BOX(c->combo)));
+ *p = strdup(gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(c->combo)));
}
static void gopt_handle_combo_int_changed(struct gopt_job_view *gjv,
{
struct fio_option *o = &fio_options[gopt->opt_index];
struct gopt_job_view *gjv = gopt->gjv;
- void *to_free = NULL;
switch (gopt->opt_type) {
case GOPT_COMBO_INT: {
c = container_of(gopt, struct gopt_combo, gopt);
gopt_handle_combo_int_changed(gjv, c, o);
- to_free = c;
break;
}
case GOPT_COMBO_STR: {
c = container_of(gopt, struct gopt_combo, gopt);
gopt_handle_combo_str_changed(gjv, c, o);
- to_free = c;
break;
}
case GOPT_INT: {
i = container_of(gopt, struct gopt_int, gopt);
gopt_handle_int_changed(gjv, i, o);
- to_free = i;
break;
}
case GOPT_BOOL: {
b = container_of(gopt, struct gopt_bool, gopt);
gopt_handle_bool_changed(gjv, b, o);
- to_free = b;
break;
}
case GOPT_STR: {
s = container_of(gopt, struct gopt_str, gopt);
gopt_handle_str_changed(gjv, s, o);
- to_free = s;
break;
}
case GOPT_STR_VAL: {
s = container_of(gopt, struct gopt_str_val, gopt);
gopt_handle_str_val_changed(gjv, s, o);
- to_free = s;
break;
}
case GOPT_RANGE: {
r = container_of(gopt, struct gopt_range, gopt);
gopt_handle_range_changed(gjv, r, o);
- to_free = r;
break;
}
case GOPT_STR_MULTI: {
m = container_of(gopt, struct gopt_str_multi, gopt);
gopt_handle_str_multi_changed(gjv, m, o);
- to_free = m;
break;
}
default:
}
g_object_unref(G_OBJECT(gopt->box));
- free(to_free);
}
-static void gopt_handle_changed_options(struct gopt_job_view *gjv)
+static int gopt_handle_changed_options(struct gopt_job_view *gjv)
{
+ struct gfio_client *gc = gjv->client;
+ uint64_t waitid = 0;
struct gopt *gopt;
+ int ret;
while (!flist_empty(&gjv->changed_list)) {
gopt = flist_entry(gjv->changed_list.next, struct gopt, changed_list);
flist_del(&gopt->changed_list);
gopt_handle_changed(gopt);
}
+
+ gopt_dialog_update_apply(gjv);
+
+ ret = fio_client_update_options(gc->client, gjv->o, &waitid);
+ if (ret)
+ return ret;
+
+ return fio_client_wait_for_reply(gc->client, waitid);
+}
+
+static gint gopt_dialog_cancel(gint response)
+{
+ switch (response) {
+ case GTK_RESPONSE_NONE:
+ case GTK_RESPONSE_REJECT:
+ case GTK_RESPONSE_DELETE_EVENT:
+ case GTK_RESPONSE_CANCEL:
+ case GTK_RESPONSE_NO:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+static gint gopt_dialog_done(gint response)
+{
+ switch (response) {
+ case GTK_RESPONSE_ACCEPT:
+ case GTK_RESPONSE_OK:
+ case GTK_RESPONSE_YES:
+ return 1;
+ default:
+ return 0;
+ }
+}
+
+
+static void gopt_handle_option_dialog(GtkWidget *dialog,
+ struct flist_head *gjv_list)
+{
+ struct flist_head *entry;
+ struct gopt_job_view *gjv;
+ gint response;
+
+ do {
+ response = gtk_dialog_run(GTK_DIALOG(dialog));
+ if (gopt_dialog_cancel(response))
+ break;
+ else if (gopt_dialog_done(response))
+ break;
+
+ flist_for_each(entry, gjv_list) {
+ gjv = flist_entry(gjv_list->next, struct gopt_job_view, list);
+
+ gopt_handle_changed_options(gjv);
+ }
+ } while (1);
+
+ if (gopt_dialog_cancel(response))
+ return;
+
+ while (!flist_empty(gjv_list)) {
+ gjv = flist_entry(gjv_list->next, struct gopt_job_view, list);
+
+ gopt_handle_changed_options(gjv);
+
+ flist_del(&gjv->list);
+ free(gjv);
+ }
}
void gopt_get_options_window(GtkWidget *window, struct gfio_client *gc)
dialog = gtk_dialog_new_with_buttons("Fio options",
GTK_WINDOW(window), GTK_DIALOG_DESTROY_WITH_PARENT,
GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_APPLY, GTK_RESPONSE_APPLY,
GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
gtk_widget_set_size_request(GTK_WIDGET(dialog), 1024, 768);
topnotebook = gtk_notebook_new();
gtk_notebook_set_scrollable(GTK_NOTEBOOK(topnotebook), 1);
gtk_notebook_popup_enable(GTK_NOTEBOOK(topnotebook));
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), topnotebook, TRUE, TRUE, 5);
+ vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ gtk_box_pack_start(GTK_BOX(vbox), topnotebook, TRUE, TRUE, 5);
flist_for_each(entry, &gc->o_list) {
const char *name;
INIT_FLIST_HEAD(&gjv->list);
INIT_FLIST_HEAD(&gjv->changed_list);
gjv->o = o;
+ gjv->dialog = dialog;
+ gjv->client = gc;
flist_add_tail(&gjv->list, &gjv_list);
gopt_add_group_tabs(notebook, gjv);
gopt_add_options(gjv, o);
+ gopt_dialog_update_apply(gjv);
}
gtk_widget_show_all(dialog);
- gtk_dialog_run(GTK_DIALOG(dialog));
-
- while (!flist_empty(&gjv_list)) {
- gjv = flist_entry(gjv_list.next, struct gopt_job_view, list);
-
- gopt_handle_changed_options(gjv);
-
- flist_del(&gjv->list);
- free(gjv);
- }
+ gopt_handle_option_dialog(dialog, &gjv_list);
gtk_widget_destroy(dialog);
}