diff options
Diffstat (limited to 'src/cairo/cdcairoprn_unix.c')
-rw-r--r-- | src/cairo/cdcairoprn_unix.c | 190 |
1 files changed, 190 insertions, 0 deletions
diff --git a/src/cairo/cdcairoprn_unix.c b/src/cairo/cdcairoprn_unix.c new file mode 100644 index 0000000..b201230 --- /dev/null +++ b/src/cairo/cdcairoprn_unix.c @@ -0,0 +1,190 @@ +/** \file + * \brief Cairo/GTK Printer Driver (UNIX Only) + * + * See Copyright Notice in cd.h + */ + +#include <stdio.h> +#include <stdlib.h> +#include <string.h> + +#include <gtk/gtkprintunixdialog.h> + +#include "cdcairoctx.h" +#include "cdprint.h" + +static gboolean print_enum(GtkPrinter *printer, GtkPrinter **ret_printer) +{ + if (gtk_printer_is_default(printer)) + { + *ret_printer = printer; + g_object_ref(printer); + return TRUE; + } + return FALSE; +} + +static void finish_send(GtkPrintJob *job, GMainLoop* loop, GError *error) +{ + if (error != NULL) + { + GtkWidget *edialog; + edialog = gtk_message_dialog_new (NULL, + GTK_DIALOG_DESTROY_WITH_PARENT, + GTK_MESSAGE_ERROR, + GTK_BUTTONS_CLOSE, + "Error printing"); + gtk_message_dialog_format_secondary_text (GTK_MESSAGE_DIALOG (edialog), "%s", error->message); + gtk_window_set_modal (GTK_WINDOW (edialog), TRUE); + g_signal_connect(edialog, "response", G_CALLBACK (gtk_widget_destroy), NULL); + + gtk_window_present(GTK_WINDOW(edialog)); + } + + g_main_loop_quit(loop); +} + +static void cdkillcanvas(cdCtxCanvas *ctxcanvas) +{ + GMainLoop* loop = g_main_loop_new (NULL, FALSE); + + cairo_surface_finish(cairo_get_target(ctxcanvas->cr)); + + gtk_print_job_send(ctxcanvas->job, (GtkPrintJobCompleteFunc)finish_send, loop, NULL); + + g_main_loop_run(loop); + g_main_loop_unref(loop); + + cdcairoKillCanvas(ctxcanvas); +} + +static char* get_printername_attrib(cdCtxCanvas* ctxcanvas) +{ + return (char*)gtk_printer_get_name(gtk_print_job_get_printer(ctxcanvas->job)); +} + +static cdAttribute printername_attrib = +{ + "PRINTERNAME", + NULL, + get_printername_attrib +}; + +static void cdcreatecanvas(cdCanvas* canvas, void *data) +{ + cdCtxCanvas* ctxcanvas; + char *data_str = (char*) data; + char docname[256] = "CD - Canvas Draw Document"; + GtkPrintUnixDialog* dialog = NULL; + GtkPrinter* printer; + GtkPrintSettings* settings; + GtkPageSetup* page_setup; + GtkPrintJob* job; + int show_dialog = 0; + + /* Starting parameters */ + if (data_str == NULL) + return; + + if (data_str[0] != 0) + { + char *ptr = strstr(data_str, "-d"); + + if (ptr != NULL) + show_dialog = 1; + + if (data_str[0] != '-') + { + strcpy(docname, data_str); + + if (show_dialog) + docname[ptr - data_str - 1] = 0; + } + } + + if (show_dialog) + { + int response; + + dialog = (GtkPrintUnixDialog*)gtk_print_unix_dialog_new(NULL, NULL); + + gtk_print_unix_dialog_set_manual_capabilities(dialog, + GTK_PRINT_CAPABILITY_PAGE_SET | + GTK_PRINT_CAPABILITY_COPIES | + GTK_PRINT_CAPABILITY_COLLATE | + GTK_PRINT_CAPABILITY_REVERSE | + GTK_PRINT_CAPABILITY_SCALE); + + gtk_widget_realize(GTK_WIDGET(dialog)); + + response = gtk_dialog_run(GTK_DIALOG(dialog)); + + if (response == GTK_RESPONSE_CANCEL) + { + gtk_widget_destroy(GTK_WIDGET(dialog)); + return; + } + + printer = gtk_print_unix_dialog_get_selected_printer(dialog); + settings = gtk_print_unix_dialog_get_settings(dialog); + page_setup = gtk_print_unix_dialog_get_page_setup(dialog); + } + else + { + printer = NULL; + gtk_enumerate_printers((GtkPrinterFunc)print_enum, &printer, NULL, TRUE); + if (!printer) + return; + page_setup = gtk_printer_get_default_page_size(printer); + if (!page_setup) + page_setup = gtk_page_setup_new(); /* ?????? */ + + settings = gtk_print_settings_new(); /* ?????? */ + } + + job = gtk_print_job_new(docname, printer, settings, page_setup); + + canvas->w_mm = (int)gtk_page_setup_get_page_width(page_setup, GTK_UNIT_MM); + canvas->h_mm = (int)gtk_page_setup_get_page_height(page_setup, GTK_UNIT_MM); + canvas->bpp = 24; + canvas->xres = (double)gtk_print_settings_get_resolution_x(settings) / 25.4; + canvas->yres = (double)gtk_print_settings_get_resolution_y(settings) / 25.4; + canvas->w = cdRound(canvas->w_mm*canvas->xres); + canvas->h = cdRound(canvas->h_mm*canvas->yres); + + ctxcanvas = cdcairoCreateCanvas(canvas, cairo_create(gtk_print_job_get_surface(job, NULL))); + ctxcanvas->job = job; + + cairo_identity_matrix(ctxcanvas->cr); + cairo_scale(ctxcanvas->cr, 0.25, 0.25); /* TODO: why this is needed? */ + + cdRegisterAttribute(canvas, &printername_attrib); + + if (dialog) + gtk_widget_destroy(GTK_WIDGET(dialog)); + + g_object_unref(settings); +} + +static void cdinittable(cdCanvas* canvas) +{ + cdcairoInitTable(canvas); + + canvas->cxKillCanvas = cdkillcanvas; +} + +static cdContext cdPrinterCairoContext = +{ + CD_CAP_ALL & ~(CD_CAP_PLAY | CD_CAP_YAXIS | CD_CAP_REGION | CD_CAP_GETIMAGERGB | + CD_CAP_WRITEMODE | CD_CAP_PALETTE | CD_CAP_IMAGESRV), + 0, + cdcreatecanvas, + cdinittable, + NULL, + NULL, +}; + +cdContext* cdContextCairoPrinter(void) +{ + return &cdPrinterCairoContext; +} |