gfio: make empty graph show grid lines, not "No good data"
[fio.git] / gfio.c
diff --git a/gfio.c b/gfio.c
index a52d84d33e3a8221bec40767760f3cab73a667b3..b1caa6780d51c21d17ddc1cecb0e33ed83a6d42c 100644 (file)
--- a/gfio.c
+++ b/gfio.c
@@ -32,6 +32,7 @@
 #include "graph.h"
 
 static int gfio_server_running;
+static const char *gfio_graph_font;
 
 static void gfio_update_thread_status(char *status_message, double perc);
 
@@ -120,12 +121,24 @@ struct gfio_client {
        GtkWidget *disk_util_frame;
 };
 
+static void add_invisible_data(struct graph *g)
+{
+       /*
+        * This puts some invisible data into a graph so that it will
+        * initially have some grid lines instead of "No good data"
+        */
+       graph_add_label(g, "invisible");
+       graph_set_color(g, "invisible", INVISIBLE_COLOR, 0.0, 0.7);
+       graph_add_xy_data(g, "invisible", 0.0, 0.0);
+       graph_add_xy_data(g, "invisible", 1.0, 100.0);
+}
+
 static void setup_iops_graph(struct gui *ui)
 {
        if (ui->iops_graph)
                graph_free(ui->iops_graph);
-       ui->iops_graph = graph_new((int) DRAWING_AREA_XDIM / 2.0,
-                                       (int) DRAWING_AREA_YDIM);
+       ui->iops_graph = graph_new(DRAWING_AREA_XDIM / 2.0,
+                                       DRAWING_AREA_YDIM, gfio_graph_font);
        graph_title(ui->iops_graph, "IOPS");
        graph_x_title(ui->iops_graph, "Time");
        graph_y_title(ui->iops_graph, "IOPS");
@@ -133,14 +146,15 @@ static void setup_iops_graph(struct gui *ui)
        graph_add_label(ui->iops_graph, "Write IOPS");
        graph_set_color(ui->iops_graph, "Read IOPS", 0.7, 0.0, 0.0);
        graph_set_color(ui->iops_graph, "Write IOPS", 0.0, 0.0, 0.7);
+       add_invisible_data(ui->iops_graph);
 }
 
 static void setup_bandwidth_graph(struct gui *ui)
 {
        if (ui->bandwidth_graph)
                graph_free(ui->bandwidth_graph);
-       ui->bandwidth_graph = graph_new((int) DRAWING_AREA_XDIM / 2.0,
-                                       (int) DRAWING_AREA_YDIM);
+       ui->bandwidth_graph = graph_new(DRAWING_AREA_XDIM / 2.0,
+                                       DRAWING_AREA_YDIM, gfio_graph_font);
        graph_title(ui->bandwidth_graph, "Bandwidth");
        graph_x_title(ui->bandwidth_graph, "Time");
        graph_y_title(ui->bandwidth_graph, "Bandwidth");
@@ -148,6 +162,7 @@ static void setup_bandwidth_graph(struct gui *ui)
        graph_add_label(ui->bandwidth_graph, "Write Bandwidth");
        graph_set_color(ui->bandwidth_graph, "Read Bandwidth", 0.7, 0.0, 0.0);
        graph_set_color(ui->bandwidth_graph, "Write Bandwidth", 0.0, 0.0, 0.7);
+       add_invisible_data(ui->bandwidth_graph);
 }
 
 static void clear_ui_info(struct gui *ui)
@@ -1381,11 +1396,52 @@ void report_error(GError *error)
        }
 }
 
+struct connection_widgets
+{
+       GtkWidget *hentry;
+       GtkWidget *combo;
+       GtkWidget *button;
+};
+
+static void hostname_cb(GtkEntry *entry, gpointer data)
+{
+       struct connection_widgets *cw = data;
+       int uses_net = 0, is_localhost = 0;
+       const gchar *text;
+       gchar *ctext;
+
+       /*
+        * Check whether to display the 'auto start backend' box
+        * 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));
+       if (!ctext || !strncmp(ctext, "IPv4", 4) || !strncmp(ctext, "IPv6", 4))
+               uses_net = 1;
+       g_free(ctext);
+
+       if (uses_net) {
+               text = gtk_entry_get_text(GTK_ENTRY(cw->hentry));
+               if (!strcmp(text, "127.0.0.1") || !strcmp(text, "localhost") ||
+                   !strcmp(text, "::1") || !strcmp(text, "ip6-localhost") ||
+                   !strcmp(text, "ip6-loopback"))
+                       is_localhost = 1;
+       }
+
+       if (!uses_net || is_localhost) {
+               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw->button), 1);
+               gtk_widget_set_sensitive(cw->button, 1);
+       } else {
+               gtk_toggle_button_set_active(GTK_TOGGLE_BUTTON(cw->button), 0);
+               gtk_widget_set_sensitive(cw->button, 0);
+       }
+}
+
 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;
+       GtkWidget *dialog, *box, *vbox, *hbox, *frame, *pentry;
+       struct connection_widgets cw;
        char *typeentry;
 
        dialog = gtk_dialog_new_with_buttons("Connection details",
@@ -1403,9 +1459,9 @@ static int get_connection_details(char **host, int *port, int *type,
 
        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);
+       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);
@@ -1424,13 +1480,13 @@ static int get_connection_details(char **host, int *port, int *type,
        hbox = gtk_hbox_new(TRUE, 4);
        gtk_box_pack_start(GTK_BOX(box), hbox, FALSE, FALSE, 0);
 
-       combo = gtk_combo_box_new_text();
-       gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "IPv4");
-       gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "IPv6");
-       gtk_combo_box_append_text(GTK_COMBO_BOX(combo), "local socket");
-       gtk_combo_box_set_active(GTK_COMBO_BOX(combo), 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), combo);
+       gtk_container_add(GTK_CONTAINER(hbox), cw.combo);
 
        frame = gtk_frame_new("Options");
        gtk_box_pack_start(GTK_BOX(vbox), frame, FALSE, FALSE, 5);
@@ -1440,10 +1496,16 @@ static int get_connection_details(char **host, int *port, int *type,
        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);
+       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(GTK_OBJECT(cw.hentry), "changed", G_CALLBACK(hostname_cb), &cw);
+       g_signal_connect(GTK_OBJECT(cw.combo), "changed", G_CALLBACK(hostname_cb), &cw);
 
        gtk_widget_show_all(dialog);
 
@@ -1452,10 +1514,10 @@ static int get_connection_details(char **host, int *port, int *type,
                return 1;
        }
 
-       *host = strdup(gtk_entry_get_text(GTK_ENTRY(hentry)));
+       *host = strdup(gtk_entry_get_text(GTK_ENTRY(cw.hentry)));
        *port = gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(pentry));
 
-       typeentry = gtk_combo_box_get_active_text(GTK_COMBO_BOX(combo));
+       typeentry = gtk_combo_box_get_active_text(GTK_COMBO_BOX(cw.combo));
        if (!typeentry || !strncmp(typeentry, "IPv4", 4))
                *type = Fio_client_ipv4;
        else if (!strncmp(typeentry, "IPv6", 4))
@@ -1464,7 +1526,7 @@ static int get_connection_details(char **host, int *port, int *type,
                *type = Fio_client_socket;
        g_free(typeentry);
 
-       *server_start = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(button));
+       *server_start = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(cw.button));
 
        gtk_widget_destroy(dialog);
        return 0;
@@ -1615,7 +1677,7 @@ static void view_log(GtkWidget *w, gpointer data)
 
 static void preferences(GtkWidget *w, gpointer data)
 {
-       GtkWidget *dialog, *frame, *box, **buttons;
+       GtkWidget *dialog, *frame, *box, **buttons, *vbox, *font;
        int i;
 
        dialog = gtk_dialog_new_with_buttons("Preferences",
@@ -1627,17 +1689,35 @@ static void preferences(GtkWidget *w, gpointer data)
 
        frame = gtk_frame_new("Debug logging");
        gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+
+       vbox = gtk_vbox_new(FALSE, 6);
+       gtk_container_add(GTK_CONTAINER(frame), vbox);
+
        box = gtk_hbox_new(FALSE, 6);
-       gtk_container_add(GTK_CONTAINER(frame), box);
+       gtk_container_add(GTK_CONTAINER(vbox), box);
 
        buttons = malloc(sizeof(GtkWidget *) * FD_DEBUG_MAX);
 
        for (i = 0; i < FD_DEBUG_MAX; i++) {
+               if (i == 7) {
+                       box = gtk_hbox_new(FALSE, 6);
+                       gtk_container_add(GTK_CONTAINER(vbox), box);
+               }
+
+
                buttons[i] = gtk_check_button_new_with_label(debug_levels[i].name);
                gtk_widget_set_tooltip_text(buttons[i], debug_levels[i].help);
                gtk_box_pack_start(GTK_BOX(box), buttons[i], FALSE, FALSE, 6);
        }
 
+       frame = gtk_frame_new("Graph font");
+       gtk_box_pack_start(GTK_BOX(GTK_DIALOG(dialog)->vbox), frame, FALSE, FALSE, 5);
+       vbox = gtk_vbox_new(FALSE, 6);
+       gtk_container_add(GTK_CONTAINER(frame), vbox);
+
+       font = gtk_font_button_new();
+       gtk_box_pack_start(GTK_BOX(vbox), font, FALSE, FALSE, 5);
+
        gtk_widget_show_all(dialog);
 
        if (gtk_dialog_run(GTK_DIALOG(dialog)) != GTK_RESPONSE_ACCEPT) {
@@ -1653,21 +1733,51 @@ static void preferences(GtkWidget *w, gpointer data)
                        fio_debug |= (1UL << i);
        }
 
+       gfio_graph_font = strdup(gtk_font_button_get_font_name(GTK_FONT_BUTTON(font)));
+       printf("got font %s\n", gfio_graph_font);
+
        gtk_widget_destroy(dialog);
 }
 
 static void about_dialog(GtkWidget *w, gpointer data)
 {
+       const char *authors[] = {
+               "Jens Axboe <axboe@kernel.dk>",
+               "Stephen Carmeron <stephenmcameron@gmail.com>",
+               NULL
+       };
+       const char *license[] = {
+               "Fio is free software; you can redistribute it and/or modify "
+               "it under the terms of the GNU General Public License as published by "
+               "the Free Software Foundation; either version 2 of the License, or "
+               "(at your option) any later version.\n",
+               "Fio is distributed in the hope that it will be useful, "
+               "but WITHOUT ANY WARRANTY; without even the implied warranty of "
+               "MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the "
+               "GNU General Public License for more details.\n",
+               "You should have received a copy of the GNU General Public License "
+               "along with Fio; if not, write to the Free Software Foundation, Inc., "
+               "51 Franklin Street, Fifth Floor, Boston, MA 02110-1301  USA\n"
+       };
+       char *license_trans;
+
+       license_trans = g_strconcat(license[0], "\n", license[1], "\n",
+                                    license[2], "\n", NULL);
+
        gtk_show_about_dialog(NULL,
                "program-name", "gfio",
                "comments", "Gtk2 UI for fio",
-               "license", "GPLv2",
+               "license", license_trans,
+               "website", "http://git.kernel.dk/?p=fio.git;a=summary",
+               "authors", authors,
                "version", fio_version_string,
-               "copyright", "Jens Axboe <axboe@kernel.dk> 2012",
+               "copyright", "© 2012 Jens Axboe <axboe@kernel.dk>",
                "logo-icon-name", "fio",
                /* Must be last: */
-               NULL, NULL,
+               "wrap-license", TRUE,
                NULL);
+
+       g_free (license_trans);
 }
 
 static GtkActionEntry menu_items[] = {
@@ -1731,6 +1841,7 @@ static void init_ui(int *argc, char **argv[], struct gui *ui)
        GtkSettings *settings;
        GtkUIManager *uimanager;
        GtkWidget *menu, *probe, *probe_frame, *probe_box;
+       GdkColor white;
 
        memset(ui, 0, sizeof(*ui));
 
@@ -1749,7 +1860,7 @@ static void init_ui(int *argc, char **argv[], struct gui *ui)
        
        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), 700, 500);
+       gtk_window_set_default_size(GTK_WINDOW(ui->window), 700, 700);
 
        g_signal_connect(ui->window, "delete-event", G_CALLBACK(quit_clicked), NULL);
        g_signal_connect(ui->window, "destroy", G_CALLBACK(quit_clicked), NULL);
@@ -1816,9 +1927,11 @@ static void init_ui(int *argc, char **argv[], struct gui *ui)
        /*
         * Set up a drawing area and IOPS and bandwidth graphs
         */
+       gdk_color_parse("white", &white);
        ui->drawing_area = gtk_drawing_area_new();
        gtk_widget_set_size_request(GTK_WIDGET(ui->drawing_area), 
                        DRAWING_AREA_XDIM, DRAWING_AREA_YDIM);
+       gtk_widget_modify_bg(ui->drawing_area, GTK_STATE_NORMAL, &white);
        g_signal_connect(G_OBJECT(ui->drawing_area), "expose_event",
                                G_CALLBACK (on_expose_drawing_area), ui);
        ui->scrolled_window = gtk_scrolled_window_new(NULL, NULL);