gfio: Add "print" option for results page.
[fio.git] / printing.c
1 #include <gtk/gtk.h>
2 #include <cairo.h>
3
4 #include "gfio.h"
5 #include "cairo_text_helpers.h"
6 #include "printing.h"
7
8
9 static struct printing_parameters {
10         gdouble width, height, xdpi, ydpi;
11         GtkPrintSettings *settings;
12         GtkPageSetup *page_setup;
13 } print_params = { 0 };
14
15 static void begin_print(GtkPrintOperation *operation,
16                         GtkPrintContext *context, gpointer data)
17 {
18         print_params.page_setup = gtk_print_context_get_page_setup(context);
19
20         print_params.width = gtk_print_context_get_width(context);
21         print_params.height = gtk_print_context_get_height(context);
22         print_params.xdpi = gtk_print_context_get_dpi_x(context);
23         print_params.ydpi = gtk_print_context_get_dpi_y(context);
24
25         /* assume 1 page for now. */
26         gtk_print_operation_set_n_pages(operation, 1);
27 }
28
29 static void results_draw_page(GtkPrintOperation *operation, GtkPrintContext *context,
30                         gint page_nr, gpointer data) 
31 {
32         cairo_t *cr;
33         char str[20];
34         double x, y;
35
36         cr = gtk_print_context_get_cairo_context(context);
37
38         cairo_set_source_rgb(cr, 0, 0, 0);
39         cairo_set_line_width (cr, 5.0);
40         cairo_move_to(cr, 0.0, 0.0);
41         cairo_line_to(cr, print_params.width, print_params.height);
42         cairo_move_to(cr, 0.0, print_params.height);
43         cairo_line_to(cr, print_params.width, 0.0);
44         cairo_stroke(cr);
45
46         x = print_params.width / 4.0;
47         y = print_params.height / 5.0;
48         sprintf(str, "(%g,%g)", x, y);
49         draw_right_justified_text(cr, "Sans", x, y, 12.0, str);
50         cairo_set_source_rgb(cr, 0, 0, 0);
51         cairo_set_line_width (cr, 2.0);
52         cairo_move_to(cr, x, y - 30.0);
53         cairo_line_to(cr, x, y + 30.0);
54         cairo_move_to(cr, x - 30, y);
55         cairo_line_to(cr, x + 30, y);
56
57         y *= 4.0;
58         x *= 2.0;
59         sprintf(str, "(%g,%g)", x, y);
60         draw_right_justified_text(cr, "Sans", x, y, 12.0, str);
61         cairo_set_source_rgb(cr, 0, 0, 0);
62         cairo_set_line_width (cr, 2.0);
63         cairo_move_to(cr, x, y - 30.0);
64         cairo_line_to(cr, x, y + 30.0);
65         cairo_move_to(cr, x - 30, y);
66         cairo_line_to(cr, x + 30, y);
67         cairo_stroke(cr);
68 }
69
70 static void printing_error_dialog(GtkWidget *window, GError *print_error)
71 {
72         GtkWidget *error_dialog;
73
74         printf("printing_error_dialog called\n");
75         printf("error message = %s\n", print_error->message);
76         error_dialog = gtk_message_dialog_new(GTK_WINDOW(window),
77                         GTK_DIALOG_DESTROY_WITH_PARENT, GTK_MESSAGE_ERROR,
78                         GTK_BUTTONS_CLOSE, "Print error:\n%s",
79                         print_error->message);
80         g_signal_connect(error_dialog, "response", 
81                         G_CALLBACK(gtk_widget_destroy), NULL);
82         gtk_widget_show(error_dialog);
83 }
84
85 static void results_print_done(GtkPrintOperation *operation,
86                         GtkPrintOperationResult result, gpointer data)
87 {
88         GError *print_error;
89         struct gui_entry *ge = data;
90
91         if (result != GTK_PRINT_OPERATION_RESULT_ERROR)
92                 return;
93
94         gtk_print_operation_get_error(operation, &print_error);
95         printing_error_dialog(ge->results_window, print_error);
96         g_error_free(print_error);
97 }
98
99 void gfio_print_results(struct gui_entry *ge)
100 {
101         GtkPrintOperation *print;
102         GtkPrintOperationResult res;
103         GError *print_error;
104
105         print = gtk_print_operation_new();
106         if (print_params.settings != NULL)
107                 gtk_print_operation_set_print_settings(print, print_params.settings);
108
109         if (print_params.page_setup != NULL)
110                 gtk_print_operation_set_default_page_setup(print, print_params.page_setup);
111
112         g_signal_connect(print, "begin_print", G_CALLBACK(begin_print), NULL);
113         g_signal_connect(print, "draw_page", G_CALLBACK(results_draw_page), NULL);
114         g_signal_connect(print, "done", G_CALLBACK(results_print_done), NULL);
115         gtk_print_operation_set_allow_async(print, TRUE);
116         res = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG,
117                 GTK_WINDOW(ge->results_window), &print_error);
118
119         /*
120          * Something's not quite right about the error handling.  If I print
121          * to a file, and the file exists, and I don't have write permission
122          * on that file but attempt to replace it anyway, then it just kind of
123          * hangs and I don't get into any of this error handling stuff at all,
124          * neither here, nor in results_print_done().
125          */
126
127         if (res == GTK_PRINT_OPERATION_RESULT_ERROR) {
128                 printing_error_dialog(ge->results_window, print_error);
129                 g_error_free(print_error);
130         } else {
131                 if (res == GTK_PRINT_OPERATION_RESULT_APPLY) {
132                         if (print_params.settings != NULL)
133                                 g_object_unref(print_params.settings);
134                         print_params.settings = g_object_ref(gtk_print_operation_get_print_settings(print));
135                 }
136         }
137         g_object_unref(print);
138 }