GtkWidget *thread_status_pb;
GtkWidget *buttonbox;
GtkWidget *button[ARRAYSIZE(buttonspeclist)];
- GtkWidget *hostname_hbox;
- GtkWidget *hostname_label;
- GtkWidget *hostname_entry;
- GtkWidget *port_button;
- GtkWidget *port_label;
- GtkWidget *hostname_combo_box; /* ipv4, ipv6 or socket */
GtkWidget *scrolled_window;
GtkWidget *textview;
GtkWidget *error_info_bar;
char **job_files;
} ui;
+static void clear_ui_info(struct gui *ui)
+{
+ gtk_label_set_text(GTK_LABEL(ui->probe.hostname), "");
+ gtk_label_set_text(GTK_LABEL(ui->probe.os), "");
+ gtk_label_set_text(GTK_LABEL(ui->probe.arch), "");
+ gtk_label_set_text(GTK_LABEL(ui->probe.fio_ver), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.name), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.iotype), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.ioengine), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.iodepth), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.jobs), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.files), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.read_bw), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.read_iops), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.write_bw), "");
+ gtk_label_set_text(GTK_LABEL(ui->eta.write_iops), "");
+}
+
static void gfio_set_connected(struct gui *ui, int connected)
{
if (connected) {
gdk_threads_enter();
gfio_set_connected(ui, 0);
+ clear_ui_info(ui);
sprintf(buf, "Client %s: timeout talking to server.\n", client->hostname);
}
}
+static GtkWidget *new_info_label_in_frame(GtkWidget *box, const char *label)
+{
+ GtkWidget *label_widget;
+ GtkWidget *frame;
+
+ frame = gtk_frame_new(label);
+ label_widget = gtk_label_new(NULL);
+ gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 3);
+ gtk_container_add(GTK_CONTAINER(frame), label_widget);
+
+ return label_widget;
+}
+
+static GtkWidget *create_spinbutton(GtkWidget *hbox, double min, double max, double defval)
+{
+ GtkWidget *button, *box;
+
+ box = gtk_hbox_new(FALSE, 3);
+ gtk_container_add(GTK_CONTAINER(hbox), box);
+
+ button = gtk_spin_button_new_with_range(min, max, 1.0);
+ gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
+
+ gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(button), GTK_UPDATE_IF_VALID);
+ gtk_spin_button_set_value(GTK_SPIN_BUTTON(button), defval);
+
+ return button;
+}
+
static void start_job_clicked(__attribute__((unused)) GtkWidget *widget,
gpointer data)
{
start_job_thread(ui);
}
-static void connect_clicked(__attribute__((unused)) GtkWidget *widget,
- gpointer data)
+static void file_open(GtkWidget *w, gpointer data);
+
+static void connect_clicked(GtkWidget *widget, gpointer data)
{
struct gui *ui = data;
if (!ui->connected) {
+ if (!ui->nr_job_files)
+ file_open(widget, data);
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ui->thread_status_pb), "No jobs running");
fio_clients_connect();
pthread_create(&ui->t, NULL, job_thread, NULL);
gfio_set_connected(ui, 1);
- } else
+ } else {
+ fio_clients_terminate();
gfio_set_connected(ui, 0);
+ clear_ui_info(ui);
+ }
}
static void add_button(struct gui *ui, int i, GtkWidget *buttonbox,
}
}
-void report_error(GError* error)
+void report_error(GError *error)
{
if (ui.error_info_bar == NULL) {
ui.error_info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_OK,
}
}
+static int get_connection_details(char **host, int *port, int *type,
+ int *server_start)
+{
+ GtkWidget *dialog, *box, *vbox, *hentry, *hbox, *frame, *pentry, *combo;
+ GtkWidget *button;
+ char *typeentry;
+
+ 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");
+ 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);
+ hentry = gtk_entry_new();
+ gtk_entry_set_text(GTK_ENTRY(hentry), "localhost");
+ gtk_box_pack_start(GTK_BOX(hbox), 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);
+
+ combo = gtk_combo_box_text_new();
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "IPv4");
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "IPv6");
+ gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(combo), "local socket");
+ gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 0);
+
+ gtk_container_add(GTK_CONTAINER(hbox), 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);
+
+ button = gtk_check_button_new_with_label("Auto-spawn fio backend");
+ gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(button), 1);
+ gtk_widget_set_tooltip_text(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), button, FALSE, FALSE, 6);
+
+ gtk_widget_show_all(dialog);
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
+ gtk_widget_destroy(dialog);
+ return 1;
+ }
+
+ *host = strdup(gtk_entry_get_text(GTK_ENTRY(hentry)));
+ *port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry));
+
+ typeentry = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(combo));
+ if (!typeentry || !strncmp(typeentry, "IPv4", 4))
+ *type = Fio_client_ipv4;
+ else if (!strncmp(typeentry, "IPv6", 4))
+ *type = Fio_client_ipv6;
+ else
+ *type = Fio_client_socket;
+ g_free(typeentry);
+
+ *server_start = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+
+ gtk_widget_destroy(dialog);
+ return 0;
+}
+
static void file_open(GtkWidget *w, gpointer data)
{
GtkWidget *dialog;
GSList *filenames, *fn_glist;
GtkFileFilter *filter;
+ char *host;
+ int port, type, server_start;
dialog = gtk_file_chooser_dialog_new("Open File",
GTK_WINDOW(ui.window),
}
fn_glist = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
+
+ gtk_widget_destroy(dialog);
+
+ if (get_connection_details(&host, &port, &type, &server_start))
+ goto err;
+
filenames = fn_glist;
while (filenames != NULL) {
- const char *hostname;
- char *typeentry;
- gint port;
- int type;
-
ui.job_files = realloc(ui.job_files, (ui.nr_job_files + 1) * sizeof(char *));
ui.job_files[ui.nr_job_files] = strdup(filenames->data);
ui.nr_job_files++;
- hostname = gtk_entry_get_text(GTK_ENTRY(ui.hostname_entry));
- port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(ui.port_button));
- typeentry = gtk_combo_box_text_get_active_text(GTK_COMBO_BOX_TEXT(ui.hostname_combo_box));
- if (!typeentry || !strncmp(typeentry, "IPv4", 4))
- type = Fio_client_ipv4;
- else if (!strncmp(typeentry, "IPv6", 4))
- type = Fio_client_ipv6;
- else
- type = Fio_client_socket;
- g_free(typeentry);
-
- ui.client = fio_client_add_explicit(hostname, type, port);
- ui.client->client_data = &ui;
-#if 0
- if (error) {
+ ui.client = fio_client_add_explicit(host, type, port);
+ if (!ui.client) {
+ GError *error;
+
+ error = g_error_new(g_quark_from_string("fio"), 1,
+ "Failed to add client %s", host);
report_error(error);
g_error_free(error);
- error = NULL;
}
-#endif
+ ui.client->client_data = &ui;
g_free(filenames->data);
filenames = g_slist_next(filenames);
}
+ free(host);
+err:
g_slist_free(fn_glist);
- gtk_widget_destroy(dialog);
}
static void file_save(GtkWidget *w, gpointer data)
gtk_widget_destroy(dialog);
}
+static void preferences(GtkWidget *w, gpointer data)
+{
+ GtkWidget *dialog, *frame, *box, **buttons;
+ int i;
+
+ dialog = gtk_dialog_new_with_buttons("Preferences",
+ 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("Debug");
+ gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+ box = gtk_hbox_new(FALSE, 6);
+ gtk_container_add(GTK_CONTAINER(frame), box);
+
+ buttons = malloc(sizeof(GtkWidget *) * FD_DEBUG_MAX);
+
+ for (i = 0; i < FD_DEBUG_MAX; i++) {
+ buttons[i] = gtk_check_button_new_with_label(debug_levels[i].name);
+ gtk_box_pack_start(GTK_BOX(box), buttons[i], FALSE, FALSE, 6);
+ }
+
+ gtk_widget_show_all(dialog);
+
+ if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
+ gtk_widget_destroy(dialog);
+ return;
+ }
+
+ for (i = 0; i < FD_DEBUG_MAX; i++) {
+ int set;
+
+ set = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(buttons[i]));
+ if (set)
+ fio_debug |= (1UL << i);
+ }
+
+ gtk_widget_destroy(dialog);
+}
+
static void about_dialog(GtkWidget *w, gpointer data)
{
gtk_show_about_dialog(NULL,
}
static GtkActionEntry menu_items[] = {
- { "FileMenuAction", GTK_STOCK_FILE, "File", NULL, NULL, NULL},
- { "HelpMenuAction", GTK_STOCK_HELP, "Help", NULL, NULL, NULL},
- { "OpenFile", GTK_STOCK_OPEN, NULL, "<Control>O", NULL, G_CALLBACK(file_open) },
- { "SaveFile", GTK_STOCK_SAVE, NULL, "<Control>S", NULL, G_CALLBACK(file_save) },
- { "Quit", GTK_STOCK_QUIT, NULL, "<Control>Q", NULL, G_CALLBACK(quit_clicked) },
- { "About", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK(about_dialog) },
+ { "FileMenuAction", GTK_STOCK_FILE, "File", NULL, NULL, NULL},
+ { "HelpMenuAction", GTK_STOCK_HELP, "Help", NULL, NULL, NULL},
+ { "OpenFile", GTK_STOCK_OPEN, NULL, "<Control>O", NULL, G_CALLBACK(file_open) },
+ { "SaveFile", GTK_STOCK_SAVE, NULL, "<Control>S", NULL, G_CALLBACK(file_save) },
+ { "Preferences", GTK_STOCK_PREFERENCES, NULL, "<Control>p", NULL, G_CALLBACK(preferences) },
+ { "Quit", GTK_STOCK_QUIT, NULL, "<Control>Q", NULL, G_CALLBACK(quit_clicked) },
+ { "About", GTK_STOCK_ABOUT, NULL, NULL, NULL, G_CALLBACK(about_dialog) },
};
static gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
<menuitem name=\"Open\" action=\"OpenFile\" /> \
<menuitem name=\"Save\" action=\"SaveFile\" /> \
<separator name=\"Separator\"/> \
+ <menuitem name=\"Preferences\" action=\"Preferences\" /> \
+ <separator name=\"Separator2\"/> \
<menuitem name=\"Quit\" action=\"Quit\" /> \
</menu> \
<menu name=\"Help\" action=\"HelpMenuAction\"> \
gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
}
-static GtkWidget *new_info_label_in_frame(GtkWidget *box, const char *label)
-{
- GtkWidget *label_widget;
- GtkWidget *frame;
-
- frame = gtk_frame_new(label);
- label_widget = gtk_label_new(NULL);
- gtk_box_pack_start(GTK_BOX(box), frame, TRUE, TRUE, 3);
- gtk_container_add(GTK_CONTAINER(frame), label_widget);
-
- return label_widget;
-}
-
-static GtkWidget *create_text_entry(GtkWidget *hbox, GtkWidget *label, const char *defval)
-{
- GtkWidget *text, *box;
-
- gtk_container_add(GTK_CONTAINER(hbox), label);
-
- box = gtk_hbox_new(FALSE, 3);
- gtk_container_add(GTK_CONTAINER(hbox), box);
-
- text = gtk_entry_new();
- gtk_box_pack_start(GTK_BOX(box), text, TRUE, TRUE, 0);
- gtk_entry_set_text(GTK_ENTRY(text), "localhost");
-
- return text;
-}
-
-static GtkWidget *create_spinbutton(GtkWidget *hbox, GtkWidget *label, double min, double max, double defval)
-{
- GtkWidget *button, *box;
-
- gtk_container_add(GTK_CONTAINER(hbox), label);
-
- box = gtk_hbox_new(FALSE, 3);
- gtk_container_add(GTK_CONTAINER(hbox), box);
-
- button = gtk_spin_button_new_with_range(min, max, 1.0);
- gtk_box_pack_start(GTK_BOX(box), button, TRUE, TRUE, 0);
-
- gtk_spin_button_set_update_policy(GTK_SPIN_BUTTON(button), GTK_UPDATE_IF_VALID);
- gtk_spin_button_set_value(GTK_SPIN_BUTTON(button), defval);
-
- return button;
-}
-
static void init_ui(int *argc, char **argv[], struct gui *ui)
{
GtkSettings *settings;
gtk_container_add(GTK_CONTAINER(ui->topalign), ui->topvbox);
gtk_box_pack_start(GTK_BOX(ui->vbox), ui->topalign, FALSE, FALSE, 0);
- /*
- * Set up hostname label + entry, port label + entry,
- */
- ui->hostname_hbox = gtk_hbox_new(FALSE, 0);
-
- ui->hostname_label = gtk_label_new("Hostname:");
- ui->hostname_entry = create_text_entry(ui->hostname_hbox, ui->hostname_label, "localhost");
-
- ui->port_label = gtk_label_new("Port:");
- ui->port_button = create_spinbutton(ui->hostname_hbox, ui->port_label, 1, 65535, FIO_NET_PORT);
-
- /*
- * Set up combo box for address type
- */
- ui->hostname_combo_box = gtk_combo_box_text_new();
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ui->hostname_combo_box), "IPv4");
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ui->hostname_combo_box), "IPv6");
- gtk_combo_box_text_append_text(GTK_COMBO_BOX_TEXT(ui->hostname_combo_box), "local socket");
- gtk_combo_box_set_active(GTK_COMBO_BOX(ui->hostname_combo_box), 0);
-
- gtk_container_add(GTK_CONTAINER(ui->hostname_hbox), ui->hostname_combo_box);
- gtk_container_add(GTK_CONTAINER(ui->topvbox), ui->hostname_hbox);
-
probe = gtk_frame_new("Job");
gtk_box_pack_start(GTK_BOX(ui->topvbox), probe, TRUE, FALSE, 3);
probe_frame = gtk_vbox_new(FALSE, 3);
*/
ui->thread_status_pb = gtk_progress_bar_new();
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(ui->thread_status_pb), 0.0);
- gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ui->thread_status_pb), "No jobs running");
+ gtk_progress_bar_set_text(GTK_PROGRESS_BAR(ui->thread_status_pb), "No connections");
gtk_container_add(GTK_CONTAINER(ui->buttonbox), ui->thread_status_pb);
if (fio_init_options())
return 1;
- fio_debug = ~0UL;
init_ui(&argc, &argv, &ui);
gdk_threads_enter();