GTK Unix Print Dialog working example



Hi,

        as nobody answered my question and I couldn't find a solution online,
I decided to do some more research. 

        I carefully studied the source code for GtkPrintOperation and finally
answered my own question. 

         I'm posting this here so it can be found by others in the future: 

        The source code: 

         - - - -  

        #include <gtk/gtk.h>
#include <gtk/gtkunixprint.h>

GMainLoop *loop;

static void
print_end(GtkPrintJob *print_job, gpointer user_data, GError *err)
{
    g_main_loop_quit( loop );
    g_assert(err == NULL);
}

static void
print_page(GtkWidget *widget, gpointer user_data)
{
    GtkWindow *parent = user_data;
    GtkPrintJob *print_job;
    GtkPrinter *printer;
    GtkPrintSettings *settings;
    GtkPageSetup *page_setup;
    GtkWidget *dialog;
    cairo_t *cr;
    cairo_surface_t *surface;

    dialog = gtk_print_unix_dialog_new(NULL, parent);
    if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {

        printer = gtk_print_unix_dialog_get_selected_printer(
GTK_PRINT_UNIX_DIALOG(dialog));
        settings = gtk_print_unix_dialog_get_settings(
GTK_PRINT_UNIX_DIALOG(dialog));
        page_setup = gtk_print_unix_dialog_get_page_setup(
GTK_PRINT_UNIX_DIALOG(dialog));

        print_job = gtk_print_job_new("Example title", printer,
settings, page_setup);
        surface = gtk_print_job_get_surface( print_job, NULL  );

        cr = cairo_create( surface );

        cairo_set_source_rgb(cr, 0.6, 0.6, 0.6);
        cairo_set_line_width(cr, 1);

        cairo_rectangle(cr, 20, 20, 120, 80);
        cairo_rectangle(cr, 180, 20, 80, 80);
        cairo_stroke_preserve(cr);
        cairo_fill(cr);

        cairo_show_page( cr );

        cairo_surface_finish( surface );

        loop = g_main_loop_new( NULL,FALSE );

        gtk_print_job_send(print_job, print_end, NULL, NULL);

        g_main_loop_run( loop );

        cairo_destroy( cr );
        cairo_surface_destroy( surface );

        g_main_loop_unref( loop );
        g_object_unref(settings);
        g_object_unref(page_setup);
        g_object_unref(printer);
    }
    gtk_widget_destroy(dialog);
    return;

}

int
main(int argc, char **argv)
{
    GtkWidget *window;
    GtkWidget *button;

    gtk_init(&argc, &argv);
    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "destroy", G_CALLBACK(gtk_main_quit),
NULL);
    gtk_container_set_border_width(GTK_CONTAINER(window), 10);

    button = gtk_button_new_with_label("Print");
    gtk_container_add(GTK_CONTAINER(window), button);
    g_signal_connect(button, "clicked", G_CALLBACK(print_page),
GTK_WINDOW(window));
    gtk_widget_show_all(window);
    gtk_main();
    return 0;
}

        - - - -  

        The main improvement was the cairo_surface_finish( surface )
statement. I don't know why it is needed but it is. Even now the
documentation leaves me clueless.  

        I don't know whether the main_loop stuff is actually needed. It waits
until the print job is finished before unref'ing the objects. My
program worked without it, but things might be different in larger
print jobs or slower printers. 

        For completion, here is the Makefile: 

        - - - -  

        EXES = unixprint
CC = cc
CFLAGS = -Wall -g `pkg-config --cflags --libs gtk+-2.0` `pkg-config
--cflags --libs gtk+-unix-print-2.0`

all:
    $(MAKE) $(EXES)

%: %.c
    $(CC) $(CFLAGS) $  c -o $@

clean:
    rm -f $(EXES) *.o

        - - - - 

        Hope this stuff is helpful to somebody. If you see any room for
improvement let me know. I'd really like this to become a good
example. 

        Regards, 

        Martin


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]