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, 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 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 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 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