X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkprintoperation-win32.c;h=04de8ebbeb178f44d8bd7d2db460199f96162a74;hb=ea043cab5718304d9b6170afa2d3f959fc99c718;hp=8184846604eeb26826a75f4a2d17d3a39abcedb1;hpb=b08305d2d713bd16200bb010b0665d97533b740e;p=~andy%2Fgtk diff --git a/gtk/gtkprintoperation-win32.c b/gtk/gtkprintoperation-win32.c index 818484660..04de8ebbe 100644 --- a/gtk/gtkprintoperation-win32.c +++ b/gtk/gtkprintoperation-win32.c @@ -13,9 +13,7 @@ * Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the - * Free Software Foundation, Inc., 59 Temple Place - Suite 330, - * Boston, MA 02111-1307, USA. + * License along with this library. If not, see . */ #ifndef _MSC_VER @@ -32,6 +30,7 @@ #include #include #include +#include #include #include #include "gtkprintoperation-private.h" @@ -40,7 +39,6 @@ #include "gtkinvisible.h" #include "gtkplug.h" #include "gtkstock.h" -#include "gtkalias.h" #include "gtk.h" #include "gtkwin32embedwidget.h" @@ -71,7 +69,7 @@ static void win32_poll_status (GtkPrintOperation *op); static const GUID myIID_IPrintDialogCallback = {0x5852a2c3,0x6530,0x11d1,{0xb6,0xa3,0x0,0x0,0xf8,0x75,0x7b,0xf9}}; -#ifndef _MSC_VER +#if !defined (_MSC_VER) && !defined (HAVE_IPRINTDIALOGCALLBACK) #undef INTERFACE #define INTERFACE IPrintDialogCallback DECLARE_INTERFACE_ (IPrintDialogCallback, IUnknown) @@ -415,6 +413,42 @@ paper_size_to_win32 (GtkPaperSize *paper_size) 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, @@ -423,6 +457,7 @@ win32_start_page (GtkPrintOperation *op, GtkPrintOperationWin32 *op_win32 = op->priv->platform_data; LPDEVMODEW devmode; GtkPaperSize *paper_size; + double x_off, y_off; devmode = GlobalLock (op_win32->devmode); @@ -438,6 +473,8 @@ win32_start_page (GtkPrintOperation *op, { 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; } @@ -445,6 +482,11 @@ win32_start_page (GtkPrintOperation *op, 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); } @@ -454,6 +496,9 @@ win32_end_page (GtkPrintOperation *op, GtkPrintContext *print_context) { GtkPrintOperationWin32 *op_win32 = op->priv->platform_data; + + cairo_surface_show_page (op_win32->surface); + EndPage (op_win32->hdc); } @@ -469,7 +514,7 @@ win32_poll_status_timeout (GtkPrintOperation *op) 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); @@ -485,6 +530,8 @@ win32_end_run (GtkPrintOperation *op, GtkPrintOperationWin32 *op_win32 = op->priv->platform_data; LPDEVNAMES devnames; HANDLE printerHandle = 0; + + cairo_surface_finish (op_win32->surface); EndDoc (op_win32->hdc); @@ -497,20 +544,19 @@ win32_end_run (GtkPrintOperation *op, GlobalUnlock (op_win32->devnames); } - GlobalFree(op_win32->devmode); - GlobalFree(op_win32->devnames); + GlobalFree (op_win32->devmode); + GlobalFree (op_win32->devnames); - cairo_surface_finish (op_win32->surface); 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); } @@ -607,7 +653,7 @@ static HWND get_parent_hwnd (GtkWidget *widget) { gtk_widget_realize (widget); - return gdk_win32_drawable_get_handle (widget->window); + return gdk_win32_window_get_handle (gtk_widget_get_window (widget)); } static void @@ -667,18 +713,19 @@ devmode_to_settings (GtkPrintSettings *settings, -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, @@ -758,7 +805,7 @@ devmode_to_settings (GtkPrintSettings *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) { @@ -840,7 +887,7 @@ static void dialog_to_print_settings (GtkPrintOperation *op, LPPRINTDLGEXW printdlgex) { - int i; + guint i; GtkPrintSettings *settings; settings = gtk_print_settings_new (); @@ -912,8 +959,8 @@ devmode_from_settings (GtkPrintSettings *settings, { 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); @@ -950,8 +997,10 @@ devmode_from_settings (GtkPrintSettings *settings, { 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); } @@ -959,7 +1008,7 @@ devmode_from_settings (GtkPrintSettings *settings, 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)) @@ -1169,7 +1218,7 @@ dialog_from_print_settings (GtkPrintOperation *op, 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); @@ -1288,8 +1337,8 @@ plug_grab_notify (GtkWidget *widget, 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); } @@ -1307,14 +1356,15 @@ pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) 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); + plug = _gtk_win32_embed_widget_new (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); @@ -1325,7 +1375,7 @@ pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) } 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); @@ -1335,7 +1385,7 @@ pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam) } 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), @@ -1356,45 +1406,49 @@ create_application_page (GtkPrintOperation *op) 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); @@ -1439,10 +1493,157 @@ create_page_setup (GtkPrintOperation *op) } GtkPrintOperationResult -_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, - gboolean show_dialog, - GtkWindow *parent, - gboolean *do_print) +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; @@ -1475,14 +1676,14 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, if (!printdlgex) { result = GTK_PRINT_OPERATION_RESULT_ERROR; - g_set_error (&priv->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; @@ -1498,10 +1699,10 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, if (!page_ranges) { result = GTK_PRINT_OPERATION_RESULT_ERROR; - g_set_error (&priv->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; } @@ -1538,7 +1739,7 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, 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); @@ -1546,30 +1747,30 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, { result = GTK_PRINT_OPERATION_RESULT_ERROR; if (hResult == E_OUTOFMEMORY) - g_set_error (&priv->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 (&priv->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 (&priv->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 (&priv->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 (&priv->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; } @@ -1597,30 +1798,33 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, *do_print = TRUE; - op_win32->surface = cairo_win32_surface_create (printdlgex->hDC); + op_win32->surface = cairo_win32_printing_surface_create (printdlgex->hDC); + 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); - - memset( &docinfo, 0, sizeof (DOCINFOW)); + + 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 (&priv->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_win32->surface); op_win32->surface = NULL; @@ -1643,6 +1847,8 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, 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; @@ -1650,11 +1856,14 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, 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); @@ -1668,6 +1877,18 @@ _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, return result; } +GtkPrintOperationResult +_gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op, + gboolean show_dialog, + GtkWindow *parent, + gboolean *do_print) +{ + if (show_dialog) + return gtk_print_operation_run_with_dialog (op, parent, do_print); + else + return gtk_print_operation_run_without_dialog (op, do_print); +} + void _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op, cairo_surface_t *surface, @@ -1699,10 +1920,13 @@ _gtk_print_operation_platform_backend_preview_end_page (GtkPrintOperation *op, cairo_surface_t *surface, cairo_t *cr) { - /* TODO: This doesn't actually seem to work. - * Do enhanced metafiles really support multiple pages? + HDC dc; + + cairo_surface_show_page (surface); + + /* TODO: Enhanced metafiles don't support multiple pages. */ - HDC dc = cairo_win32_surface_get_dc (surface); + dc = cairo_win32_surface_get_dc (surface); EndPage (dc); } @@ -1714,7 +1938,6 @@ _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation gchar **target) { GtkPaperSize *paper_size; - double w, h; HDC metafile_dc; RECT rect; char *template; @@ -1724,7 +1947,7 @@ _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation template = g_build_filename (g_get_tmp_dir (), "prXXXXXX", NULL); fd = g_mkstemp (template); - close(fd); + close (fd); filename = g_strconcat (template, ".emf", NULL); g_free (template); @@ -1733,13 +1956,12 @@ _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation g_free (filename); paper_size = gtk_page_setup_get_paper_size (page_setup); - w = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM); - h = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM); - + + /* The rectangle dimensions are given in hundredths of a millimeter */ rect.left = 0; - rect.right = w*100; + rect.right = 100.0 * gtk_paper_size_get_width (paper_size, GTK_UNIT_MM); rect.top = 0; - rect.bottom = h*100; + 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"); @@ -1754,7 +1976,7 @@ _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *dpi_x = (double)GetDeviceCaps (metafile_dc, LOGPIXELSX); *dpi_y = (double)GetDeviceCaps (metafile_dc, LOGPIXELSY); - return cairo_win32_surface_create (metafile_dc); + return cairo_win32_printing_surface_create (metafile_dc); } void @@ -1792,7 +2014,7 @@ gtk_print_run_page_setup_dialog (GtkWindow *parent, memset (pagesetupdlg, 0, sizeof (PAGESETUPDLGW)); - pagesetupdlg->lStructSize = sizeof(PAGESETUPDLGW); + pagesetupdlg->lStructSize = sizeof (PAGESETUPDLGW); if (parent != NULL) pagesetupdlg->hwndOwner = get_parent_hwnd (GTK_WIDGET (parent)); @@ -1804,10 +2026,10 @@ gtk_print_run_page_setup_dialog (GtkWindow *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) { @@ -1855,9 +2077,6 @@ gtk_print_run_page_setup_dialog (GtkWindow *parent, devmode_to_settings (settings, pagesetupdlg->hDevMode); } - if (free_settings) - g_object_unref (settings); - if (res) { gtk_page_setup_set_orientation (page_setup, @@ -1894,6 +2113,9 @@ gtk_print_run_page_setup_dialog (GtkWindow *parent, unit); } + if (free_settings) + g_object_unref (settings); + return page_setup; }