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