+static void on_info_bar_response(GtkWidget *widget, gint response,
+ gpointer data)
+{
+ if (response == GTK_RESPONSE_OK) {
+ gtk_widget_destroy(widget);
+ ui.error_info_bar = NULL;
+ }
+}
+
+void report_error(GError *error)
+{
+ if (ui.error_info_bar == NULL) {
+ ui.error_info_bar = gtk_info_bar_new_with_buttons(GTK_STOCK_OK,
+ GTK_RESPONSE_OK,
+ NULL);
+ g_signal_connect(ui.error_info_bar, "response", G_CALLBACK(on_info_bar_response), NULL);
+ gtk_info_bar_set_message_type(GTK_INFO_BAR(ui.error_info_bar),
+ GTK_MESSAGE_ERROR);
+
+ ui.error_label = gtk_label_new(error->message);
+ GtkWidget *container = gtk_info_bar_get_content_area(GTK_INFO_BAR(ui.error_info_bar));
+ gtk_container_add(GTK_CONTAINER(container), ui.error_label);
+
+ gtk_box_pack_start(GTK_BOX(ui.vbox), ui.error_info_bar, FALSE, FALSE, 0);
+ gtk_widget_show_all(ui.vbox);
+ } else {
+ char buffer[256];
+ snprintf(buffer, sizeof(buffer), "Failed to open file.");
+ gtk_label_set(GTK_LABEL(ui.error_label), buffer);
+ }
+}
+
+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),
+ 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), TRUE);
+
+ filter = gtk_file_filter_new();
+ gtk_file_filter_add_pattern(filter, "*.fio");
+ gtk_file_filter_add_pattern(filter, "*.job");
+ gtk_file_filter_add_mime_type(filter, "text/fio");
+ 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;
+ }
+
+ 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) {
+ 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++;
+
+ 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);
+ }
+ ui.client->client_data = &ui;
+
+ g_free(filenames->data);
+ filenames = g_slist_next(filenames);
+ }
+ free(host);
+err:
+ g_slist_free(fn_glist);
+}
+
+static void file_save(GtkWidget *w, gpointer 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);
+
+ 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;
+
+ filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
+ // save_job_file(filename);
+ g_free(filename);
+ }
+ gtk_widget_destroy(dialog);
+}
+
+static void about_dialog(GtkWidget *w, gpointer data)
+{
+ gtk_show_about_dialog(NULL,
+ "program-name", "gfio",
+ "comments", "Gtk2 UI for fio",
+ "license", "GPLv2",
+ "version", fio_version_string,
+ "copyright", "Jens Axboe <axboe@kernel.dk> 2012",
+ "logo-icon-name", "fio",
+ /* Must be last: */
+ NULL, NULL,
+ 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) },
+};
+static gint nmenu_items = sizeof(menu_items) / sizeof(menu_items[0]);
+
+static const gchar *ui_string = " \
+ <ui> \
+ <menubar name=\"MainMenu\"> \
+ <menu name=\"FileMenu\" action=\"FileMenuAction\"> \
+ <menuitem name=\"Open\" action=\"OpenFile\" /> \
+ <menuitem name=\"Save\" action=\"SaveFile\" /> \
+ <separator name=\"Separator\"/> \
+ <menuitem name=\"Quit\" action=\"Quit\" /> \
+ </menu> \
+ <menu name=\"Help\" action=\"HelpMenuAction\"> \
+ <menuitem name=\"About\" action=\"About\" /> \
+ </menu> \
+ </menubar> \
+ </ui> \
+";
+
+static GtkWidget *get_menubar_menu(GtkWidget *window, GtkUIManager *ui_manager)
+{
+ GtkActionGroup *action_group = gtk_action_group_new("Menu");
+ GError *error = 0;
+
+ action_group = gtk_action_group_new("Menu");
+ gtk_action_group_add_actions(action_group, menu_items, nmenu_items, 0);
+
+ gtk_ui_manager_insert_action_group(ui_manager, action_group, 0);
+ gtk_ui_manager_add_ui_from_string(GTK_UI_MANAGER(ui_manager), ui_string, -1, &error);
+
+ gtk_window_add_accel_group(GTK_WINDOW(window), gtk_ui_manager_get_accel_group(ui_manager));
+ return gtk_ui_manager_get_widget(ui_manager, "/MainMenu");
+}
+
+void gfio_ui_setup(GtkSettings *settings, GtkWidget *menubar,
+ GtkWidget *vbox, GtkUIManager *ui_manager)
+{
+ gtk_box_pack_start(GTK_BOX(vbox), menubar, FALSE, FALSE, 0);
+}
+