/*
* gfio - gui front end for fio - the flexible io tester
*
- * Copyright (C) 2012 Stephen M. Cameron <stephenmcameron@gmail.com>
+ * Copyright (C) 2012 Stephen M. Cameron <stephenmcameron@gmail.com>
* Copyright (C) 2012 Jens Axboe <axboe@kernel.dk>
*
* The license below covers all files distributed with fio unless otherwise
static unsigned int gfio_graph_limit = 100;
GdkColor gfio_color_white;
-const char *gfio_graph_font;
+GdkColor gfio_color_lightyellow;
+const char *gfio_graph_font = GRAPH_DEFAULT_FONT;
typedef void (*clickfunction)(GtkWidget *widget, gpointer data);
},
};
-static struct graph *setup_iops_graph(void)
+static void setup_iops_graph(struct gfio_graphs *gg)
{
struct graph *g;
g = graph_new(DRAWING_AREA_XDIM / 2.0, DRAWING_AREA_YDIM, gfio_graph_font);
graph_title(g, "IOPS (IOs/sec)");
graph_x_title(g, "Time (secs)");
- graph_add_label(g, "Read IOPS");
- graph_add_label(g, "Write IOPS");
- graph_set_color(g, "Read IOPS", 0.13, 0.54, 0.13);
- graph_set_color(g, "Write IOPS", 1.0, 0.0, 0.0);
+ gg->read_iops = graph_add_label(g, "Read IOPS");
+ gg->write_iops = graph_add_label(g, "Write IOPS");
+ gg->trim_iops = graph_add_label(g, "Trim IOPS");
+ graph_set_color(g, gg->read_iops, GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+ graph_set_color(g, gg->write_iops, GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+ graph_set_color(g, gg->trim_iops, GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
line_graph_set_data_count_limit(g, gfio_graph_limit);
graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
- return g;
+ graph_set_graph_all_zeroes(g, 0);
+ gg->iops_graph = g;
}
-static struct graph *setup_bandwidth_graph(void)
+static void setup_bandwidth_graph(struct gfio_graphs *gg)
{
struct graph *g;
g = graph_new(DRAWING_AREA_XDIM / 2.0, DRAWING_AREA_YDIM, gfio_graph_font);
graph_title(g, "Bandwidth (bytes/sec)");
graph_x_title(g, "Time (secs)");
- graph_add_label(g, "Read Bandwidth");
- graph_add_label(g, "Write Bandwidth");
- graph_set_color(g, "Read Bandwidth", 0.13, 0.54, 0.13);
- graph_set_color(g, "Write Bandwidth", 1.0, 0.0, 0.0);
+ gg->read_bw = graph_add_label(g, "Read Bandwidth");
+ gg->write_bw = graph_add_label(g, "Write Bandwidth");
+ gg->trim_bw = graph_add_label(g, "Trim Bandwidth");
+ graph_set_color(g, gg->read_bw, GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+ graph_set_color(g, gg->write_bw, GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+ graph_set_color(g, gg->trim_bw, GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
graph_set_base_offset(g, 1);
line_graph_set_data_count_limit(g, 100);
graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
- return g;
+ graph_set_graph_all_zeroes(g, 0);
+ gg->bandwidth_graph = g;
}
static void setup_graphs(struct gfio_graphs *g)
{
- g->iops_graph = setup_iops_graph();
- g->bandwidth_graph = setup_bandwidth_graph();
+ setup_iops_graph(g);
+ setup_bandwidth_graph(g);
}
void clear_ge_ui_info(struct gui_entry *ge)
GtkListStore *model;
GtkWidget *tree_view;
- model = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_INT, G_TYPE_STRING);
+ model = gtk_list_store_new(4, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING, G_TYPE_STRING);
tree_view = gtk_tree_view_new_with_model(GTK_TREE_MODEL(model));
gtk_widget_set_can_focus(tree_view, FALSE);
static gint on_config_drawing_area(GtkWidget *w, GdkEventConfigure *event,
gpointer data)
{
+ guint width = gtk_widget_get_allocated_width(w);
+ guint height = gtk_widget_get_allocated_height(w);
struct gfio_graphs *g = data;
- graph_set_size(g->iops_graph, w->allocation.width / 2.0, w->allocation.height);
- graph_set_position(g->iops_graph, w->allocation.width / 2.0, 0.0);
- graph_set_size(g->bandwidth_graph, w->allocation.width / 2.0, w->allocation.height);
+ graph_set_size(g->iops_graph, width / 2.0, height);
+ graph_set_position(g->iops_graph, width / 2.0, 0.0);
+ graph_set_size(g->bandwidth_graph, width / 2.0, height);
graph_set_position(g->bandwidth_graph, 0, 0);
return TRUE;
}
struct gfio_graphs *g = p;
cairo_t *cr;
- cr = gdk_cairo_create(w->window);
+ cr = gdk_cairo_create(gtk_widget_get_window(w));
if (graph_has_tooltips(g->iops_graph) ||
graph_has_tooltips(g->bandwidth_graph)) {
{
struct gfio_client *gc = ge->client;
- if (gc && gc->client) {
- if (ge->state >= GE_STATE_CONNECTED)
- fio_client_terminate(gc->client);
+ if (gc) {
+ if (gc->client) {
+ if (ge->state >= GE_STATE_CONNECTED)
+ fio_client_terminate(gc->client);
- fio_put_client(gc->client);
+ fio_put_client(gc->client);
+ }
+ free(gc);
}
+ g_hash_table_remove(ge->ui->ge_hash, &ge->page_num);
+
free(ge->job_file);
free(ge->host);
- flist_del(&ge->list);
free(ge);
}
static void gfio_quit(struct gui *ui)
{
- struct gui_entry *ge;
-
- while (!flist_empty(&ui->list)) {
- ge = flist_entry(ui->list.next, struct gui_entry, list);
- ge_destroy(ge);
- }
-
- gtk_main_quit();
+ gtk_main_quit();
}
static void quit_clicked(__attribute__((unused)) GtkWidget *widget,
- __attribute__((unused)) gpointer data)
+ gpointer data)
{
struct gui *ui = (struct gui *) data;
struct gfio_client *gc = ge->client;
int ret = 0;
- ret = fio_client_send_ini(gc->client, ge->job_file);
+ /*
+ * Prune old options, we are expecting the return options
+ * when the job file is parsed remotely and returned to us.
+ */
+ while (!flist_empty(&gc->o_list)) {
+ struct gfio_client_options *gco;
+
+ gco = flist_first_entry(&gc->o_list, struct gfio_client_options, list);
+ flist_del(&gco->list);
+ free(gco);
+ }
+
+ ret = fio_client_send_ini(gc->client, ge->job_file, 0);
if (!ret)
return 0;
}
static void start_job_clicked(__attribute__((unused)) GtkWidget *widget,
- gpointer data)
+ gpointer data)
{
struct gui_entry *ge = data;
struct gfio_client *gc = ge->client;
* or not. Show it if we are a localhost and using network,
* or using a socket.
*/
- ctext = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw->combo));
+ ctext = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(cw->combo));
if (!ctext || !strncmp(ctext, "IPv4", 4) || !strncmp(ctext, "IPv6", 4))
uses_net = 1;
g_free(ctext);
gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw->button), 0);
gtk_widget_set_sensitive(cw->button, 0);
}
- }
+}
- static int get_connection_details(struct gui_entry *ge)
- {
- GtkWidget *dialog, *box, *vbox, *hbox, *frame, *pentry;
- struct connection_widgets cw;
- struct gui *ui = ge->ui;
- char *typeentry;
-
- if (ge->host)
- return 0;
-
- dialog = gtk_dialog_new_with_buttons("Connection details",
- GTK_WINDOW(ui->window),
- GTK_DIALOG_DESTROY_WITH_PARENT,
- GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
- GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
-
- frame = gtk_frame_new("Hostname / socket name");
- /* gtk_dialog_get_content_area() is 2.14 and newer */
- vbox = GTK_DIALOG(dialog)->vbox;
- gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
-
- box = gtk_vbox_new(FALSE, 6);
- gtk_container_add(GTK_CONTAINER(frame), box);
-
- hbox = gtk_hbox_new(TRUE, 10);
- gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
- cw.hentry = gtk_entry_new();
- gtk_entry_set_text(GTK_ENTRY(cw.hentry), "localhost");
- gtk_box_pack_start(GTK_BOX(hbox), cw.hentry, TRUE, TRUE, 0);
-
- frame = gtk_frame_new("Port");
- gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
- box = gtk_vbox_new(FALSE, 10);
- gtk_container_add(GTK_CONTAINER(frame), box);
-
- hbox = gtk_hbox_new(TRUE, 4);
- gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
- pentry = create_spinbutton(hbox, 1, 65535, FIO_NET_PORT);
-
- frame = gtk_frame_new("Type");
- gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
- box = gtk_vbox_new(FALSE, 10);
- gtk_container_add(GTK_CONTAINER(frame), box);
-
- hbox = gtk_hbox_new(TRUE, 4);
- gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
-
- cw.combo = gtk_combo_box_new_text();
- gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "IPv4");
- gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "IPv6");
- gtk_combo_box_append_text(GTK_COMBO_BOX(cw.combo), "local socket");
- gtk_combo_box_set_active(GTK_COMBO_BOX(cw.combo), 0);
-
- gtk_container_add(GTK_CONTAINER(hbox), cw.combo);
-
- frame = gtk_frame_new("Options");
- gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
- box = gtk_vbox_new(FALSE, 10);
- gtk_container_add(GTK_CONTAINER(frame), box);
-
- hbox = gtk_hbox_new(TRUE, 4);
- gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
-
- cw.button = gtk_check_button_new_with_label("Auto-spawn fio backend");
- gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw.button), 1);
- gtk_widget_set_tooltip_text(cw.button, "When running fio locally, it is necessary to have the backend running on the same system. If this is checked, gfio will start the backend automatically for you if it isn't already running.");
- gtk_box_pack_start(GTK_BOX(hbox), cw.button, FALSE, FALSE, 6);
+static int get_connection_details(struct gui_entry *ge)
+{
+ GtkWidget *dialog, *box, *vbox, *hbox, *frame, *pentry;
+ struct connection_widgets cw;
+ struct gui *ui = ge->ui;
+ char *typeentry;
- /*
- * Connect edit signal, so we can show/not-show the auto start button
- */
- g_signal_connect(GTK_OBJECT(cw.hentry), "changed", G_CALLBACK(hostname_cb), &cw);
- g_signal_connect(GTK_OBJECT(cw.combo), "changed", G_CALLBACK(hostname_cb), &cw);
+ if (ge->host)
+ return 0;
- gtk_widget_show_all(dialog);
+ dialog = gtk_dialog_new_with_buttons("Connection details",
+ GTK_WINDOW(ui->window),
+ GTK_DIALOG_DESTROY_WITH_PARENT,
+ GTK_STOCK_OK, GTK_RESPONSE_ACCEPT,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT, NULL);
- if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
- gtk_widget_destroy(dialog);
- return 1;
- }
+ frame = gtk_frame_new("Hostname / socket name");
+ vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+
+ box = gtk_vbox_new(FALSE, 6);
+ gtk_container_add(GTK_CONTAINER(frame), box);
+
+ hbox = gtk_hbox_new(TRUE, 10);
+ gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
+ cw.hentry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(cw.hentry), "localhost");
+ gtk_box_pack_start(GTK_BOX(hbox), cw.hentry, TRUE, TRUE, 0);
+
+ frame = gtk_frame_new("Port");
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+ box = gtk_vbox_new(FALSE, 10);
+ gtk_container_add(GTK_CONTAINER(frame), box);
+
+ hbox = gtk_hbox_new(TRUE, 4);
+ gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
+ pentry = create_spinbutton(hbox, 1, 65535, FIO_NET_PORT);
+
+ frame = gtk_frame_new("Type");
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+ box = gtk_vbox_new(FALSE, 10);
+ gtk_container_add(GTK_CONTAINER(frame), box);
+
+ hbox = gtk_hbox_new(TRUE, 4);
+ gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
- ge->host = strdup(gtk_entry_get_text(GTK_ENTRY(cw.hentry)));
- ge->port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry));
+ cw.combo = gtk_combo_box_text_new();
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "IPv4");
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "IPv6");
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(cw.combo), "local socket");
+ gtk_combo_box_set_active(GTK_COMBO_BOX(cw.combo), 0);
- typeentry = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw.combo));
- if (!typeentry || !strncmp(typeentry, "IPv4", 4))
- ge->type = Fio_client_ipv4;
- else if (!strncmp(typeentry, "IPv6", 4))
- ge->type = Fio_client_ipv6;
- else
- ge->type = Fio_client_socket;
- g_free(typeentry);
+ gtk_container_add(GTK_CONTAINER(hbox), cw.combo);
- ge->server_start = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw.button));
+ frame = gtk_frame_new("Options");
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
+ box = gtk_vbox_new(FALSE, 10);
+ gtk_container_add(GTK_CONTAINER(frame), box);
+ hbox = gtk_hbox_new(TRUE, 4);
+ gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
+
+ cw.button = gtk_check_button_new_with_label("Auto-spawn fio backend");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw.button), 1);
+ gtk_widget_set_tooltip_text(cw.button, "When running fio locally, it is necessary to have the backend running on the same system. If this is checked, gfio will start the backend automatically for you if it isn't already running.");
+ gtk_box_pack_start(GTK_BOX(hbox), cw.button, FALSE, FALSE, 6);
+
+ /*
+ * Connect edit signal, so we can show/not-show the auto start button
+ */
+ g_signal_connect(G_OBJECT(cw.hentry), "changed", G_CALLBACK(hostname_cb), &cw);
+ g_signal_connect(G_OBJECT(cw.combo), "changed", G_CALLBACK(hostname_cb), &cw);
+
+ gtk_widget_show_all(dialog);
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
gtk_widget_destroy(dialog);
- return 0;
+ return 1;
}
- static void gfio_set_client(struct gfio_client *gc, struct fio_client *client)
- {
- gc->client = fio_get_client(client);
- client->client_data = gc;
- }
+ ge->host = strdup(gtk_entry_get_text(GTK_ENTRY(cw.hentry)));
+ ge->port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry));
- static void gfio_client_added(struct gui_entry *ge, struct fio_client *client)
- {
- struct gfio_client *gc;
-
- gc = malloc(sizeof(*gc));
- memset(gc, 0, sizeof(*gc));
- options_default_fill(&gc->o);
- gc->ge = ge;
- ge->client = gc;
- gfio_set_client(gc, client);
- }
+ typeentry = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(cw.combo));
+ if (!typeentry || !strncmp(typeentry, "IPv4", 4))
+ ge->type = Fio_client_ipv4;
+ else if (!strncmp(typeentry, "IPv6", 4))
+ ge->type = Fio_client_ipv6;
+ else
+ ge->type = Fio_client_socket;
+ g_free(typeentry);
- static void connect_clicked(GtkWidget *widget, gpointer data)
- {
- struct gui_entry *ge = data;
- struct gfio_client *gc = ge->client;
+ ge->server_start = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw.button));
- if (ge->state == GE_STATE_NEW) {
- int ret;
+ gtk_widget_destroy(dialog);
+ return 0;
+}
- if (!ge->job_file)
- file_open(widget, ge->ui);
- if (!ge->job_file)
- return;
+static void gfio_set_client(struct gfio_client *gc, struct fio_client *client)
+{
+ gc->client = fio_get_client(client);
+ client->client_data = gc;
+}
+
+static void gfio_client_added(struct gui_entry *ge, struct fio_client *client)
+{
+ struct gfio_client_options *gco;
+ struct gfio_client *gc;
+
+ gc = calloc(1, sizeof(*gc));
+ INIT_FLIST_HEAD(&gc->o_list);
+ gc->ge = ge;
+ ge->client = gc;
+ gfio_set_client(gc, client);
+
+ /*
+ * Just add a default set of options, need to consider how best
+ * to handle this
+ */
+ gco = calloc(1, sizeof(*gco));
+ INIT_FLIST_HEAD(&gco->list);
+ options_default_fill(&gco->o);
+ flist_add_tail(&gco->list, &gc->o_list);
+ gc->o_list_nr++;
+}
+
+static void gfio_clear_graph_data(struct gfio_graphs *g)
+{
+ graph_clear_values(g->iops_graph);
+ graph_clear_values(g->bandwidth_graph);
+}
+
+static void connect_clicked(GtkWidget *widget, gpointer data)
+{
+ struct gui_entry *ge = data;
+ struct gfio_client *gc = ge->client;
- gc = ge->client;
+ if (ge->state == GE_STATE_NEW) {
+ int ret;
+
+ if (!ge->job_file)
+ file_open(widget, ge->ui);
+ if (!ge->job_file)
+ return;
- if (!gc->client) {
- struct fio_client *client;
+ gc = ge->client;
- if (get_connection_details(ge)) {
- gfio_report_error(ge, "Failed to get connection details\n");
- return;
- }
+ if (!gc->client) {
+ struct fio_client *client;
- client = fio_client_add_explicit(&gfio_client_ops, ge->host, ge->type, ge->port);
- if (!client) {
- gfio_report_error(ge, "Failed to add client %s\n", ge->host);
- free(ge->host);
- ge->host = NULL;
- return;
- }
- gfio_set_client(gc, client);
+ if (get_connection_details(ge)) {
+ gfio_report_error(ge, "Failed to get connection details\n");
+ return;
}
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ge->thread_status_pb), "No jobs running");
- gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ge->thread_status_pb), 0.0);
- ret = fio_client_connect(gc->client);
- if (!ret) {
- if (!ge->ui->handler_running)
- pthread_create(&ge->ui->t, NULL, job_thread, ge->ui);
- gfio_set_state(ge, GE_STATE_CONNECTED);
- } else {
- gfio_report_error(ge, "Failed to connect to %s: %s\n", ge->client->client->hostname, strerror(-ret));
+ client = fio_client_add_explicit(&gfio_client_ops, ge->host, ge->type, ge->port);
+ if (!client) {
+ gfio_report_error(ge, "Failed to add client %s\n", ge->host);
+ free(ge->host);
+ ge->host = NULL;
+ return;
}
+ gfio_set_client(gc, client);
+ }
+
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ge->thread_status_pb), "No jobs running");
+ gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ge->thread_status_pb), 0.0);
+ ret = fio_client_connect(gc->client);
+ if (!ret) {
+ if (!ge->ui->handler_running)
+ pthread_create(&ge->ui->t, NULL, job_thread, ge->ui);
+ gfio_set_state(ge, GE_STATE_CONNECTED);
+ gfio_clear_graph_data(&ge->graphs);
} else {
- fio_client_terminate(gc->client);
- gfio_set_state(ge, GE_STATE_NEW);
- clear_ge_ui_info(ge);
+ gfio_report_error(ge, "Failed to connect to %s: %s\n", ge->client->client->hostname, strerror(-ret));
}
+ } else {
+ fio_client_terminate(gc->client);
+ gfio_set_state(ge, GE_STATE_NEW);
+ clear_ge_ui_info(ge);
}
+}
- static void send_clicked(GtkWidget *widget, gpointer data)
- {
- struct gui_entry *ge = data;
+static void send_clicked(GtkWidget *widget, gpointer data)
+{
+ struct gui_entry *ge = data;
- if (send_job_file(ge))
- gtk_widget_set_sensitive(ge->button[GFIO_BUTTON_START], 1);
- }
+ if (send_job_file(ge))
+ gtk_widget_set_sensitive(ge->button[GFIO_BUTTON_START], 1);
+}
- static GtkWidget *new_client_page(struct gui_entry *ge);
+static GtkWidget *new_client_page(struct gui_entry *ge);
- static struct gui_entry *alloc_new_gui_entry(struct gui *ui)
- {
- struct gui_entry *ge;
-
- ge = malloc(sizeof(*ge));
- memset(ge, 0, sizeof(*ge));
- ge->state = GE_STATE_NEW;
- INIT_FLIST_HEAD(&ge->list);
- flist_add_tail(&ge->list, &ui->list);
- ge->ui = ui;
- return ge;
- }
+static struct gui_entry *alloc_new_gui_entry(struct gui *ui)
+{
+ struct gui_entry *ge;
- static struct gui_entry *get_new_ge_with_tab(struct gui *ui, const char *name)
- {
- struct gui_entry *ge;
+ ge = malloc(sizeof(*ge));
+ memset(ge, 0, sizeof(*ge));
+ ge->state = GE_STATE_NEW;
+ ge->ui = ui;
+ return ge;
+}
- ge = alloc_new_gui_entry(ui);
+static struct gui_entry *get_new_ge_with_tab(struct gui *ui, const char *name)
+{
+ struct gui_entry *ge;
- ge->vbox = new_client_page(ge);
- g_signal_connect(ge->vbox, "destroy", G_CALLBACK(ge_widget_destroy), ge);
+ ge = alloc_new_gui_entry(ui);
- ge->page_label = gtk_label_new(name);
- ge->page_num = gtk_notebook_append_page(GTK_NOTEBOOK(ui->notebook), ge->vbox, ge->page_label);
+ ge->vbox = new_client_page(ge);
+ g_signal_connect(ge->vbox, "destroy", G_CALLBACK(ge_widget_destroy), ge);
- gtk_widget_show_all(ui->window);
- return ge;
- }
+ ge->page_label = gtk_label_new(name);
+ ge->page_num = gtk_notebook_append_page(GTK_NOTEBOOK(ui->notebook), ge->vbox, ge->page_label);
- static void file_new(GtkWidget *w, gpointer data)
- {
- struct gui *ui = (struct gui *) data;
- struct gui_entry *ge;
+ g_hash_table_insert(ui->ge_hash, &ge->page_num, ge);
- ge = get_new_ge_with_tab(ui, "Untitled");
- gtk_notebook_set_current_page(GTK_NOTEBOOK(ui->notebook), ge->page_num);
+ gtk_widget_show_all(ui->window);
+ return ge;
+}
+
+static void file_new(GtkWidget *w, gpointer data)
+{
+ struct gui *ui = (struct gui *) data;
+ struct gui_entry *ge;
+
+ ge = get_new_ge_with_tab(ui, "Untitled");
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(ui->notebook), ge->page_num);
+}
+
+/*
+ * Return the 'ge' corresponding to the tab. If the active tab is the
+ * main tab, open a new tab.
+ */
+static struct gui_entry *get_ge_from_page(struct gui *ui, gint cur_page,
+ int *created)
+{
+ if (!cur_page) {
+ if (created)
+ *created = 1;
+ return get_new_ge_with_tab(ui, "Untitled");
}
+ if (created)
+ *created = 0;
+
+ return g_hash_table_lookup(ui->ge_hash, &cur_page);
+}
+
+static struct gui_entry *get_ge_from_cur_tab(struct gui *ui)
+{
+ gint cur_page;
+
/*
- * Return the 'ge' corresponding to the tab. If the active tab is the
- * main tab, open a new tab.
+ * Main tab is tab 0, so any current page other than 0 holds
+ * a ge entry.
*/
- static struct gui_entry *get_ge_from_page(struct gui *ui, gint cur_page,
- int *created)
- {
- struct flist_head *entry;
- struct gui_entry *ge;
+ cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(ui->notebook));
+ if (cur_page)
+ return get_ge_from_page(ui, cur_page, NULL);
- if (!cur_page) {
- if (created)
- *created = 1;
- return get_new_ge_with_tab(ui, "Untitled");
- }
+ return NULL;
+}
- if (created)
- *created = 0;
+static void file_close(GtkWidget *w, gpointer data)
+{
+ struct gui *ui = (struct gui *) data;
+ struct gui_entry *ge;
- flist_for_each(entry, &ui->list) {
- ge = flist_entry(entry, struct gui_entry, list);
- if (ge->page_num == cur_page)
- return ge;
- }
+ /*
+ * Can't close the main tab
+ */
+ ge = get_ge_from_cur_tab(ui);
+ if (ge) {
+ gtk_widget_destroy(ge->vbox);
+ return;
+ }
- return NULL;
+ if (g_hash_table_size(ui->ge_hash)) {
+ gfio_report_info(ui, "Error", "The main page view cannot be closed\n");
+ return;
}
- static struct gui_entry *get_ge_from_cur_tab(struct gui *ui)
- {
- gint cur_page;
+ gfio_quit(ui);
+}
- /*
- * Main tab is tab 0, so any current page other than 0 holds
- * a ge entry.
- */
- cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(ui->notebook));
- if (cur_page)
- return get_ge_from_page(ui, cur_page, NULL);
+static void file_add_recent(struct gui *ui, const gchar *uri)
+{
+ GtkRecentData grd;
- return NULL;
- }
+ memset(&grd, 0, sizeof(grd));
+ grd.display_name = strdup("gfio");
+ grd.description = strdup("Fio job file");
+ grd.mime_type = strdup(GFIO_MIME);
+ grd.app_name = strdup(g_get_application_name());
+ grd.app_exec = strdup("gfio %f/%u");
- static void file_close(GtkWidget *w, gpointer data)
- {
- struct gui *ui = (struct gui *) data;
- struct gui_entry *ge;
+ gtk_recent_manager_add_full(ui->recentmanager, uri, &grd);
+}
- /*
- * Can't close the main tab
- */
- ge = get_ge_from_cur_tab(ui);
- if (ge) {
- gtk_widget_destroy(ge->vbox);
- return;
- }
+static gchar *get_filename_from_uri(const gchar *uri)
+{
+ if (strncmp(uri, "file://", 7))
+ return strdup(uri);
- if (!flist_empty(&ui->list)) {
- gfio_report_info(ui, "Error", "The main page view cannot be closed\n");
- return;
- }
+ return strdup(uri + 7);
+}
- gfio_quit(ui);
- }
+static int do_file_open(struct gui_entry *ge, const gchar *uri)
+{
+ struct fio_client *client;
- static void file_add_recent(struct gui *ui, const gchar *uri)
- {
- GtkRecentData grd;
+ assert(!ge->job_file);
- memset(&grd, 0, sizeof(grd));
- grd.display_name = strdup("gfio");
- grd.description = strdup("Fio job file");
- grd.mime_type = strdup(GFIO_MIME);
- grd.app_name = strdup(g_get_application_name());
- grd.app_exec = strdup("gfio %f/%u");
+ ge->job_file = get_filename_from_uri(uri);
- gtk_recent_manager_add_full(ui->recentmanager, uri, &grd);
- }
+ client = fio_client_add_explicit(&gfio_client_ops, ge->host, ge->type, ge->port);
+ if (client) {
+ char *label = strdup(uri);
- static gchar *get_filename_from_uri(const gchar *uri)
- {
- if (strncmp(uri, "file://", 7))
- return strdup(uri);
+ basename(label);
+ gtk_label_set_text(GTK_LABEL(ge->page_label), basename(label));
+ free(label);
- return strdup(uri + 7);
+ gfio_client_added(ge, client);
+ file_add_recent(ge->ui, uri);
+ return 0;
}
- static int do_file_open(struct gui_entry *ge, const gchar *uri)
- {
- struct fio_client *client;
+ gfio_report_error(ge, "Failed to add client %s\n", ge->host);
+ free(ge->host);
+ ge->host = NULL;
+ free(ge->job_file);
+ ge->job_file = NULL;
+ return 1;
+}
+
+static int do_file_open_with_tab(struct gui *ui, const gchar *uri)
+{
+ struct gui_entry *ge;
+ gint cur_page;
+ int ret, ge_is_new = 0;
- assert(!ge->job_file);
+ /*
+ * Creates new tab if current tab is the main window, or the
+ * current tab already has a client.
+ */
+ cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(ui->notebook));
+ ge = get_ge_from_page(ui, cur_page, &ge_is_new);
+ if (ge->client) {
+ ge = get_new_ge_with_tab(ui, "Untitled");
+ ge_is_new = 1;
+ }
- ge->job_file = get_filename_from_uri(uri);
+ gtk_notebook_set_current_page(GTK_NOTEBOOK(ui->notebook), ge->page_num);
- client = fio_client_add_explicit(&gfio_client_ops, ge->host, ge->type, ge->port);
- if (client) {
- gfio_client_added(ge, client);
- file_add_recent(ge->ui, uri);
- return 0;
- }
+ if (get_connection_details(ge)) {
+ if (ge_is_new)
+ gtk_widget_destroy(ge->vbox);
- gfio_report_error(ge, "Failed to add client %s\n", ge->host);
- free(ge->host);
- ge->host = NULL;
return 1;
}
- static int do_file_open_with_tab(struct gui *ui, const gchar *uri)
- {
- struct gui_entry *ge;
- gint cur_page;
- int ret, ge_is_new = 0;
+ ret = do_file_open(ge, uri);
- /*
- * Creates new tab if current tab is the main window, or the
- * current tab already has a client.
- */
- cur_page = gtk_notebook_get_current_page(GTK_NOTEBOOK(ui->notebook));
- ge = get_ge_from_page(ui, cur_page, &ge_is_new);
- if (ge->client) {
- ge = get_new_ge_with_tab(ui, "Untitled");
- ge_is_new = 1;
- }
+ if (!ret) {
+ if (ge->server_start)
+ gfio_start_server(ui);
+ } else {
+ if (ge_is_new)
+ gtk_widget_destroy(ge->vbox);
+ }
- gtk_notebook_set_current_page(GTK_NOTEBOOK(ui->notebook), ge->page_num);
+ return ret;
+}
- if (get_connection_details(ge)) {
- if (ge_is_new)
- gtk_widget_destroy(ge->vbox);
-
- return 1;
- }
+static void recent_open(GtkAction *action, gpointer data)
+{
+ struct gui *ui = (struct gui *) data;
+ GtkRecentInfo *info;
+ const gchar *uri;
- ret = do_file_open(ge, uri);
+ info = g_object_get_data(G_OBJECT(action), "gtk-recent-info");
+ uri = gtk_recent_info_get_uri(info);
- if (!ret) {
- if (ge->server_start)
- gfio_start_server(ui);
- } else {
- if (ge_is_new)
- gtk_widget_destroy(ge->vbox);
- }
+ do_file_open_with_tab(ui, uri);
+}
- return ret;
- }
+static void file_open(GtkWidget *w, gpointer data)
+{
+ struct gui *ui = data;
+ GtkWidget *dialog;
+ GtkFileFilter *filter;
+ gchar *filename;
- static void recent_open(GtkAction *action, gpointer data)
- {
- struct gui *ui = (struct gui *) data;
- GtkRecentInfo *info;
- const gchar *uri;
+ dialog = gtk_file_chooser_dialog_new("Open File",
+ GTK_WINDOW(ui->window),
+ GTK_FILE_CHOOSER_ACTION_OPEN,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
+ NULL);
+ gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE);
- info = g_object_get_data(G_OBJECT(action), "gtk-recent-info");
- uri = gtk_recent_info_get_uri(info);
+ filter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(filter, "*.fio");
+ gtk_file_filter_add_pattern(filter, "*.job");
+ gtk_file_filter_add_pattern(filter, "*.ini");
+ gtk_file_filter_add_mime_type(filter, GFIO_MIME);
+ gtk_file_filter_set_name(filter, "Fio job file");
+ gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
- do_file_open_with_tab(ui, uri);
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
+ gtk_widget_destroy(dialog);
+ return;
}
- static void file_open(GtkWidget *w, gpointer data)
- {
- struct gui *ui = data;
- GtkWidget *dialog;
- GtkFileFilter *filter;
- gchar *filename;
-
- dialog = gtk_file_chooser_dialog_new("Open File",
- GTK_WINDOW(ui->window),
- GTK_FILE_CHOOSER_ACTION_OPEN,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_OPEN, GTK_RESPONSE_ACCEPT,
- NULL);
- gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), FALSE);
-
- filter = gtk_file_filter_new();
- gtk_file_filter_add_pattern(filter, "*.fio");
- gtk_file_filter_add_pattern(filter, "*.job");
- gtk_file_filter_add_pattern(filter, "*.ini");
- gtk_file_filter_add_mime_type(filter, GFIO_MIME);
- gtk_file_filter_set_name(filter, "Fio job file");
- gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
-
- if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
- gtk_widget_destroy(dialog);
- return;
- }
-
- filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- gtk_widget_destroy(dialog);
+ gtk_widget_destroy(dialog);
- do_file_open_with_tab(ui, filename);
- g_free(filename);
- }
+ do_file_open_with_tab(ui, filename);
+ g_free(filename);
+}
- static void file_save(GtkWidget *w, gpointer data)
- {
- struct gui *ui = data;
- GtkWidget *dialog;
+static void file_save(GtkWidget *w, gpointer data)
+{
+ struct gui *ui = data;
+ GtkWidget *dialog;
- dialog = gtk_file_chooser_dialog_new("Save File",
- GTK_WINDOW(ui->window),
- GTK_FILE_CHOOSER_ACTION_SAVE,
- GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
- GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
- NULL);
+ dialog = gtk_file_chooser_dialog_new("Save File",
+ GTK_WINDOW(ui->window),
+ GTK_FILE_CHOOSER_ACTION_SAVE,
+ GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL,
+ GTK_STOCK_SAVE, GTK_RESPONSE_ACCEPT,
+ NULL);
- gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
- gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "Untitled document");
+ gtk_file_chooser_set_do_overwrite_confirmation(GTK_FILE_CHOOSER(dialog), TRUE);
+ gtk_file_chooser_set_current_name(GTK_FILE_CHOOSER(dialog), "Untitled document");
- if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
- char *filename;
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_ACCEPT) {
+ char *filename;
- filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
- // save_job_file(filename);
- g_free(filename);
- }
- gtk_widget_destroy(dialog);
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ // save_job_file(filename);
+ g_free(filename);
}
+ gtk_widget_destroy(dialog);
+}
static void view_log_destroy(GtkWidget *w, gpointer data)
{
struct gui *ui = (struct gui *) data;
- gtk_widget_ref(ui->log_tree);
+ g_object_ref(G_OBJECT(ui->log_tree));
gtk_container_remove(GTK_CONTAINER(w), ui->log_tree);
gtk_widget_destroy(w);
ui->log_view = NULL;
gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroll), GTK_POLICY_AUTOMATIC, GTK_POLICY_AUTOMATIC);
box = gtk_hbox_new(TRUE, 0);
- gtk_box_pack_start_defaults(GTK_BOX(box), ui->log_tree);
+ gtk_box_pack_start(GTK_BOX(box), ui->log_tree, TRUE, TRUE, 0);
g_signal_connect(box, "destroy", G_CALLBACK(view_log_destroy), ui);
gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(scroll), box);
vbox = gtk_vbox_new(TRUE, 5);
- gtk_box_pack_start_defaults(GTK_BOX(vbox), scroll);
+ gtk_box_pack_start(GTK_BOX(vbox), scroll, TRUE, TRUE, 0);
gtk_container_add(GTK_CONTAINER(win), vbox);
gtk_widget_show_all(win);
{
struct gui *ui = (struct gui *) data;
struct gui_entry *ge;
-
+
ge = get_ge_from_cur_tab(ui);
if (ge)
connect_clicked(w, ge);
ge = get_ge_from_cur_tab(ui);
if (ge && ge->client)
- gopt_get_options_window(ui->window, &ge->client->o);
+ gopt_get_options_window(ui->window, ge->client);
}
static void start_job_entry(GtkWidget *w, gpointer data)
gfio_display_end_results(gc);
}
-static void __update_graph_limits(struct gfio_graphs *g)
+static void __update_graph_settings(struct gfio_graphs *g)
{
line_graph_set_data_count_limit(g->iops_graph, gfio_graph_limit);
+ graph_set_font(g->iops_graph, gfio_graph_font);
line_graph_set_data_count_limit(g->bandwidth_graph, gfio_graph_limit);
+ graph_set_font(g->bandwidth_graph, gfio_graph_font);
+}
+
+static void ge_update_settings_fn(gpointer key, gpointer value, gpointer data)
+{
+ struct gui_entry *ge = (struct gui_entry *) value;
+ GdkEvent *ev;
+
+ __update_graph_settings(&ge->graphs);
+
+ ev = gdk_event_new(GDK_EXPOSE);
+ g_signal_emit_by_name(G_OBJECT(ge->graphs.drawing_area), GFIO_DRAW_EVENT, GTK_WIDGET(ge->graphs.drawing_area), ev, &ge->graphs);
+ gdk_event_free(ev);
}
static void update_graph_limits(void)
{
- struct flist_head *entry;
- struct gui_entry *ge;
+ struct gui *ui = &main_ui;
+ GdkEvent *ev;
- __update_graph_limits(&main_ui.graphs);
+ __update_graph_settings(&ui->graphs);
- flist_for_each(entry, &main_ui.list) {
- ge = flist_entry(entry, struct gui_entry, list);
- __update_graph_limits(&ge->graphs);
- }
+ ev = gdk_event_new(GDK_EXPOSE);
+ g_signal_emit_by_name(G_OBJECT(ui->graphs.drawing_area), GFIO_DRAW_EVENT, GTK_WIDGET(ui->graphs.drawing_area), ev, &ui->graphs);
+ gdk_event_free(ev);
+
+ g_hash_table_foreach(ui->ge_hash, ge_update_settings_fn, NULL);
}
static void preferences(GtkWidget *w, gpointer data)
NULL);
frame = gtk_frame_new("Graphing");
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+ vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
vbox = gtk_vbox_new(FALSE, 6);
gtk_container_add(GTK_CONTAINER(frame), vbox);
entry = gtk_label_new("Font face to use for graph labels");
gtk_box_pack_start(GTK_BOX(hbox), entry, TRUE, TRUE, 5);
- font = gtk_font_button_new();
+ font = gtk_font_button_new_with_font(gfio_graph_font);
gtk_box_pack_start(GTK_BOX(hbox), font, FALSE, FALSE, 5);
box = gtk_vbox_new(FALSE, 6);
spin_int = create_spinbutton(hbox, 100, 100000, gfio_client_ops.eta_msec);
frame = gtk_frame_new("Debug logging");
- gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+ vbox = gtk_dialog_get_content_area(GTK_DIALOG(dialog));
+ gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
vbox = gtk_vbox_new(FALSE, 6);
gtk_container_add(GTK_CONTAINER(frame), vbox);
probe_box = gtk_hbox_new(FALSE, 3);
gtk_box_pack_start(GTK_BOX(probe_frame), probe_box, FALSE, FALSE, 3);
- ge->eta.read_bw = new_info_entry_in_frame(probe_box, "Read BW");
- ge->eta.read_iops = new_info_entry_in_frame(probe_box, "IOPS");
- ge->eta.write_bw = new_info_entry_in_frame(probe_box, "Write BW");
- ge->eta.write_iops = new_info_entry_in_frame(probe_box, "IOPS");
+ ge->eta.read_bw = new_info_entry_in_frame_rgb(probe_box, "Read BW", GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+ ge->eta.read_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+ ge->eta.write_bw = new_info_entry_in_frame_rgb(probe_box, "Write BW", GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+ ge->eta.write_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+ ge->eta.trim_bw = new_info_entry_in_frame_rgb(probe_box, "Trim BW", GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
+ ge->eta.trim_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
/*
* Only add this if we have a commit rate
ge->graphs.drawing_area = gtk_drawing_area_new();
gtk_widget_set_size_request(GTK_WIDGET(ge->graphs.drawing_area),
DRAWING_AREA_XDIM, DRAWING_AREA_YDIM);
- gtk_widget_modify_bg(ge->graphs.drawing_area, GTK_STATE_NORMAL, &gfio_color_white);
- g_signal_connect(G_OBJECT(ge->graphs.drawing_area), "expose_event",
+ gtk_widget_modify_bg(ge->graphs.drawing_area, GTK_STATE_NORMAL, &gfio_color_lightyellow);
+ g_signal_connect(G_OBJECT(ge->graphs.drawing_area), GFIO_DRAW_EVENT,
G_CALLBACK(on_expose_drawing_area), &ge->graphs);
g_signal_connect(G_OBJECT(ge->graphs.drawing_area), "configure_event",
G_CALLBACK(on_config_drawing_area), &ge->graphs);
setup_graphs(&ge->graphs);
/*
- * Set up alignments for widgets at the bottom of ui,
+ * Set up alignments for widgets at the bottom of ui,
* align bottom left, expand horizontally but not vertically
*/
bottom_align = gtk_alignment_new(0, 1, 1, 0);
gtk_container_add(GTK_CONTAINER(bottom_align), ge->buttonbox);
gtk_box_pack_start(GTK_BOX(main_vbox), bottom_align, FALSE, FALSE, 0);
- add_buttons(ge, buttonspeclist, ARRAYSIZE(buttonspeclist));
+ add_buttons(ge, buttonspeclist, ARRAY_SIZE(buttonspeclist));
/*
* Set up thread status progress bar
probe_box = gtk_hbox_new(FALSE, 3);
gtk_box_pack_start(GTK_BOX(probe_frame), probe_box, FALSE, FALSE, 3);
ui->eta.jobs = new_info_entry_in_frame(probe_box, "Running");
- ui->eta.read_bw = new_info_entry_in_frame(probe_box, "Read BW");
- ui->eta.read_iops = new_info_entry_in_frame(probe_box, "IOPS");
- ui->eta.write_bw = new_info_entry_in_frame(probe_box, "Write BW");
- ui->eta.write_iops = new_info_entry_in_frame(probe_box, "IOPS");
+ ui->eta.read_bw = new_info_entry_in_frame_rgb(probe_box, "Read BW", GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+ ui->eta.read_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_READ_R, GFIO_READ_G, GFIO_READ_B);
+ ui->eta.write_bw = new_info_entry_in_frame_rgb(probe_box, "Write BW", GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+ ui->eta.write_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_WRITE_R, GFIO_WRITE_G, GFIO_WRITE_B);
+ ui->eta.trim_bw = new_info_entry_in_frame_rgb(probe_box, "Trim BW", GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
+ ui->eta.trim_iops = new_info_entry_in_frame_rgb(probe_box, "IOPS", GFIO_TRIM_R, GFIO_TRIM_G, GFIO_TRIM_B);
/*
* Only add this if we have a commit rate
ui->graphs.drawing_area = gtk_drawing_area_new();
gtk_widget_set_size_request(GTK_WIDGET(ui->graphs.drawing_area),
DRAWING_AREA_XDIM, DRAWING_AREA_YDIM);
- gtk_widget_modify_bg(ui->graphs.drawing_area, GTK_STATE_NORMAL, &gfio_color_white);
- g_signal_connect(G_OBJECT(ui->graphs.drawing_area), "expose_event",
+ gtk_widget_modify_bg(ui->graphs.drawing_area, GTK_STATE_NORMAL, &gfio_color_lightyellow);
+ g_signal_connect(G_OBJECT(ui->graphs.drawing_area), GFIO_DRAW_EVENT,
G_CALLBACK(on_expose_drawing_area), &ui->graphs);
g_signal_connect(G_OBJECT(ui->graphs.drawing_area), "configure_event",
G_CALLBACK(on_config_drawing_area), &ui->graphs);
setup_graphs(&ui->graphs);
/*
- * Set up alignments for widgets at the bottom of ui,
+ * Set up alignments for widgets at the bottom of ui,
* align bottom left, expand horizontally but not vertically
*/
bottom_align = gtk_alignment_new(0, 1, 1, 0);
* Without it, the update that happens in gfio_update_thread_status
* doesn't really happen in a timely fashion, you need expose events
*/
+#if !GTK_CHECK_VERSION(2, 24, 0)
if (!g_thread_supported())
g_thread_init(NULL);
+#endif
+
gdk_threads_init();
gtk_init(argc, argv);
settings = gtk_settings_get_default();
gtk_settings_set_long_property(settings, "gtk_tooltip_timeout", 10, "gfio setting");
+#if !GLIB_CHECK_VERSION(2, 36, 0)
g_type_init();
+#endif
+ gdk_color_parse("#fffff4", &gfio_color_lightyellow);
gdk_color_parse("white", &gfio_color_white);
-
+
ui->window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
gtk_window_set_title(GTK_WINDOW(ui->window), "fio");
gtk_window_set_default_size(GTK_WINDOW(ui->window), 1024, 768);
if (fio_init_options())
return 1;
+ gopt_init();
+
memset(&main_ui, 0, sizeof(main_ui));
- INIT_FLIST_HEAD(&main_ui.list);
+ main_ui.ge_hash = g_hash_table_new(g_int_hash, g_int_equal);
init_ui(&argc, &argv, &main_ui);
gdk_threads_enter();
gtk_main();
gdk_threads_leave();
+
+ g_hash_table_destroy(main_ui.ge_hash);
+
+ gopt_exit();
return 0;
}