gfio: Add "print" option for results page.
authorStephen M. Cameron <stephenmcameron@gmail.com>
Tue, 27 Mar 2012 06:14:48 +0000 (08:14 +0200)
committerJens Axboe <axboe@kernel.dk>
Tue, 27 Mar 2012 06:14:48 +0000 (08:14 +0200)
It doesn't really print the results page yet, just a kind of test page.

Signed-off-by: Stephen M. Cameron <stephenmcameron@gmail.com>
Signed-off-by: Jens Axboe <axboe@kernel.dk>
Makefile
gclient.c
printing.c [new file with mode: 0644]
printing.h [new file with mode: 0644]

index ca025c8..b7091bf 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -70,7 +70,7 @@ endif
 OBJS = $(SOURCE:.c=.o)
 FIO_OBJS = $(OBJS) fio.o
 GFIO_OBJS = $(OBJS) gfio.o graph.o tickmarks.o ghelpers.o goptions.o gerror.o \
-                       gclient.o gcompat.o cairo_text_helpers.o
+                       gclient.o gcompat.o cairo_text_helpers.o printing.o
 
 T_SMALLOC_OBJS = t/stest.o
 T_SMALLOC_OBJS += mutex.o smalloc.o t/log.o
@@ -138,6 +138,9 @@ graph.o: graph.c graph.h
 cairo_text_helpers.o: cairo_text_helpers.c cairo_text_helpers.h
        $(QUIET_CC)$(CC) $(CFLAGS) $(GTK_CFLAGS) $(CPPFLAGS) -c cairo_text_helpers.c
 
+printing.o: printing.c printing.h
+       $(QUIET_CC)$(CC) $(CFLAGS) $(GTK_CFLAGS) $(CPPFLAGS) -c printing.c
+
 t/stest: $(T_SMALLOC_OBJS)
        $(QUIET_CC)$(CC) $(LDFLAGS) $(CFLAGS) -o $@ $(T_SMALLOC_OBJS) $(LIBS) $(LDFLAGS)
 
index 8d63586..1042eaf 100644 (file)
--- a/gclient.c
+++ b/gclient.c
@@ -12,6 +12,7 @@
 #include "gerror.h"
 #include "graph.h"
 #include "gclient.h"
+#include "printing.h"
 
 static void gfio_display_ts(struct fio_client *client, struct thread_stat *ts,
                            struct group_run_stats *rs);
@@ -33,9 +34,17 @@ static void results_close(GtkWidget *w, gpointer *data)
        gtk_widget_destroy(ge->results_window);
 }
 
+static void results_print(GtkWidget *w, gpointer *data)
+{
+       struct gui_entry *ge = (struct gui_entry *) data;
+
+       gfio_print_results(ge);
+}
+
 static GtkActionEntry results_menu_items[] = {
        { "FileMenuAction", GTK_STOCK_FILE, "File", NULL, NULL, NULL},
        { "GraphMenuAction", GTK_STOCK_FILE, "Graph", NULL, NULL, NULL},
+       { "PrintFile", GTK_STOCK_PRINT, "Print", "<Control>P", NULL, G_CALLBACK(results_print) },
        { "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]);
@@ -44,6 +53,7 @@ static const gchar *results_ui_string = " \
        <ui> \
                <menubar name=\"MainMenu\"> \
                        <menu name=\"FileMenu\" action=\"FileMenuAction\"> \
+                               <menuitem name=\"Print\" action=\"PrintFile\" /> \
                                <menuitem name=\"Close\" action=\"CloseFile\" /> \
                        </menu> \
                        <menu name=\"GraphMenu\" action=\"GraphMenuAction\"> \
diff --git a/printing.c b/printing.c
new file mode 100644 (file)
index 0000000..570e659
--- /dev/null
@@ -0,0 +1,138 @@
+#include <gtk/gtk.h>
+#include <cairo.h>
+
+#include "gfio.h"
+#include "cairo_text_helpers.h"
+#include "printing.h"
+
+
+static struct printing_parameters {
+       gdouble width, height, xdpi, ydpi;
+       GtkPrintSettings *settings;
+       GtkPageSetup *page_setup;
+} print_params = { 0 };
+
+static void begin_print(GtkPrintOperation *operation,
+                       GtkPrintContext *context, gpointer data)
+{
+       print_params.page_setup = gtk_print_context_get_page_setup(context);
+
+       print_params.width = gtk_print_context_get_width(context);
+       print_params.height = gtk_print_context_get_height(context);
+       print_params.xdpi = gtk_print_context_get_dpi_x(context);
+       print_params.ydpi = gtk_print_context_get_dpi_y(context);
+
+       /* assume 1 page for now. */
+       gtk_print_operation_set_n_pages(operation, 1);
+}
+
+static void results_draw_page(GtkPrintOperation *operation, GtkPrintContext *context,
+                       gint page_nr, gpointer data) 
+{
+       cairo_t *cr;
+       char str[20];
+       double x, y;
+
+       cr = gtk_print_context_get_cairo_context(context);
+
+        cairo_set_source_rgb(cr, 0, 0, 0);
+        cairo_set_line_width (cr, 5.0);
+       cairo_move_to(cr, 0.0, 0.0);
+       cairo_line_to(cr, print_params.width, print_params.height);
+       cairo_move_to(cr, 0.0, print_params.height);
+       cairo_line_to(cr, print_params.width, 0.0);
+       cairo_stroke(cr);
+
+       x = print_params.width / 4.0;
+       y = print_params.height / 5.0;
+       sprintf(str, "(%g,%g)", x, y);
+       draw_right_justified_text(cr, "Sans", x, y, 12.0, str);
+        cairo_set_source_rgb(cr, 0, 0, 0);
+        cairo_set_line_width (cr, 2.0);
+       cairo_move_to(cr, x, y - 30.0);
+       cairo_line_to(cr, x, y + 30.0);
+       cairo_move_to(cr, x - 30, y);
+       cairo_line_to(cr, x + 30, y);
+
+       y *= 4.0;
+       x *= 2.0;
+       sprintf(str, "(%g,%g)", x, y);
+       draw_right_justified_text(cr, "Sans", x, y, 12.0, str);
+        cairo_set_source_rgb(cr, 0, 0, 0);
+        cairo_set_line_width (cr, 2.0);
+       cairo_move_to(cr, x, y - 30.0);
+       cairo_line_to(cr, x, y + 30.0);
+       cairo_move_to(cr, x - 30, y);
+       cairo_line_to(cr, x + 30, y);
+       cairo_stroke(cr);
+}
+
+static void printing_error_dialog(GtkWidget *window, GError *print_error)
+{
+       GtkWidget *error_dialog;
+
+       printf("printing_error_dialog called\n");
+       printf("error message = %s\n", print_error->message);
+       error_dialog = gtk_message_dialog_new(GTK_WINDOW(window),
+                       GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
+                       GTK_BUTTONS_CLOSE, "Print error:\n%s",
+                       print_error->message);
+       g_signal_connect(error_dialog, "response", 
+                       G_CALLBACK(gtk_widget_destroy), NULL);
+       gtk_widget_show(error_dialog);
+}
+
+static void results_print_done(GtkPrintOperation *operation,
+                       GtkPrintOperationResult result, gpointer data)
+{
+       GError *print_error;
+       struct gui_entry *ge = data;
+
+       if (result != GTK_PRINT_OPERATION_RESULT_ERROR)
+               return;
+
+       gtk_print_operation_get_error(operation, &print_error);
+       printing_error_dialog(ge->results_window, print_error);
+       g_error_free(print_error);
+}
+
+void gfio_print_results(struct gui_entry *ge)
+{
+       GtkPrintOperation *print;
+       GtkPrintOperationResult res;
+       GError *print_error;
+
+       print = gtk_print_operation_new();
+       if (print_params.settings != NULL)
+               gtk_print_operation_set_print_settings(print, print_params.settings);
+
+       if (print_params.page_setup != NULL)
+               gtk_print_operation_set_default_page_setup(print, print_params.page_setup);
+
+       g_signal_connect(print, "begin_print", G_CALLBACK(begin_print), NULL);
+       g_signal_connect(print, "draw_page", G_CALLBACK(results_draw_page), NULL);
+       g_signal_connect(print, "done", G_CALLBACK(results_print_done), NULL);
+       gtk_print_operation_set_allow_async(print, TRUE);
+       res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
+               GTK_WINDOW(ge->results_window), &print_error);
+
+       /*
+        * Something's not quite right about the error handling.  If I print
+        * to a file, and the file exists, and I don't have write permission
+        * on that file but attempt to replace it anyway, then it just kind of
+        * hangs and I don't get into any of this error handling stuff at all,
+        * neither here, nor in results_print_done().
+        */
+
+       if (res == GTK_PRINT_OPERATION_RESULT_ERROR) {
+               printing_error_dialog(ge->results_window, print_error);
+               g_error_free(print_error);
+       } else {
+               if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
+                       if (print_params.settings != NULL)
+                               g_object_unref(print_params.settings);
+                       print_params.settings = g_object_ref(gtk_print_operation_get_print_settings(print));
+               }
+       }
+       g_object_unref(print);
+}
diff --git a/printing.h b/printing.h
new file mode 100644 (file)
index 0000000..0079919
--- /dev/null
@@ -0,0 +1,6 @@
+#ifndef PRINTING_H
+#define PRINTING_H
+
+void gfio_print_results(struct gui_entry *ge);
+
+#endif