#ifndef _MSC_VER
#define _WIN32_WINNT 0x0500
#define WINVER _WIN32_WINNT
#endif

#include <windows.h>
#include <cairo-win32.h>
#include <gdk/gdkwin32.h>
#include <gtk/gtk.h>

static void
print_to_hdc(HDC hdc)
{
    DOCINFOW docinfo;
    cairo_surface_t *surface;
    cairo_t *cr;

    memset(&docinfo, 0, sizeof (DOCINFOW));
    docinfo.cbSize = sizeof (DOCINFOW); 
    docinfo.lpszDocName = g_utf8_to_utf16("JName", -1, NULL, NULL, NULL); 
    docinfo.lpszOutput = (LPCWSTR) NULL; 
    docinfo.lpszDatatype = (LPCWSTR) NULL; 
    docinfo.fwType = 0;
    StartDocW(hdc, &docinfo);
    StartPage(hdc);

    surface = cairo_win32_surface_create(hdc);
    cr = cairo_create(surface);

    cairo_rectangle(cr, 500, 500, 500, 500);
    cairo_stroke(cr);

    cairo_destroy(cr);
    cairo_surface_finish(surface);
    cairo_surface_destroy(surface);

    EndPage(hdc);
    EndDoc(hdc);
}

int
main(int argc, char **argv)
{
    GtkWidget *window;
    HWND hWnd;
    HRESULT hResult;
    LPPRINTDLGEX pPDX = NULL;
    LPPRINTPAGERANGE pPageRanges = NULL;

    gtk_init(&argc, &argv);

    window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
    g_signal_connect(window, "delete_event", G_CALLBACK(gtk_main_quit), NULL);
    gtk_widget_show(window);

    hWnd = GDK_WINDOW_HWND(window->window);

    pPDX = (LPPRINTDLGEX)GlobalAlloc(GPTR, sizeof(PRINTDLGEX));
    if (!pPDX)
        return E_OUTOFMEMORY;

    pPageRanges = (LPPRINTPAGERANGE) GlobalAlloc(GPTR, 
                                                 10 * sizeof(PRINTPAGERANGE));
    if (!pPageRanges)
        return E_OUTOFMEMORY;

    pPDX->lStructSize = sizeof(PRINTDLGEX);
    pPDX->hwndOwner = hWnd;
    pPDX->hDevMode = NULL;
    pPDX->hDevNames = NULL;
    pPDX->hDC = NULL;
    pPDX->Flags = PD_RETURNDC | PD_COLLATE;
    pPDX->Flags2 = 0;
    pPDX->ExclusionFlags = 0;
    pPDX->nPageRanges = 0;
    pPDX->nMaxPageRanges = 10;
    pPDX->lpPageRanges = pPageRanges;
    pPDX->nMinPage = 1;
    pPDX->nMaxPage = 1000;
    pPDX->nCopies = 1;
    pPDX->hInstance = 0;
    pPDX->lpPrintTemplateName = NULL;
    pPDX->lpCallback = NULL;
    pPDX->nPropertyPages = 0;
    pPDX->lphPropertyPages = NULL;
    pPDX->nStartPage = START_PAGE_GENERAL;
    pPDX->dwResultAction = 0;

    hResult = PrintDlgEx(pPDX);

    if ( (hResult == S_OK) &&
         pPDX->dwResultAction == PD_RESULT_PRINT) {
        print_to_hdc(pPDX->hDC);
    }

    if (pPDX->hDC != NULL) 
        DeleteDC(pPDX->hDC);
    if (pPDX->hDevMode != NULL) 
        GlobalFree(pPDX->hDevMode); 
    if (pPDX->hDevNames != NULL) 
        GlobalFree(pPDX->hDevNames); 

    return hResult;
}
