X-Git-Url: https://git.kernel.dk/?p=fio.git;a=blobdiff_plain;f=gfio.c;h=a67accf4b885189f493a12c1a769cbf0a14304b5;hp=d491abaf629cac463e8a6e99352cca5995ff5b90;hb=284b1e65aa9b35c67d8392e2257fd53b310bb1a3;hpb=2c77d831cbe69c88d7cf8c2d9cc83cec35390bd8;ds=sidebyside diff --git a/gfio.c b/gfio.c index d491abaf..a67accf4 100644 --- a/gfio.c +++ b/gfio.c @@ -158,6 +158,9 @@ struct gui_entry { 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; @@ -187,70 +190,36 @@ static void gfio_update_thread_status(struct gui_entry *ge, char *status_message 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; } @@ -485,10 +454,6 @@ static void update_button_states(struct gui *ui, struct gui_entry *ge) 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); @@ -1068,9 +1033,55 @@ static gboolean results_window_delete(GtkWidget *w, gpointer data) 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", "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 = " \ + \ + \ + \ + \ + \ + \ + \ + \ + \ +"; + +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; @@ -1081,10 +1092,16 @@ static GtkWidget *get_results_window(struct gui_entry *ge) 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; @@ -1579,7 +1596,7 @@ static void gfio_update_thread_status_all(char *status_message, double perc) 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; @@ -1670,8 +1687,14 @@ static void gfio_client_job_start(struct fio_client *client, struct fio_net_cmd 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, @@ -1684,14 +1707,50 @@ struct client_ops gfio_client_ops = { .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) @@ -2041,25 +2100,6 @@ static struct gui_entry *alloc_new_gui_entry(struct gui *ui) 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; @@ -2067,7 +2107,7 @@ static struct gui_entry *get_new_ge_with_tab(const char *name) 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); @@ -2146,12 +2186,21 @@ static void file_close(GtkWidget *w, gpointer data) 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) @@ -2602,7 +2651,7 @@ static void set_job_menu_visible(struct gui *ui, int visible) 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");