GtkWidget *error_label;
GtkWidget *results_notebook;
GtkWidget *results_window;
+ GtkUIManager *results_uimanager;
+ GtkWidget *results_vbox;
+ GtkWidget *results_menu;
GtkListStore *log_model;
GtkWidget *log_tree;
GtkWidget *log_view;
static void gfio_update_thread_status_all(char *status_message, double perc);
void report_error(GError *error);
-static void iops_graph_y_axis_unit_change(struct graph *g, int power_of_ten)
-{
- switch (power_of_ten) {
- case 9: graph_y_title(g, "Billions of IOs / sec");
- break;
- case 6: graph_y_title(g, "Millions of IOs / sec");
- break;
- case 3: graph_y_title(g, "Thousands of IOs / sec");
- break;
- case 0:
- default: graph_y_title(g, "IOs / sec");
- break;
- }
-}
-
static struct graph *setup_iops_graph(void)
{
struct graph *g;
g = graph_new(DRAWING_AREA_XDIM / 2.0, DRAWING_AREA_YDIM, gfio_graph_font);
- graph_title(g, "IOPS");
+ graph_title(g, "IOPS (IOs/sec)");
graph_x_title(g, "Time (secs)");
- graph_y_title(g, "IOs / sec");
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);
line_graph_set_data_count_limit(g, gfio_graph_limit);
- graph_y_axis_unit_change_notify(g, iops_graph_y_axis_unit_change);
- graph_add_extra_space(g, 0.005, 0.005, 0.03, 0.03);
+ graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
return g;
}
-static void bandwidth_graph_y_axis_unit_change(struct graph *g, int power_of_ten)
-{
- switch (power_of_ten) {
- case 9: graph_y_title(g, "Petabytes / sec");
- break;
- case 6: graph_y_title(g, "Gigabytes / sec");
- break;
- case 3: graph_y_title(g, "Megabytes / sec");
- break;
- case 0:
- default: graph_y_title(g, "Kilobytes / sec");
- break;
- }
-}
-
static struct graph *setup_bandwidth_graph(void)
{
struct graph *g;
g = graph_new(DRAWING_AREA_XDIM / 2.0, DRAWING_AREA_YDIM, gfio_graph_font);
- graph_title(g, "Bandwidth");
+ graph_title(g, "Bandwidth (bytes/sec)");
graph_x_title(g, "Time (secs)");
- graph_y_title(g, "Kbytes / sec");
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);
+ graph_set_base_offset(g, 1);
line_graph_set_data_count_limit(g, 100);
- graph_y_axis_unit_change_notify(g, bandwidth_graph_y_axis_unit_change);
- graph_add_extra_space(g, 0.005, 0.005, 0.03, 0.03);
-
+ graph_add_extra_space(g, 0.0, 0.0, 0.0, 0.0);
return g;
}
gtk_widget_set_sensitive(ge->button[START_JOB_BUTTON], start_state);
gtk_button_set_label(GTK_BUTTON(ge->button[CONNECT_BUTTON]), connect_str);
- /*
- * So the below doesn't work at all, how to set those menu items
- * invisibible...
- */
w = gtk_ui_manager_get_widget(ui->uimanager, "/MainMenu/JobMenu/Connect");
gtk_widget_set_sensitive(w, connect_state);
gtk_menu_item_set_label(GTK_MENU_ITEM(w), connect_str);
return TRUE;
}
+static void results_close(GtkWidget *w, gpointer *data)
+{
+ struct gui_entry *ge = (struct gui_entry *) data;
+
+ gtk_widget_destroy(ge->results_window);
+}
+
+static GtkActionEntry results_menu_items[] = {
+ { "FileMenuAction", GTK_STOCK_FILE, "File", NULL, NULL, NULL},
+ { "GraphMenuAction", GTK_STOCK_FILE, "Graph", NULL, NULL, NULL},
+ { "CloseFile", GTK_STOCK_CLOSE, "Close", "<Control>W", NULL, G_CALLBACK(results_close) },
+};
+static gint results_nmenu_items = sizeof(results_menu_items) / sizeof(results_menu_items[0]);
+
+static const gchar *results_ui_string = " \
+ <ui> \
+ <menubar name=\"MainMenu\"> \
+ <menu name=\"FileMenu\" action=\"FileMenuAction\"> \
+ <menuitem name=\"Close\" action=\"CloseFile\" /> \
+ </menu> \
+ <menu name=\"GraphMenu\" action=\"GraphMenuAction\"> \
+ </menu>\
+ </menubar> \
+ </ui> \
+";
+
+static GtkWidget *get_results_menubar(GtkWidget *window, struct gui_entry *ge)
+{
+ GtkActionGroup *action_group;
+ GtkWidget *widget;
+ GError *error = 0;
+
+ ge->results_uimanager = gtk_ui_manager_new();
+
+ action_group = gtk_action_group_new("ResultsMenu");
+ gtk_action_group_add_actions(action_group, results_menu_items, results_nmenu_items, ge);
+
+ gtk_ui_manager_insert_action_group(ge->results_uimanager, action_group, 0);
+ gtk_ui_manager_add_ui_from_string(GTK_UI_MANAGER(ge->results_uimanager), results_ui_string, -1, &error);
+
+ gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(ge->results_uimanager));
+
+ widget = gtk_ui_manager_get_widget(ge->results_uimanager, "/MainMenu");
+ return widget;
+}
+
static GtkWidget *get_results_window(struct gui_entry *ge)
{
- GtkWidget *win, *notebook;
+ GtkWidget *win, *notebook, *vbox;
if (ge->results_window)
return ge->results_notebook;
g_signal_connect(win, "delete-event", G_CALLBACK(results_window_delete), ge);
g_signal_connect(win, "destroy", G_CALLBACK(results_window_delete), ge);
+ vbox = gtk_vbox_new(FALSE, 0);
+ gtk_container_add(GTK_CONTAINER(win), vbox);
+
+ ge->results_menu = get_results_menubar(win, ge);
+ gtk_box_pack_start(GTK_BOX(vbox), ge->results_menu, FALSE, FALSE, 0);
+
notebook = gtk_notebook_new();
gtk_notebook_set_scrollable(GTK_NOTEBOOK(notebook), 1);
gtk_notebook_popup_enable(GTK_NOTEBOOK(notebook));
- gtk_container_add(GTK_CONTAINER(win), notebook);
+ gtk_container_add(GTK_CONTAINER(vbox), notebook);
ge->results_window = win;
ge->results_notebook = notebook;
gtk_widget_queue_draw(ui->window);
}
-static void gfio_quit_op(struct fio_client *client)
+static void gfio_quit_op(struct fio_client *client, struct fio_net_cmd *cmd)
{
struct gfio_client *gc = client->client_data;
gdk_threads_leave();
}
+static void gfio_client_iolog(struct fio_client *client, struct cmd_iolog_pdu *pdu)
+{
+ printf("got iolog: name=%s, type=%u, entries=%u\n", pdu->name, pdu->log_type, pdu->nr_samples);
+ free(pdu);
+}
+
struct client_ops gfio_client_ops = {
- .text_op = gfio_text_op,
+ .text = gfio_text_op,
.disk_util = gfio_disk_util_op,
.thread_status = gfio_thread_status_op,
.group_stats = gfio_group_stats_op,
.stop = gfio_client_stop,
.start = gfio_client_start,
.job_start = gfio_client_job_start,
+ .iolog = gfio_client_iolog,
.eta_msec = FIO_CLIENT_DEF_ETA_MSEC,
.stay_connected = 1,
+ .client_type = FIO_CLIENT_TYPE_GUI,
};
+/*
+ * FIXME: need more handling here
+ */
+static void ge_destroy(struct gui_entry *ge)
+{
+ struct gfio_client *gc = ge->client;
+
+ if (gc && gc->client) {
+ if (ge->state >= GE_STATE_CONNECTED)
+ fio_client_terminate(gc->client);
+
+ fio_put_client(gc->client);
+ }
+
+ flist_del(&ge->list);
+ free(ge);
+}
+
+static void ge_widget_destroy(GtkWidget *w, gpointer data)
+{
+}
+
+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();
+}
+
static void quit_clicked(__attribute__((unused)) GtkWidget *widget,
__attribute__((unused)) gpointer data)
{
- gtk_main_quit();
+ gfio_quit(data);
}
static void *job_thread(void *arg)
return ge;
}
-/*
- * FIXME: need more handling here
- */
-static void ge_destroy(GtkWidget *w, gpointer data)
-{
- struct gui_entry *ge = data;
- struct gfio_client *gc = ge->client;
-
- if (gc && gc->client) {
- if (ge->state >= GE_STATE_CONNECTED)
- fio_client_terminate(gc->client);
-
- fio_put_client(gc->client);
- }
-
- flist_del(&ge->list);
- free(ge);
-}
-
static struct gui_entry *get_new_ge_with_tab(const char *name)
{
struct gui_entry *ge;
ge = alloc_new_gui_entry(&main_ui);
ge->vbox = new_client_page(ge);
- g_signal_connect(ge->vbox, "destroy", G_CALLBACK(ge_destroy), ge);
+ g_signal_connect(ge->vbox, "destroy", G_CALLBACK(ge_widget_destroy), ge);
ge->page_label = gtk_label_new(name);
ge->page_num = gtk_notebook_append_page(GTK_NOTEBOOK(main_ui.notebook), ge->vbox, ge->page_label);
return;
}
- gtk_main_quit();
+ gfio_quit(ui);
}
static void file_add_recent(struct gui *ui, const gchar *uri)
{
- gtk_recent_manager_add_item(ui->recentmanager, uri);
+ GtkRecentData grd;
+
+ 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");
+
+ gtk_recent_manager_add_full(ui->recentmanager, uri, &grd);
}
static gchar *get_filename_from_uri(const gchar *uri)
static GtkWidget *get_menubar_menu(GtkWidget *window, GtkUIManager *ui_manager,
struct gui *ui)
{
- GtkActionGroup *action_group = gtk_action_group_new("Menu");
+ GtkActionGroup *action_group;
GError *error = 0;
action_group = gtk_action_group_new("Menu");