/* Assumes A4 portrait pages. Draws a rectange two pages high and renders each
 * page of output during the print operation from a GooCanvas.
 * Compile with gcc test.c `pkg-config --cflags --libs gtk+-3.0 goocanvas-2.0`
 */
#include <gtk/gtk.h>
#include <goocanvas.h>

GtkPrintSettings *settings = NULL;

const double A4_PAGE_HEIGHT = 297.0;
const double A4_PAGE_WIDTH = 210.0;

typedef struct
{
    GtkWidget *window;
    GtkWidget *canvas;
} PrintData;

void begin_print(GtkPrintOperation *operation, GtkPrintContext *context, gpointer user_data)
{
    gtk_print_operation_set_n_pages(operation, 2);
}

void draw_page(GtkPrintOperation *operation, GtkPrintContext *context, gint page_nr, gpointer user_data)
{
    PrintData *data = (PrintData *)user_data;
    cairo_t *cr;
    GooCanvasBounds bounds;
    bounds.x1 = 0;
    bounds.x2 = A4_PAGE_WIDTH;
    bounds.y1 = A4_PAGE_HEIGHT * page_nr;
    bounds.y2 = A4_PAGE_HEIGHT * (page_nr + 1);

    cr = gtk_print_context_get_cairo_context(context);
    goo_canvas_render(GOO_CANVAS(data->canvas), cr, &bounds, 0.0);
}

void do_print(GtkButton *button, gpointer user_data)
{
    GtkPrintOperation *print;
    GtkPrintOperationResult result;
    PrintData *data = (PrintData *)user_data;

    print = gtk_print_operation_new();
    g_object_set(print, "unit", GTK_UNIT_MM, "use_full_page", TRUE, NULL);
    if(settings != NULL)
        gtk_print_operation_set_print_settings(print, settings);
    g_signal_connect(print, "begin_print", G_CALLBACK(begin_print), data);
    g_signal_connect(print, "draw_page", G_CALLBACK(draw_page), data);
    result = gtk_print_operation_run(print, GTK_PRINT_OPERATION_ACTION_PRINT_DIALOG, GTK_WINDOW(data->window), NULL);
    if(result == GTK_PRINT_OPERATION_RESULT_APPLY)
    {
        if(settings != NULL)
            g_object_unref(settings);
        settings = g_object_ref(gtk_print_operation_get_print_settings(print));
    }
    g_object_unref(print);
}

int main (int argc, char *argv[])
{
    GtkWidget *box;
    GtkWidget *print_button;
    GooCanvasItem *root, *rect;
    PrintData print_data;

    gtk_init(&argc, &argv);

    print_data.window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    gtk_window_set_default_size(GTK_WINDOW(print_data.window), 640, 480);
    print_data.canvas = goo_canvas_new();
    print_button = gtk_button_new_from_stock(GTK_STOCK_PRINT);
    box = gtk_box_new(GTK_ORIENTATION_VERTICAL, 6);
    g_object_set(print_data.canvas, "units", GTK_UNIT_MM, NULL);

    /* Two portait A4 pages tall. */
    goo_canvas_set_bounds(GOO_CANVAS(print_data.canvas), 0, 0, A4_PAGE_WIDTH, 2 * A4_PAGE_HEIGHT);
    root = goo_canvas_get_root_item(GOO_CANVAS(print_data.canvas));
    rect = goo_canvas_rect_new(root, 100, 0, 10, 2 * A4_PAGE_HEIGHT, "stroke-color", "red", "line-width", 2.0, "fill-color", "blue", NULL);

    gtk_box_pack_start(GTK_BOX(box), print_data.canvas, TRUE, TRUE, 0);
    gtk_container_add(GTK_CONTAINER(box), print_button);
    gtk_container_add(GTK_CONTAINER(print_data.window), box);

    g_signal_connect(print_button, "clicked", G_CALLBACK(do_print), (gpointer)&print_data);
    g_signal_connect(print_data.window, "delete-event", gtk_main_quit, NULL);
    gtk_widget_show_all(print_data.window);

    gtk_main();
    return 0;
}
