#define COBJMACROS
#include "config.h"
#include <math.h>
+#ifdef HAVE_UNISTD_H
+#include <unistd.h>
+#endif
+#include <io.h>
+#include <stdio.h>
#include <stdlib.h>
+#include <windows.h>
#include <cairo-win32.h>
#include <glib.h>
#include "gtkprintoperation-private.h"
#include "gtkinvisible.h"
#include "gtkplug.h"
#include "gtkstock.h"
-#include "gtkalias.h"
#include "gtk.h"
#include "gtkwin32embedwidget.h"
int job_id;
guint timeout_id;
+ cairo_surface_t *surface;
GtkWidget *embed_widget;
} GtkPrintOperationWin32;
static const GUID myIID_IPrintDialogCallback = {0x5852a2c3,0x6530,0x11d1,{0xb6,0xa3,0x0,0x0,0xf8,0x75,0x7b,0xf9}};
+#if !defined (_MSC_VER) && !defined (__MINGW64_VERSION_MAJOR)
#undef INTERFACE
#define INTERFACE IPrintDialogCallback
DECLARE_INTERFACE_ (IPrintDialogCallback, IUnknown)
STDMETHOD (SelectionChange)(THIS) PURE;
STDMETHOD (HandleMessage)(THIS_ HWND,UINT,WPARAM,LPARAM,LRESULT*) PURE;
};
+#endif
static UINT got_gdk_events_message;
return 0;
}
+static gchar*
+get_default_printer (void)
+{
+ wchar_t *win32_printer_name = NULL;
+ gchar *printer_name = NULL;
+ DWORD needed;
+
+ GetDefaultPrinterW (NULL, &needed);
+ win32_printer_name = g_malloc ((gsize) needed * sizeof (wchar_t));
+ if (!GetDefaultPrinterW (win32_printer_name, &needed))
+ {
+ g_free (win32_printer_name);
+ return NULL;
+ }
+ printer_name = g_utf16_to_utf8 (win32_printer_name, -1, NULL, NULL, NULL);
+ g_free (win32_printer_name);
+
+ return printer_name;
+}
+
+static void
+set_hard_margins (GtkPrintOperation *op)
+{
+ double top, bottom, left, right;
+ GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
+
+ top = GetDeviceCaps (op_win32->hdc, PHYSICALOFFSETY);
+ bottom = GetDeviceCaps (op_win32->hdc, PHYSICALHEIGHT)
+ - GetDeviceCaps (op_win32->hdc, VERTRES) - top;
+ left = GetDeviceCaps (op_win32->hdc, PHYSICALOFFSETX);
+ right = GetDeviceCaps (op_win32->hdc, PHYSICALWIDTH)
+ - GetDeviceCaps (op_win32->hdc, HORZRES) - left;
+
+ _gtk_print_context_set_hard_margins (op->priv->print_context, top, bottom, left, right);
+}
+
void
win32_start_page (GtkPrintOperation *op,
GtkPrintContext *print_context,
GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
LPDEVMODEW devmode;
GtkPaperSize *paper_size;
+ double x_off, y_off;
devmode = GlobalLock (op_win32->devmode);
{
devmode->dmPaperSize = DMPAPER_USER;
devmode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
+
+ /* Lengths in DEVMODE are in tenths of a millimeter */
devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) * 10.0;
devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) * 10.0;
}
ResetDCW (op_win32->hdc, devmode);
GlobalUnlock (op_win32->devmode);
+
+ set_hard_margins (op);
+ x_off = GetDeviceCaps (op_win32->hdc, PHYSICALOFFSETX);
+ y_off = GetDeviceCaps (op_win32->hdc, PHYSICALOFFSETY);
+ cairo_surface_set_device_offset (op_win32->surface, -x_off, -y_off);
StartPage (op_win32->hdc);
}
GtkPrintContext *print_context)
{
GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
+
+ cairo_surface_show_page (op_win32->surface);
+
EndPage (op_win32->hdc);
}
win32_poll_status (op);
if (!gtk_print_operation_is_finished (op))
- op_win32->timeout_id = g_timeout_add (STATUS_POLLING_TIME,
+ op_win32->timeout_id = gdk_threads_add_timeout (STATUS_POLLING_TIME,
(GSourceFunc)win32_poll_status_timeout,
op);
g_object_unref (op);
GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
LPDEVNAMES devnames;
HANDLE printerHandle = 0;
+
+ cairo_surface_finish (op_win32->surface);
EndDoc (op_win32->hdc);
GlobalUnlock (op_win32->devnames);
}
- GlobalFree(op_win32->devmode);
- GlobalFree(op_win32->devnames);
+ GlobalFree (op_win32->devmode);
+ GlobalFree (op_win32->devnames);
- cairo_surface_destroy (op->priv->surface);
- op->priv->surface = NULL;
+ cairo_surface_destroy (op_win32->surface);
+ op_win32->surface = NULL;
- DeleteDC(op_win32->hdc);
+ DeleteDC (op_win32->hdc);
if (printerHandle != 0)
{
op_win32->printerHandle = printerHandle;
win32_poll_status (op);
- op_win32->timeout_id = g_timeout_add (STATUS_POLLING_TIME,
+ op_win32->timeout_id = gdk_threads_add_timeout (STATUS_POLLING_TIME,
(GSourceFunc)win32_poll_status_timeout,
op);
}
status_str = NULL;
if (ret)
{
+ DWORD win32_status;
job_info = (JOB_INFO_1W *)data;
- DWORD win32_status = job_info->Status;
+ win32_status = job_info->Status;
if (job_info->pStatus)
status_str = g_utf16_to_utf8 (job_info->pStatus,
get_parent_hwnd (GtkWidget *widget)
{
gtk_widget_realize (widget);
- return gdk_win32_drawable_get_handle (widget->window);
+ return gdk_win32_drawable_get_handle (gtk_widget_get_window (widget));
}
static void
-1, NULL, NULL, NULL);
if (form_name == NULL || form_name[0] == 0)
form_name = g_strdup (_("Custom size"));
+
+ /* Lengths in DEVMODE are in tenths of a millimeter */
paper_size = gtk_paper_size_new_custom (form_name,
form_name,
- devmode->dmPaperWidth * 10.0,
- devmode->dmPaperLength * 10.0,
+ devmode->dmPaperWidth / 10.0,
+ devmode->dmPaperLength / 10.0,
GTK_UNIT_MM);
gtk_print_settings_set_paper_size (settings, paper_size);
gtk_paper_size_free (paper_size);
}
if (devmode->dmFields & DM_SCALE)
- gtk_print_settings_set_scale (settings,
- devmode->dmScale / 100.0);
+ gtk_print_settings_set_scale (settings, devmode->dmScale);
if (devmode->dmFields & DM_COPIES)
gtk_print_settings_set_n_copies (settings,
}
if (devmode->dmFields & DM_COLOR)
- gtk_print_settings_set_use_color (settings, devmode->dmFields == DMCOLOR_COLOR);
+ gtk_print_settings_set_use_color (settings, devmode->dmColor == DMCOLOR_COLOR);
if (devmode->dmFields & DM_DUPLEX)
{
dialog_to_print_settings (GtkPrintOperation *op,
LPPRINTDLGEXW printdlgex)
{
- int i;
+ guint i;
GtkPrintSettings *settings;
settings = gtk_print_settings_new ();
{
devmode->dmDriverExtra = extras_len;
memcpy (((char *)devmode) + sizeof (DEVMODEW), extras, extras_len);
- g_free (extras);
}
+ g_free (extras);
if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION))
devmode->dmDriverVersion = gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION);
{
devmode->dmPaperSize = DMPAPER_USER;
devmode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
- devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) / 10.0;
- devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) / 10.0;
+
+ /* Lengths in DEVMODE are in tenths of a millimeter */
+ devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) * 10.0;
+ devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) * 10.0;
}
gtk_paper_size_free (paper_size);
}
if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_SCALE))
{
devmode->dmFields |= DM_SCALE;
- devmode->dmScale = gtk_print_settings_get_scale (settings) * 100;
+ devmode->dmScale = gtk_print_settings_get_scale (settings);
}
if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_N_COPIES))
printer = gtk_print_settings_get_printer (settings);
if (printer)
- printdlgex->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
+ printdlgex->hDevNames = gtk_print_win32_devnames_to_win32_from_printer_name (printer);
printdlgex->hDevMode = devmode_from_settings (settings,
op->priv->default_page_setup);
gboolean was_grabbed,
GtkPrintOperation *op)
{
- EnableWindow(GetAncestor (GDK_WINDOW_HWND (widget->window), GA_ROOT),
- was_grabbed);
+ EnableWindow (GetAncestor (GDK_WINDOW_HWND (gtk_widget_get_window (widget)), GA_ROOT),
+ was_grabbed);
}
op = GTK_PRINT_OPERATION ((gpointer)page->lParam);
op_win32 = op->priv->platform_data;
- SetWindowLongPtrW(wnd, GWLP_USERDATA, (LONG_PTR)op);
+ SetWindowLongPtrW (wnd, GWLP_USERDATA, (LONG_PTR)op);
plug = _gtk_win32_embed_widget_new ((GdkNativeWindow) wnd);
+ gtk_window_set_modal (GTK_WINDOW (plug), TRUE);
op_win32->embed_widget = plug;
gtk_container_add (GTK_CONTAINER (plug), op->priv->custom_widget);
gtk_widget_show (op->priv->custom_widget);
gtk_widget_show (plug);
- gdk_window_focus (plug->window, GDK_CURRENT_TIME);
+ gdk_window_focus (gtk_widget_get_window (plug), GDK_CURRENT_TIME);
/* This dialog is modal, so we grab the embed widget */
gtk_grab_add (plug);
}
else if (message == WM_DESTROY)
{
- op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
+ op = GTK_PRINT_OPERATION (GetWindowLongPtrW (wnd, GWLP_USERDATA));
op_win32 = op->priv->platform_data;
g_signal_emit_by_name (op, "custom-widget-apply", op->priv->custom_widget);
}
else
{
- op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
+ op = GTK_PRINT_OPERATION (GetWindowLongPtrW (wnd, GWLP_USERDATA));
op_win32 = op->priv->platform_data;
return _gtk_win32_embed_widget_dialog_procedure (GTK_WIN32_EMBED_WIDGET (op_win32->embed_widget),
WORD baseunitX, baseunitY;
WORD *array;
GtkRequisition requisition;
- const char *app_name;
+ const char *tab_label;
/* Make the template the size of the custom widget size request */
- gtk_widget_size_request (op->priv->custom_widget, &requisition);
-
- base_units = GetDialogBaseUnits();
- baseunitX = LOWORD(base_units);
- baseunitY = HIWORD(base_units);
+ gtk_widget_get_preferred_size (op->priv->custom_widget,
+ &requisition, NULL);
+
+ base_units = GetDialogBaseUnits ();
+ baseunitX = LOWORD (base_units);
+ baseunitY = HIWORD (base_units);
htemplate = GlobalAlloc (GMEM_MOVEABLE,
- sizeof (DLGTEMPLATE) + sizeof(WORD) * 3);
+ sizeof (DLGTEMPLATE) + sizeof (WORD) * 3);
template = GlobalLock (htemplate);
template->style = WS_CHILDWINDOW | DS_CONTROL;
template->dwExtendedStyle = WS_EX_CONTROLPARENT;
template->cdit = 0;
- template->x = MulDiv(0, 4, baseunitX);
- template->y = MulDiv(0, 8, baseunitY);
- template->cx = MulDiv(requisition.width, 4, baseunitX);
- template->cy = MulDiv(requisition.height, 8, baseunitY);
+ template->x = MulDiv (0, 4, baseunitX);
+ template->y = MulDiv (0, 8, baseunitY);
+ template->cx = MulDiv (requisition.width, 4, baseunitX);
+ template->cy = MulDiv (requisition.height, 8, baseunitY);
array = (WORD *) (template+1);
*array++ = 0; /* menu */
*array++ = 0; /* class */
*array++ = 0; /* title */
- memset(&page, 0, sizeof (page));
+ memset (&page, 0, sizeof (page));
page.dwSize = sizeof (page);
page.dwFlags = PSP_DLGINDIRECT | PSP_USETITLE | PSP_PREMATURE;
page.hInstance = GetModuleHandle (NULL);
page.pResource = template;
- app_name = g_get_application_name ();
- if (app_name == NULL)
- app_name = _("Application");
- page.pszTitle = g_utf8_to_utf16 (app_name,
+
+ tab_label = op->priv->custom_tab_label;
+ if (tab_label == NULL)
+ tab_label = g_get_application_name ();
+ if (tab_label == NULL)
+ tab_label = _("Application");
+ page.pszTitle = g_utf8_to_utf16 (tab_label,
-1, NULL, NULL, NULL);
page.pfnDlgProc = pageDlgProc;
page.pfnCallback = NULL;
page.lParam = (LPARAM) op;
- hpage = CreatePropertySheetPageW(&page);
+ hpage = CreatePropertySheetPageW (&page);
GlobalUnlock (htemplate);
return hpage;
}
+static GtkPageSetup *
+create_page_setup (GtkPrintOperation *op)
+{
+ GtkPrintOperationPrivate *priv = op->priv;
+ GtkPageSetup *page_setup;
+ GtkPrintSettings *settings;
+
+ if (priv->default_page_setup)
+ page_setup = gtk_page_setup_copy (priv->default_page_setup);
+ else
+ page_setup = gtk_page_setup_new ();
+
+ settings = priv->print_settings;
+ if (settings)
+ {
+ GtkPaperSize *paper_size;
+
+ if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
+ gtk_page_setup_set_orientation (page_setup,
+ gtk_print_settings_get_orientation (settings));
+
+
+ paper_size = gtk_print_settings_get_paper_size (settings);
+ if (paper_size)
+ {
+ gtk_page_setup_set_paper_size (page_setup, paper_size);
+ gtk_paper_size_free (paper_size);
+ }
+
+ /* TODO: Margins? */
+ }
+
+ return page_setup;
+}
+
GtkPrintOperationResult
-_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
- GtkWindow *parent,
- gboolean *do_print,
- GError **error)
+gtk_print_operation_run_without_dialog (GtkPrintOperation *op,
+ gboolean *do_print)
+{
+ GtkPrintOperationResult result;
+ GtkPrintOperationWin32 *op_win32;
+ GtkPrintOperationPrivate *priv;
+ GtkPrintSettings *settings;
+ GtkPageSetup *page_setup;
+ DOCINFOW docinfo;
+ HGLOBAL hDevMode = NULL;
+ HGLOBAL hDevNames = NULL;
+ HDC hDC = NULL;
+ const char *printer = NULL;
+ double dpi_x, dpi_y;
+ int job_id;
+ cairo_t *cr;
+ DEVNAMES *pdn;
+ DEVMODEW *pdm;
+
+ *do_print = FALSE;
+
+ priv = op->priv;
+ settings = priv->print_settings;
+
+ op_win32 = g_new0 (GtkPrintOperationWin32, 1);
+ priv->platform_data = op_win32;
+ priv->free_platform_data = (GDestroyNotify) op_win32_free;
+ printer = gtk_print_settings_get_printer (settings);
+
+ if (!printer)
+ {
+ /* No printer selected. Get the system default printer and store
+ * it in settings.
+ */
+ gchar *tmp_printer = get_default_printer ();
+ if (!tmp_printer)
+ {
+ result = GTK_PRINT_OPERATION_RESULT_ERROR;
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_INTERNAL_ERROR,
+ _("No printer found"));
+ goto out;
+ }
+ gtk_print_settings_set_printer (settings, tmp_printer);
+ printer = gtk_print_settings_get_printer (settings);
+ g_free (tmp_printer);
+ }
+
+ hDevNames = gtk_print_win32_devnames_to_win32_from_printer_name (printer);
+ hDevMode = devmode_from_settings (settings, op->priv->default_page_setup);
+
+ /* Create a printer DC for the print settings and page setup provided. */
+ pdn = GlobalLock (hDevNames);
+ pdm = GlobalLock (hDevMode);
+ hDC = CreateDCW ((wchar_t*)pdn + pdn->wDriverOffset,
+ (wchar_t*)pdn + pdn->wDeviceOffset,
+ (wchar_t*)pdn + pdn->wOutputOffset,
+ pdm );
+ GlobalUnlock (hDevNames);
+ GlobalUnlock (hDevMode);
+
+ if (!hDC)
+ {
+ result = GTK_PRINT_OPERATION_RESULT_ERROR;
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_INTERNAL_ERROR,
+ _("Invalid argument to CreateDC"));
+ goto out;
+ }
+
+ priv->print_context = _gtk_print_context_new (op);
+ page_setup = create_page_setup (op);
+ _gtk_print_context_set_page_setup (priv->print_context, page_setup);
+ g_object_unref (page_setup);
+
+ *do_print = TRUE;
+
+ op_win32->surface = cairo_win32_printing_surface_create (hDC);
+ dpi_x = (double) GetDeviceCaps (hDC, LOGPIXELSX);
+ dpi_y = (double) GetDeviceCaps (hDC, LOGPIXELSY);
+
+ cr = cairo_create (op_win32->surface);
+ gtk_print_context_set_cairo_context (priv->print_context, cr, dpi_x, dpi_y);
+ cairo_destroy (cr);
+
+ set_hard_margins (op);
+
+ memset (&docinfo, 0, sizeof (DOCINFOW));
+ docinfo.cbSize = sizeof (DOCINFOW);
+ docinfo.lpszDocName = g_utf8_to_utf16 (op->priv->job_name, -1, NULL, NULL, NULL);
+ docinfo.lpszOutput = NULL;
+ docinfo.lpszDatatype = NULL;
+ docinfo.fwType = 0;
+
+ job_id = StartDocW (hDC, &docinfo);
+ g_free ((void *)docinfo.lpszDocName);
+ if (job_id <= 0)
+ {
+ result = GTK_PRINT_OPERATION_RESULT_ERROR;
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_GENERAL,
+ _("Error from StartDoc"));
+ *do_print = FALSE;
+ cairo_surface_destroy (op_win32->surface);
+ op_win32->surface = NULL;
+ goto out;
+ }
+
+ result = GTK_PRINT_OPERATION_RESULT_APPLY;
+ op_win32->hdc = hDC;
+ op_win32->devmode = hDevMode;
+ op_win32->devnames = hDevNames;
+ op_win32->job_id = job_id;
+ op->priv->print_pages = gtk_print_settings_get_print_pages (op->priv->print_settings);
+ op->priv->num_page_ranges = 0;
+ if (op->priv->print_pages == GTK_PRINT_PAGES_RANGES)
+ op->priv->page_ranges = gtk_print_settings_get_page_ranges (op->priv->print_settings,
+ &op->priv->num_page_ranges);
+ op->priv->manual_num_copies = 1;
+ op->priv->manual_collation = FALSE;
+ op->priv->manual_reverse = FALSE;
+ op->priv->manual_orientation = FALSE;
+ op->priv->manual_scale = 1.0;
+ op->priv->manual_page_set = GTK_PAGE_SET_ALL;
+ op->priv->manual_number_up = 1;
+ op->priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
+
+ op->priv->start_page = win32_start_page;
+ op->priv->end_page = win32_end_page;
+ op->priv->end_run = win32_end_run;
+
+ out:
+ if (!*do_print && hDC != NULL)
+ DeleteDC (hDC);
+
+ if (!*do_print && hDevMode != NULL)
+ GlobalFree (hDevMode);
+
+ if (!*do_print && hDevNames != NULL)
+ GlobalFree (hDevNames);
+
+ return result;
+}
+
+GtkPrintOperationResult
+gtk_print_operation_run_with_dialog (GtkPrintOperation *op,
+ GtkWindow *parent,
+ gboolean *do_print)
{
HRESULT hResult;
LPPRINTDLGEXW printdlgex = NULL;
GtkWidget *invisible = NULL;
GtkPrintOperationResult result;
GtkPrintOperationWin32 *op_win32;
+ GtkPrintOperationPrivate *priv;
IPrintDialogCallback *callback;
HPROPSHEETPAGE prop_page;
*do_print = FALSE;
+ priv = op->priv;
+
op_win32 = g_new0 (GtkPrintOperationWin32, 1);
- op->priv->platform_data = op_win32;
- op->priv->free_platform_data = (GDestroyNotify) op_win32_free;
+ priv->platform_data = op_win32;
+ priv->free_platform_data = (GDestroyNotify) op_win32_free;
if (parent == NULL)
{
if (!printdlgex)
{
result = GTK_PRINT_OPERATION_RESULT_ERROR;
- g_set_error (error,
- GTK_PRINT_ERROR,
- GTK_PRINT_ERROR_NOMEM,
- _("Not enough free memory"));
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_NOMEM,
+ _("Not enough free memory"));
goto out;
}
- printdlgex->lStructSize = sizeof(PRINTDLGEXW);
+ printdlgex->lStructSize = sizeof (PRINTDLGEXW);
printdlgex->hwndOwner = parentHWnd;
printdlgex->hDevMode = NULL;
printdlgex->hDevNames = NULL;
if (!page_ranges)
{
result = GTK_PRINT_OPERATION_RESULT_ERROR;
- g_set_error (error,
- GTK_PRINT_ERROR,
- GTK_PRINT_ERROR_NOMEM,
- _("Not enough free memory"));
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_NOMEM,
+ _("Not enough free memory"));
goto out;
}
printdlgex->lpCallback = (IUnknown *)callback;
got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
- hResult = PrintDlgExW(printdlgex);
+ hResult = PrintDlgExW (printdlgex);
IUnknown_Release ((IUnknown *)callback);
gdk_win32_set_modal_dialog_libgtk_only (NULL);
{
result = GTK_PRINT_OPERATION_RESULT_ERROR;
if (hResult == E_OUTOFMEMORY)
- g_set_error (error,
- GTK_PRINT_ERROR,
- GTK_PRINT_ERROR_NOMEM,
- _("Not enough free memory"));
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_NOMEM,
+ _("Not enough free memory"));
else if (hResult == E_INVALIDARG)
- g_set_error (error,
- GTK_PRINT_ERROR,
- GTK_PRINT_ERROR_INTERNAL_ERROR,
- _("Invalid argument to PrintDlgEx"));
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_INTERNAL_ERROR,
+ _("Invalid argument to PrintDlgEx"));
else if (hResult == E_POINTER)
- g_set_error (error,
- GTK_PRINT_ERROR,
- GTK_PRINT_ERROR_INTERNAL_ERROR,
- _("Invalid pointer to PrintDlgEx"));
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_INTERNAL_ERROR,
+ _("Invalid pointer to PrintDlgEx"));
else if (hResult == E_HANDLE)
- g_set_error (error,
- GTK_PRINT_ERROR,
- GTK_PRINT_ERROR_INTERNAL_ERROR,
- _("Invalid handle to PrintDlgEx"));
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_INTERNAL_ERROR,
+ _("Invalid handle to PrintDlgEx"));
else /* E_FAIL */
- g_set_error (error,
- GTK_PRINT_ERROR,
- GTK_PRINT_ERROR_GENERAL,
- _("Unspecified error"));
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_GENERAL,
+ _("Unspecified error"));
goto out;
}
{
DOCINFOW docinfo;
int job_id;
-
+ double dpi_x, dpi_y;
+ cairo_t *cr;
+ GtkPageSetup *page_setup;
+
+ priv->print_context = _gtk_print_context_new (op);
+ page_setup = create_page_setup (op);
+ _gtk_print_context_set_page_setup (priv->print_context, page_setup);
+ g_object_unref (page_setup);
+
*do_print = TRUE;
- op->priv->surface = cairo_win32_surface_create (printdlgex->hDC);
- op->priv->dpi_x = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSX);
- op->priv->dpi_y = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSY);
+ op_win32->surface = cairo_win32_printing_surface_create (printdlgex->hDC);
- memset( &docinfo, 0, sizeof (DOCINFOW));
+ dpi_x = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSX);
+ dpi_y = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSY);
+
+ cr = cairo_create (op_win32->surface);
+ gtk_print_context_set_cairo_context (priv->print_context, cr, dpi_x, dpi_y);
+ cairo_destroy (cr);
+
+ set_hard_margins (op);
+
+ memset ( &docinfo, 0, sizeof (DOCINFOW));
docinfo.cbSize = sizeof (DOCINFOW);
docinfo.lpszDocName = g_utf8_to_utf16 (op->priv->job_name, -1, NULL, NULL, NULL);
docinfo.lpszOutput = (LPCWSTR) NULL;
docinfo.lpszDatatype = (LPCWSTR) NULL;
docinfo.fwType = 0;
- job_id = StartDocW(printdlgex->hDC, &docinfo);
+ job_id = StartDocW (printdlgex->hDC, &docinfo);
g_free ((void *)docinfo.lpszDocName);
if (job_id <= 0)
- {
+ {
result = GTK_PRINT_OPERATION_RESULT_ERROR;
- g_set_error (error,
- GTK_PRINT_ERROR,
- GTK_PRINT_ERROR_GENERAL,
- _("Error from StartDoc"));
+ g_set_error_literal (&priv->error,
+ GTK_PRINT_ERROR,
+ GTK_PRINT_ERROR_GENERAL,
+ _("Error from StartDoc"));
*do_print = FALSE;
- cairo_surface_destroy (op->priv->surface);
- op->priv->surface = NULL;
+ cairo_surface_destroy (op_win32->surface);
+ op_win32->surface = NULL;
goto out;
}
op->priv->manual_orientation = FALSE;
op->priv->manual_scale = 1.0;
op->priv->manual_page_set = GTK_PAGE_SET_ALL;
+ op->priv->manual_number_up = 1;
+ op->priv->manual_number_up_layout = GTK_NUMBER_UP_LAYOUT_LEFT_TO_RIGHT_TOP_TO_BOTTOM;
}
op->priv->start_page = win32_start_page;
op->priv->end_run = win32_end_run;
out:
+ if (!*do_print && printdlgex && printdlgex->hDC != NULL)
+ DeleteDC (printdlgex->hDC);
+
if (!*do_print && printdlgex && printdlgex->hDevMode != NULL)
- GlobalFree(printdlgex->hDevMode);
+ GlobalFree (printdlgex->hDevMode);
if (!*do_print && printdlgex && printdlgex->hDevNames != NULL)
- GlobalFree(printdlgex->hDevNames);
+ GlobalFree (printdlgex->hDevNames);
if (page_ranges)
GlobalFree (page_ranges);
return result;
}
-void
-_gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
- GtkWindow *parent,
- GtkPrintOperationPrintFunc print_cb)
+GtkPrintOperationResult
+_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
+ gboolean show_dialog,
+ GtkWindow *parent,
+ gboolean *do_print)
{
- gboolean do_print;
-
- _gtk_print_operation_platform_backend_run_dialog (op, parent, &do_print, NULL);
- if (do_print)
- print_cb (op, parent, FALSE);
+ if (show_dialog)
+ return gtk_print_operation_run_with_dialog (op, parent, do_print);
else
- _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
+ return gtk_print_operation_run_without_dialog (op, do_print);
+}
+
+void
+_gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
+ cairo_surface_t *surface,
+ GtkWindow *parent,
+ const gchar *filename)
+{
+ HDC dc;
+ HENHMETAFILE metafile;
+
+ dc = cairo_win32_surface_get_dc (surface);
+ cairo_surface_destroy (surface);
+ metafile = CloseEnhMetaFile (dc);
+ DeleteEnhMetaFile (metafile);
+
+ ShellExecuteW (NULL, L"open", (gunichar2 *)filename, NULL, NULL, SW_SHOW);
+}
+
+void
+_gtk_print_operation_platform_backend_preview_start_page (GtkPrintOperation *op,
+ cairo_surface_t *surface,
+ cairo_t *cr)
+{
+ HDC dc = cairo_win32_surface_get_dc (surface);
+ StartPage (dc);
+}
+
+void
+_gtk_print_operation_platform_backend_preview_end_page (GtkPrintOperation *op,
+ cairo_surface_t *surface,
+ cairo_t *cr)
+{
+ HDC dc;
+
+ cairo_surface_show_page (surface);
+
+ /* TODO: Enhanced metafiles don't support multiple pages.
+ */
+ dc = cairo_win32_surface_get_dc (surface);
+ EndPage (dc);
+}
+
+cairo_surface_t *
+_gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *op,
+ GtkPageSetup *page_setup,
+ gdouble *dpi_x,
+ gdouble *dpi_y,
+ gchar **target)
+{
+ GtkPaperSize *paper_size;
+ HDC metafile_dc;
+ RECT rect;
+ char *template;
+ char *filename;
+ gunichar2 *filename_utf16;
+ int fd;
+
+ template = g_build_filename (g_get_tmp_dir (), "prXXXXXX", NULL);
+ fd = g_mkstemp (template);
+ close (fd);
+
+ filename = g_strconcat (template, ".emf", NULL);
+ g_free (template);
+
+ filename_utf16 = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
+ g_free (filename);
+
+ paper_size = gtk_page_setup_get_paper_size (page_setup);
+
+ /* The rectangle dimensions are given in hundredths of a millimeter */
+ rect.left = 0;
+ rect.right = 100.0 * gtk_paper_size_get_width (paper_size, GTK_UNIT_MM);
+ rect.top = 0;
+ rect.bottom = 100.0 * gtk_paper_size_get_height (paper_size, GTK_UNIT_MM);
+
+ metafile_dc = CreateEnhMetaFileW (NULL, filename_utf16,
+ &rect, L"Gtk+\0Print Preview\0\0");
+ if (metafile_dc == NULL)
+ {
+ g_warning ("Can't create metafile");
+ return NULL;
+ }
+
+ *target = (char *)filename_utf16;
+
+ *dpi_x = (double)GetDeviceCaps (metafile_dc, LOGPIXELSX);
+ *dpi_y = (double)GetDeviceCaps (metafile_dc, LOGPIXELSY);
+
+ return cairo_win32_printing_surface_create (metafile_dc);
+}
+
+void
+_gtk_print_operation_platform_backend_resize_preview_surface (GtkPrintOperation *op,
+ GtkPageSetup *page_setup,
+ cairo_surface_t *surface)
+{
+ /* TODO: Implement */
}
GtkPageSetup *
memset (pagesetupdlg, 0, sizeof (PAGESETUPDLGW));
- pagesetupdlg->lStructSize = sizeof(PAGESETUPDLGW);
+ pagesetupdlg->lStructSize = sizeof (PAGESETUPDLGW);
if (parent != NULL)
pagesetupdlg->hwndOwner = get_parent_hwnd (GTK_WIDGET (parent));
pagesetupdlg->hDevNames = NULL;
printer = gtk_print_settings_get_printer (settings);
if (printer)
- pagesetupdlg->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
+ pagesetupdlg->hDevNames = gtk_print_win32_devnames_to_win32_from_printer_name (printer);
- GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IMEASURE|LOCALE_RETURN_NUMBER,
- (LPWSTR)&measure_system, sizeof (DWORD));
+ GetLocaleInfoW (LOCALE_USER_DEFAULT, LOCALE_IMEASURE|LOCALE_RETURN_NUMBER,
+ (LPWSTR)&measure_system, sizeof (DWORD));
if (measure_system == 0)
{
devmode_to_settings (settings, pagesetupdlg->hDevMode);
}
- if (free_settings)
- g_object_unref (settings);
-
if (res)
{
gtk_page_setup_set_orientation (page_setup,
unit);
}
+ if (free_settings)
+ g_object_unref (settings);
+
return page_setup;
}