2161 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
			
		
		
	
	
			2161 lines
		
	
	
		
			60 KiB
		
	
	
	
		
			C
		
	
	
	
	
	
| /* GTK - The GIMP Toolkit
 | |
|  * gtkprintoperation-win32.c: Print Operation Details for Win32
 | |
|  * Copyright (C) 2006, Red Hat, Inc.
 | |
|  *
 | |
|  * This library is free software; you can redistribute it and/or
 | |
|  * modify it under the terms of the GNU Lesser General Public
 | |
|  * License as published by the Free Software Foundation; either
 | |
|  * version 2 of the License, or (at your option) any later version.
 | |
|  *
 | |
|  * This library is distributed in the hope that it will be useful,
 | |
|  * but WITHOUT ANY WARRANTY; without even the implied warranty of
 | |
|  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
 | |
|  * 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, see <http://www.gnu.org/licenses/>.
 | |
|  */
 | |
| 
 | |
| #ifndef _MSC_VER
 | |
| #ifndef _WIN32_WINNT
 | |
| #define _WIN32_WINNT 0x0500
 | |
| #endif
 | |
| #ifndef WINVER
 | |
| #define WINVER _WIN32_WINNT
 | |
| #endif
 | |
| #endif
 | |
| 
 | |
| #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 "gtkprint-win32.h"
 | |
| #include "gtkintl.h"
 | |
| #include "gtkinvisible.h"
 | |
| #include "gtkplug.h"
 | |
| #include "gtk.h"
 | |
| #include "gtkwin32embedwidget.h"
 | |
| #include "gtkprivate.h"
 | |
| 
 | |
| #define MAX_PAGE_RANGES 20
 | |
| #define STATUS_POLLING_TIME 2000
 | |
| 
 | |
| #ifndef JOB_STATUS_RESTART
 | |
| #define JOB_STATUS_RESTART 0x800
 | |
| #endif
 | |
| 
 | |
| #ifndef JOB_STATUS_COMPLETE
 | |
| #define JOB_STATUS_COMPLETE 0x1000
 | |
| #endif
 | |
| 
 | |
| typedef struct {
 | |
|   HDC hdc;
 | |
|   HGLOBAL devmode;
 | |
|   HGLOBAL devnames;
 | |
|   HANDLE printerHandle;
 | |
|   int job_id;
 | |
|   guint timeout_id;
 | |
| 
 | |
|   cairo_surface_t *surface;
 | |
|   GtkWidget *embed_widget;
 | |
| } GtkPrintOperationWin32;
 | |
| 
 | |
| static void win32_poll_status (GtkPrintOperation *op);
 | |
| 
 | |
| static const GUID myIID_IPrintDialogCallback  = {0x5852a2c3,0x6530,0x11d1,{0xb6,0xa3,0x0,0x0,0xf8,0x75,0x7b,0xf9}};
 | |
| 
 | |
| #if !defined (_MSC_VER) && !defined (HAVE_IPRINTDIALOGCALLBACK)
 | |
| #undef INTERFACE
 | |
| #define INTERFACE IPrintDialogCallback
 | |
| DECLARE_INTERFACE_ (IPrintDialogCallback, IUnknown)
 | |
| {
 | |
|     STDMETHOD (QueryInterface)(THIS_ REFIID,LPVOID*) PURE;
 | |
|     STDMETHOD_ (ULONG, AddRef)(THIS) PURE;
 | |
|     STDMETHOD_ (ULONG, Release)(THIS) PURE;
 | |
|     STDMETHOD (InitDone)(THIS) PURE;
 | |
|     STDMETHOD (SelectionChange)(THIS) PURE;
 | |
|     STDMETHOD (HandleMessage)(THIS_ HWND,UINT,WPARAM,LPARAM,LRESULT*) PURE;
 | |
| }; 
 | |
| #endif
 | |
| 
 | |
| static UINT got_gdk_events_message;
 | |
| 
 | |
| UINT_PTR CALLBACK
 | |
| run_mainloop_hook (HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
 | |
| {
 | |
|   if (uiMsg == WM_INITDIALOG)
 | |
|     {
 | |
|       gdk_win32_set_modal_dialog_libgtk_only (hdlg);
 | |
|       while (gtk_events_pending ())
 | |
| 	gtk_main_iteration ();
 | |
|     }
 | |
|   else if (uiMsg == got_gdk_events_message)
 | |
|     {
 | |
|       while (gtk_events_pending ())
 | |
| 	gtk_main_iteration ();
 | |
|       return 1;
 | |
|     }
 | |
|   return 0;
 | |
| }
 | |
| 
 | |
| static GtkPageOrientation
 | |
| orientation_from_win32 (short orientation)
 | |
| {
 | |
|   if (orientation == DMORIENT_LANDSCAPE)
 | |
|     return GTK_PAGE_ORIENTATION_LANDSCAPE;
 | |
|   return GTK_PAGE_ORIENTATION_PORTRAIT;
 | |
| }
 | |
| 
 | |
| static short
 | |
| orientation_to_win32 (GtkPageOrientation orientation)
 | |
| {
 | |
|   if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE ||
 | |
|       orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
 | |
|     return DMORIENT_LANDSCAPE;
 | |
|   return DMORIENT_PORTRAIT;
 | |
| }
 | |
| 
 | |
| static GtkPaperSize *
 | |
| paper_size_from_win32 (short size)
 | |
| {
 | |
|   const char *name;
 | |
|   
 | |
|   switch (size)
 | |
|     {
 | |
|     case DMPAPER_LETTER_TRANSVERSE:
 | |
|     case DMPAPER_LETTER:
 | |
|     case DMPAPER_LETTERSMALL:
 | |
|       name = "na_letter";
 | |
|       break;
 | |
|     case DMPAPER_TABLOID:
 | |
|     case DMPAPER_LEDGER:
 | |
|       name = "na_ledger";
 | |
|       break;
 | |
|     case DMPAPER_LEGAL:
 | |
|       name = "na_legal";
 | |
|       break;
 | |
|     case DMPAPER_STATEMENT:
 | |
|       name = "na_invoice";
 | |
|       break;
 | |
|     case DMPAPER_EXECUTIVE:
 | |
|       name = "na_executive";
 | |
|       break;
 | |
|     case DMPAPER_A3:
 | |
|     case DMPAPER_A3_TRANSVERSE:
 | |
|       name = "iso_a3";
 | |
|       break;
 | |
|     case DMPAPER_A4:
 | |
|     case DMPAPER_A4SMALL:
 | |
|     case DMPAPER_A4_TRANSVERSE:
 | |
|       name = "iso_a4";
 | |
|       break;
 | |
|     case DMPAPER_A5:
 | |
|     case DMPAPER_A5_TRANSVERSE:
 | |
|       name = "iso_a5";
 | |
|       break;
 | |
|     case DMPAPER_B4:
 | |
|       name = "jis_b4";
 | |
|       break;
 | |
|     case DMPAPER_B5:
 | |
|     case DMPAPER_B5_TRANSVERSE:
 | |
|       name = "jis_b5";
 | |
|       break;
 | |
|     case DMPAPER_QUARTO:
 | |
|       name = "na_quarto";
 | |
|       break;
 | |
|     case DMPAPER_10X14:
 | |
|       name = "na_10x14";
 | |
|       break;
 | |
|     case DMPAPER_11X17:
 | |
|       name = "na_ledger";
 | |
|       break;
 | |
|     case DMPAPER_NOTE:
 | |
|       name = "na_letter";
 | |
|       break;
 | |
|     case DMPAPER_ENV_9:
 | |
|       name = "na_number-9";
 | |
|       break;
 | |
|     case DMPAPER_ENV_10:
 | |
|       name = "na_number-10";
 | |
|       break;
 | |
|     case DMPAPER_ENV_11:
 | |
|       name = "na_number-11";
 | |
|       break;
 | |
|     case DMPAPER_ENV_12:
 | |
|       name = "na_number-12";
 | |
|       break;
 | |
|     case DMPAPER_ENV_14:
 | |
|       name = "na_number-14";
 | |
|       break;
 | |
|     case DMPAPER_CSHEET:
 | |
|       name = "na_c";
 | |
|       break;
 | |
|     case DMPAPER_DSHEET:
 | |
|       name = "na_d";
 | |
|       break;
 | |
|     case DMPAPER_ESHEET:
 | |
|       name = "na_e";
 | |
|       break;
 | |
|     case DMPAPER_ENV_DL:
 | |
|       name = "iso_dl";
 | |
|       break;
 | |
|     case DMPAPER_ENV_C5:
 | |
|       name = "iso_c5";
 | |
|       break;
 | |
|     case DMPAPER_ENV_C3:
 | |
|       name = "iso_c3";
 | |
|       break;
 | |
|     case DMPAPER_ENV_C4:
 | |
|       name = "iso_c4";
 | |
|       break;
 | |
|     case DMPAPER_ENV_C6:
 | |
|       name = "iso_c6";
 | |
|       break;
 | |
|     case DMPAPER_ENV_C65:
 | |
|       name = "iso_c6c5";
 | |
|       break;
 | |
|     case DMPAPER_ENV_B4:
 | |
|       name = "iso_b4";
 | |
|       break;
 | |
|     case DMPAPER_ENV_B5:
 | |
|       name = "iso_b5";
 | |
|       break;
 | |
|     case DMPAPER_ENV_B6:
 | |
|       name = "iso_b6";
 | |
|       break;
 | |
|     case DMPAPER_ENV_ITALY:
 | |
|       name = "om_italian";
 | |
|       break;
 | |
|     case DMPAPER_ENV_MONARCH:
 | |
|       name = "na_monarch";
 | |
|       break;
 | |
|     case DMPAPER_ENV_PERSONAL:
 | |
|       name = "na_personal";
 | |
|       break;
 | |
|     case DMPAPER_FANFOLD_US:
 | |
|       name = "na_fanfold-us";
 | |
|       break;
 | |
|     case DMPAPER_FANFOLD_STD_GERMAN:
 | |
|       name = "na_fanfold-eur";
 | |
|       break;
 | |
|     case DMPAPER_FANFOLD_LGL_GERMAN:
 | |
|       name = "na_foolscap";
 | |
|       break;
 | |
|     case DMPAPER_ISO_B4:
 | |
|       name = "iso_b4";
 | |
|       break;
 | |
|     case DMPAPER_JAPANESE_POSTCARD:
 | |
|       name = "jpn_hagaki";
 | |
|       break;
 | |
|     case DMPAPER_9X11:
 | |
|       name = "na_9x11";
 | |
|       break;
 | |
|     case DMPAPER_10X11:
 | |
|       name = "na_10x11";
 | |
|       break;
 | |
|     case DMPAPER_ENV_INVITE:
 | |
|       name = "om_invite";
 | |
|        break;
 | |
|     case DMPAPER_LETTER_EXTRA:
 | |
|     case DMPAPER_LETTER_EXTRA_TRANSVERSE:
 | |
|       name = "na_letter-extra";
 | |
|       break;
 | |
|     case DMPAPER_LEGAL_EXTRA:
 | |
|       name = "na_legal-extra";
 | |
|       break;
 | |
|     case DMPAPER_TABLOID_EXTRA:
 | |
|       name = "na_arch";
 | |
|       break;
 | |
|     case DMPAPER_A4_EXTRA:
 | |
|       name = "iso_a4-extra";
 | |
|       break;
 | |
|     case DMPAPER_B_PLUS:
 | |
|       name = "na_b-plus";
 | |
|       break;
 | |
|     case DMPAPER_LETTER_PLUS:
 | |
|       name = "na_letter-plus";
 | |
|       break;
 | |
|     case DMPAPER_A3_EXTRA:
 | |
|     case DMPAPER_A3_EXTRA_TRANSVERSE:
 | |
|       name = "iso_a3-extra";
 | |
|       break;
 | |
|     case DMPAPER_A5_EXTRA:
 | |
|       name = "iso_a5-extra";
 | |
|       break;
 | |
|     case DMPAPER_B5_EXTRA:
 | |
|       name = "iso_b5-extra";
 | |
|       break;
 | |
|     case DMPAPER_A2:
 | |
|       name = "iso_a2";
 | |
|       break;
 | |
|       
 | |
|     default:
 | |
|       name = NULL;
 | |
|       break;
 | |
|     }
 | |
| 
 | |
|   if (name)
 | |
|     return gtk_paper_size_new (name);
 | |
|   else 
 | |
|     return NULL;
 | |
| }
 | |
| 
 | |
| static short
 | |
| paper_size_to_win32 (GtkPaperSize *paper_size)
 | |
| {
 | |
|   const char *format;
 | |
| 
 | |
|   if (gtk_paper_size_is_custom (paper_size))
 | |
|     return 0;
 | |
|   
 | |
|   format = gtk_paper_size_get_name (paper_size);
 | |
| 
 | |
|   if (strcmp (format, "na_letter") == 0)
 | |
|     return DMPAPER_LETTER;
 | |
|   if (strcmp (format, "na_ledger") == 0)
 | |
|     return DMPAPER_LEDGER;
 | |
|   if (strcmp (format, "na_legal") == 0)
 | |
|     return DMPAPER_LEGAL;
 | |
|   if (strcmp (format, "na_invoice") == 0)
 | |
|     return DMPAPER_STATEMENT;
 | |
|   if (strcmp (format, "na_executive") == 0)
 | |
|     return DMPAPER_EXECUTIVE;
 | |
|   if (strcmp (format, "iso_a2") == 0)
 | |
|     return DMPAPER_A2;
 | |
|   if (strcmp (format, "iso_a3") == 0)
 | |
|     return DMPAPER_A3;
 | |
|   if (strcmp (format, "iso_a4") == 0)
 | |
|     return DMPAPER_A4;
 | |
|   if (strcmp (format, "iso_a5") == 0)
 | |
|     return DMPAPER_A5;
 | |
|   if (strcmp (format, "iso_b4") == 0)
 | |
|     return DMPAPER_B4;
 | |
|   if (strcmp (format, "iso_b5") == 0)
 | |
|     return DMPAPER_B5;
 | |
|   if (strcmp (format, "na_quarto") == 0)
 | |
|     return DMPAPER_QUARTO;
 | |
|   if (strcmp (format, "na_10x14") == 0)
 | |
|     return DMPAPER_10X14;
 | |
|   if (strcmp (format, "na_number-9") == 0)
 | |
|     return DMPAPER_ENV_9;
 | |
|   if (strcmp (format, "na_number-10") == 0)
 | |
|     return DMPAPER_ENV_10;
 | |
|   if (strcmp (format, "na_number-11") == 0)
 | |
|     return DMPAPER_ENV_11;
 | |
|   if (strcmp (format, "na_number-12") == 0)
 | |
|     return DMPAPER_ENV_12;
 | |
|   if (strcmp (format, "na_number-14") == 0)
 | |
|     return DMPAPER_ENV_14;
 | |
|   if (strcmp (format, "na_c") == 0)
 | |
|     return DMPAPER_CSHEET;
 | |
|   if (strcmp (format, "na_d") == 0)
 | |
|     return DMPAPER_DSHEET;
 | |
|   if (strcmp (format, "na_e") == 0)
 | |
|     return DMPAPER_ESHEET;
 | |
|   if (strcmp (format, "iso_dl") == 0)
 | |
|     return DMPAPER_ENV_DL;
 | |
|   if (strcmp (format, "iso_c3") == 0)
 | |
|     return DMPAPER_ENV_C3;
 | |
|   if (strcmp (format, "iso_c4") == 0)
 | |
|     return DMPAPER_ENV_C4;
 | |
|   if (strcmp (format, "iso_c5") == 0)
 | |
|     return DMPAPER_ENV_C5;
 | |
|   if (strcmp (format, "iso_c6") == 0)
 | |
|     return DMPAPER_ENV_C6;
 | |
|   if (strcmp (format, "iso_c5c6") == 0)
 | |
|     return DMPAPER_ENV_C65;
 | |
|   if (strcmp (format, "iso_b6") == 0)
 | |
|     return DMPAPER_ENV_B6;
 | |
|   if (strcmp (format, "om_italian") == 0)
 | |
|     return DMPAPER_ENV_ITALY;
 | |
|   if (strcmp (format, "na_monarch") == 0)
 | |
|     return DMPAPER_ENV_MONARCH;
 | |
|   if (strcmp (format, "na_personal") == 0)
 | |
|     return DMPAPER_ENV_PERSONAL;
 | |
|   if (strcmp (format, "na_fanfold-us") == 0)
 | |
|     return DMPAPER_FANFOLD_US;
 | |
|   if (strcmp (format, "na_fanfold-eur") == 0)
 | |
|     return DMPAPER_FANFOLD_STD_GERMAN;
 | |
|   if (strcmp (format, "na_foolscap") == 0)
 | |
|     return DMPAPER_FANFOLD_LGL_GERMAN;
 | |
|   if (strcmp (format, "jpn_hagaki") == 0)
 | |
|     return DMPAPER_JAPANESE_POSTCARD;
 | |
|   if (strcmp (format, "na_9x11") == 0)
 | |
|     return DMPAPER_9X11;
 | |
|   if (strcmp (format, "na_10x11") == 0)
 | |
|     return DMPAPER_10X11;
 | |
|   if (strcmp (format, "om_invite") == 0)
 | |
|     return DMPAPER_ENV_INVITE;
 | |
|   if (strcmp (format, "na_letter-extra") == 0)
 | |
|     return DMPAPER_LETTER_EXTRA;
 | |
|   if (strcmp (format, "na_legal-extra") == 0)
 | |
|     return DMPAPER_LEGAL_EXTRA;
 | |
|   if (strcmp (format, "na_arch") == 0)
 | |
|     return DMPAPER_TABLOID_EXTRA;
 | |
|   if (strcmp (format, "iso_a3-extra") == 0)
 | |
|     return DMPAPER_A3_EXTRA;
 | |
|   if (strcmp (format, "iso_a4-extra") == 0)
 | |
|     return DMPAPER_A4_EXTRA;
 | |
|   if (strcmp (format, "iso_a5-extra") == 0)
 | |
|     return DMPAPER_A5_EXTRA;
 | |
|   if (strcmp (format, "iso_b5-extra") == 0)
 | |
|     return DMPAPER_B5_EXTRA;
 | |
|   if (strcmp (format, "na_b-plus") == 0)
 | |
|     return DMPAPER_B_PLUS;
 | |
|   if (strcmp (format, "na_letter-plus") == 0)
 | |
|     return DMPAPER_LETTER_PLUS;
 | |
| 
 | |
|   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,
 | |
| 		  GtkPageSetup *page_setup)
 | |
| {
 | |
|   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
 | |
|   LPDEVMODEW devmode;
 | |
|   GtkPaperSize *paper_size;
 | |
|   double x_off, y_off;
 | |
| 
 | |
|   devmode = GlobalLock (op_win32->devmode);
 | |
|   
 | |
|   devmode->dmFields |= DM_ORIENTATION;
 | |
|   devmode->dmOrientation =
 | |
|     orientation_to_win32 (gtk_page_setup_get_orientation (page_setup));
 | |
|   
 | |
|   paper_size = gtk_page_setup_get_paper_size (page_setup);
 | |
|   devmode->dmFields |= DM_PAPERSIZE;
 | |
|   devmode->dmFields &= ~(DM_PAPERWIDTH | DM_PAPERLENGTH);
 | |
|   devmode->dmPaperSize = paper_size_to_win32 (paper_size);
 | |
|   if (devmode->dmPaperSize == 0)
 | |
|     {
 | |
|       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);
 | |
| }
 | |
| 
 | |
| static void
 | |
| 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);
 | |
| }
 | |
| 
 | |
| static gboolean
 | |
| win32_poll_status_timeout (GtkPrintOperation *op)
 | |
| {
 | |
|   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
 | |
|   
 | |
|   op_win32->timeout_id = 0;
 | |
|   /* We need to ref this, as setting the status to finished
 | |
|      might unref the object */
 | |
|   g_object_ref (op);
 | |
|   win32_poll_status (op);
 | |
| 
 | |
|   if (!gtk_print_operation_is_finished (op)) {
 | |
|     op_win32->timeout_id = gdk_threads_add_timeout (STATUS_POLLING_TIME,
 | |
| 					  (GSourceFunc)win32_poll_status_timeout,
 | |
| 					  op);
 | |
|     g_source_set_name_by_id (op_win32->timeout_id, "[gtk+] win32_poll_status_timeout");
 | |
|   }
 | |
|   g_object_unref (op);
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| 
 | |
| static void
 | |
| win32_end_run (GtkPrintOperation *op,
 | |
| 	       gboolean           wait,
 | |
| 	       gboolean           cancelled)
 | |
| {
 | |
|   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
 | |
|   LPDEVNAMES devnames;
 | |
|   HANDLE printerHandle = 0;
 | |
| 
 | |
|   cairo_surface_finish (op_win32->surface);
 | |
|   
 | |
|   EndDoc (op_win32->hdc);
 | |
| 
 | |
|   if (op->priv->track_print_status)
 | |
|     {
 | |
|       devnames = GlobalLock (op_win32->devnames);
 | |
|       if (!OpenPrinterW (((gunichar2 *)devnames) + devnames->wDeviceOffset,
 | |
| 			 &printerHandle, NULL))
 | |
| 	printerHandle = 0;
 | |
|       GlobalUnlock (op_win32->devnames);
 | |
|     }
 | |
|   
 | |
|   GlobalFree (op_win32->devmode);
 | |
|   GlobalFree (op_win32->devnames);
 | |
| 
 | |
|   cairo_surface_destroy (op_win32->surface);
 | |
|   op_win32->surface = NULL;
 | |
| 
 | |
|   DeleteDC (op_win32->hdc);
 | |
|   
 | |
|   if (printerHandle != 0)
 | |
|     {
 | |
|       op_win32->printerHandle = printerHandle;
 | |
|       win32_poll_status (op);
 | |
|       op_win32->timeout_id = gdk_threads_add_timeout (STATUS_POLLING_TIME,
 | |
| 					    (GSourceFunc)win32_poll_status_timeout,
 | |
| 					    op);
 | |
|       g_source_set_name_by_id (op_win32->timeout_id, "[gtk+] win32_poll_status_timeout");
 | |
|     }
 | |
|   else
 | |
|     /* Dunno what happened, pretend its finished */
 | |
|     _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
 | |
| }
 | |
| 
 | |
| static void
 | |
| win32_poll_status (GtkPrintOperation *op)
 | |
| {
 | |
|   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
 | |
|   guchar *data;
 | |
|   DWORD needed;
 | |
|   JOB_INFO_1W *job_info;
 | |
|   GtkPrintStatus status;
 | |
|   char *status_str;
 | |
|   BOOL ret;
 | |
| 
 | |
|   GetJobW (op_win32->printerHandle, op_win32->job_id,
 | |
| 	   1,(LPBYTE)NULL, 0, &needed);
 | |
|   data = g_malloc (needed);
 | |
|   ret = GetJobW (op_win32->printerHandle, op_win32->job_id,
 | |
| 		 1, (LPBYTE)data, needed, &needed);
 | |
| 
 | |
|   status_str = NULL;
 | |
|   if (ret)
 | |
|     {
 | |
|       DWORD win32_status;
 | |
|       job_info = (JOB_INFO_1W *)data;
 | |
|       win32_status = job_info->Status;
 | |
| 
 | |
|       if (job_info->pStatus)
 | |
| 	status_str = g_utf16_to_utf8 (job_info->pStatus, 
 | |
| 				      -1, NULL, NULL, NULL);
 | |
|      
 | |
|       if (win32_status &
 | |
| 	  (JOB_STATUS_COMPLETE | JOB_STATUS_PRINTED))
 | |
| 	status = GTK_PRINT_STATUS_FINISHED;
 | |
|       else if (win32_status &
 | |
| 	       (JOB_STATUS_OFFLINE |
 | |
| 		JOB_STATUS_PAPEROUT |
 | |
| 		JOB_STATUS_PAUSED |
 | |
| 		JOB_STATUS_USER_INTERVENTION))
 | |
| 	{
 | |
| 	  status = GTK_PRINT_STATUS_PENDING_ISSUE;
 | |
| 	  if (status_str == NULL)
 | |
| 	    {
 | |
| 	      if (win32_status & JOB_STATUS_OFFLINE)
 | |
| 		status_str = g_strdup (_("Printer offline"));
 | |
| 	      else if (win32_status & JOB_STATUS_PAPEROUT)
 | |
| 		status_str = g_strdup (_("Out of paper"));
 | |
| 	      else if (win32_status & JOB_STATUS_PAUSED)
 | |
| 		status_str = g_strdup (_("Paused"));
 | |
| 	      else if (win32_status & JOB_STATUS_USER_INTERVENTION)
 | |
| 		status_str = g_strdup (_("Need user intervention"));
 | |
| 	    }
 | |
| 	}
 | |
|       else if (win32_status &
 | |
| 	       (JOB_STATUS_BLOCKED_DEVQ |
 | |
| 		JOB_STATUS_DELETED |
 | |
| 		JOB_STATUS_ERROR))
 | |
| 	status = GTK_PRINT_STATUS_FINISHED_ABORTED;
 | |
|       else if (win32_status &
 | |
| 	       (JOB_STATUS_SPOOLING |
 | |
| 		JOB_STATUS_DELETING))
 | |
| 	status = GTK_PRINT_STATUS_PENDING;
 | |
|       else if (win32_status & JOB_STATUS_PRINTING)
 | |
| 	status = GTK_PRINT_STATUS_PRINTING;
 | |
|       else
 | |
| 	status = GTK_PRINT_STATUS_FINISHED;
 | |
|     }
 | |
|   else
 | |
|     status = GTK_PRINT_STATUS_FINISHED;
 | |
| 
 | |
|   g_free (data);
 | |
| 
 | |
|   _gtk_print_operation_set_status (op, status, status_str);
 | |
|  
 | |
|   g_free (status_str);
 | |
| }
 | |
| 
 | |
| static void
 | |
| op_win32_free (GtkPrintOperationWin32 *op_win32)
 | |
| {
 | |
|   if (op_win32->printerHandle)
 | |
|     ClosePrinter (op_win32->printerHandle);
 | |
|   if (op_win32->timeout_id != 0)
 | |
|     g_source_remove (op_win32->timeout_id);
 | |
|   g_free (op_win32);
 | |
| }
 | |
| 
 | |
| static HWND
 | |
| get_parent_hwnd (GtkWidget *widget)
 | |
| {
 | |
|   gtk_widget_realize (widget);
 | |
|   return gdk_win32_window_get_handle (gtk_widget_get_window (widget));
 | |
| }
 | |
| 
 | |
| static void
 | |
| devnames_to_settings (GtkPrintSettings *settings,
 | |
| 		      HANDLE hDevNames)
 | |
| {
 | |
|   GtkPrintWin32Devnames *devnames = gtk_print_win32_devnames_from_win32 (hDevNames);
 | |
|   gtk_print_settings_set_printer (settings, devnames->device);
 | |
|   gtk_print_win32_devnames_free (devnames);
 | |
| }
 | |
| 
 | |
| static void
 | |
| devmode_to_settings (GtkPrintSettings *settings,
 | |
| 		     HANDLE hDevMode)
 | |
| {
 | |
|   LPDEVMODEW devmode;
 | |
| 
 | |
|   devmode = GlobalLock (hDevMode);
 | |
|   
 | |
|   gtk_print_settings_set_int (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION,
 | |
| 			      devmode->dmDriverVersion);
 | |
|   if (devmode->dmDriverExtra != 0)
 | |
|     {
 | |
|       char *extra = g_base64_encode (((const guchar *)devmode) + sizeof (DEVMODEW),
 | |
| 				     devmode->dmDriverExtra);
 | |
|       gtk_print_settings_set (settings,
 | |
| 			      GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA,
 | |
| 			      extra);
 | |
|       g_free (extra);
 | |
|     }
 | |
|   
 | |
|   if (devmode->dmFields & DM_ORIENTATION)
 | |
|     gtk_print_settings_set_orientation (settings,
 | |
| 					orientation_from_win32 (devmode->dmOrientation));
 | |
|   
 | |
|   
 | |
|   if (devmode->dmFields & DM_PAPERSIZE &&
 | |
|       devmode->dmPaperSize != 0)
 | |
|     {
 | |
|       GtkPaperSize *paper_size = paper_size_from_win32 (devmode->dmPaperSize);
 | |
|       if (paper_size)
 | |
| 	{
 | |
| 	  gtk_print_settings_set_paper_size (settings, paper_size);
 | |
| 	  gtk_paper_size_free (paper_size);
 | |
| 	}
 | |
|       gtk_print_settings_set_int (settings, "win32-paper-size", (int)devmode->dmPaperSize);
 | |
|     }
 | |
|   else if ((devmode->dmFields & DM_PAPERSIZE &&
 | |
| 	    devmode->dmPaperSize == 0) ||
 | |
| 	   ((devmode->dmFields & DM_PAPERWIDTH) &&
 | |
| 	    (devmode->dmFields & DM_PAPERLENGTH)))
 | |
|     {
 | |
|       GtkPaperSize *paper_size;
 | |
|       char *form_name = NULL;
 | |
|       if (devmode->dmFields & DM_FORMNAME)
 | |
| 	form_name = g_utf16_to_utf8 (devmode->dmFormName, 
 | |
| 				     -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,
 | |
| 					      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);
 | |
|   
 | |
|   if (devmode->dmFields & DM_COPIES)
 | |
|     gtk_print_settings_set_n_copies (settings,
 | |
| 				     devmode->dmCopies);
 | |
|   
 | |
|   if (devmode->dmFields & DM_DEFAULTSOURCE)
 | |
|     {
 | |
|       char *source;
 | |
|       switch (devmode->dmDefaultSource)
 | |
| 	{
 | |
| 	default:
 | |
| 	case DMBIN_AUTO:
 | |
| 	  source = "auto";
 | |
| 	  break;
 | |
| 	case DMBIN_CASSETTE:
 | |
| 	  source = "cassette";
 | |
| 	  break;
 | |
| 	case DMBIN_ENVELOPE:
 | |
| 	  source = "envelope";
 | |
| 	  break;
 | |
| 	case DMBIN_ENVMANUAL:
 | |
| 	  source = "envelope-manual";
 | |
| 	  break;
 | |
| 	case DMBIN_LOWER:
 | |
| 	  source = "lower";
 | |
| 	  break;
 | |
| 	case DMBIN_MANUAL:
 | |
| 	  source = "manual";
 | |
| 	  break;
 | |
| 	case DMBIN_MIDDLE:
 | |
| 	  source = "middle";
 | |
| 	  break;
 | |
| 	case DMBIN_ONLYONE:
 | |
| 	  source = "only-one";
 | |
| 	  break;
 | |
| 	case DMBIN_FORMSOURCE:
 | |
| 	  source = "form-source";
 | |
| 	  break;
 | |
| 	case DMBIN_LARGECAPACITY:
 | |
| 	  source = "large-capacity";
 | |
| 	  break;
 | |
| 	case DMBIN_LARGEFMT:
 | |
| 	  source = "large-format";
 | |
| 	  break;
 | |
| 	case DMBIN_TRACTOR:
 | |
| 	  source = "tractor";
 | |
| 	  break;
 | |
| 	case DMBIN_SMALLFMT:
 | |
| 	  source = "small-format";
 | |
| 	  break;
 | |
| 	}
 | |
|       gtk_print_settings_set_default_source (settings, source);
 | |
|       gtk_print_settings_set_int (settings, "win32-default-source", devmode->dmDefaultSource);
 | |
|     }
 | |
|   
 | |
|   if (devmode->dmFields & DM_PRINTQUALITY)
 | |
|     {
 | |
|       GtkPrintQuality quality;
 | |
|       switch (devmode->dmPrintQuality)
 | |
| 	{
 | |
| 	case DMRES_LOW:
 | |
| 	  quality = GTK_PRINT_QUALITY_LOW;
 | |
| 	  break;
 | |
| 	case DMRES_MEDIUM:
 | |
| 	  quality = GTK_PRINT_QUALITY_NORMAL;
 | |
| 	  break;
 | |
| 	default:
 | |
| 	case DMRES_HIGH:
 | |
| 	  quality = GTK_PRINT_QUALITY_HIGH;
 | |
| 	  break;
 | |
| 	case DMRES_DRAFT:
 | |
| 	  quality = GTK_PRINT_QUALITY_DRAFT;
 | |
| 	  break;
 | |
| 	}
 | |
|       gtk_print_settings_set_quality (settings, quality);
 | |
|       gtk_print_settings_set_int (settings, "win32-print-quality", devmode->dmPrintQuality);
 | |
|     }
 | |
|   
 | |
|   if (devmode->dmFields & DM_COLOR)
 | |
|     gtk_print_settings_set_use_color (settings, devmode->dmColor == DMCOLOR_COLOR);
 | |
|   
 | |
|   if (devmode->dmFields & DM_DUPLEX)
 | |
|     {
 | |
|       GtkPrintDuplex duplex;
 | |
|       switch (devmode->dmDuplex)
 | |
| 	{
 | |
| 	default:
 | |
| 	case DMDUP_SIMPLEX:
 | |
| 	  duplex = GTK_PRINT_DUPLEX_SIMPLEX;
 | |
| 	  break;
 | |
| 	case DMDUP_HORIZONTAL:
 | |
| 	  duplex = GTK_PRINT_DUPLEX_HORIZONTAL;
 | |
| 	  break;
 | |
| 	case DMDUP_VERTICAL:
 | |
| 	  duplex = GTK_PRINT_DUPLEX_VERTICAL;
 | |
| 	  break;
 | |
| 	}
 | |
|       
 | |
|       gtk_print_settings_set_duplex (settings, duplex);
 | |
|     }
 | |
|   
 | |
|   if (devmode->dmFields & DM_COLLATE)
 | |
|     gtk_print_settings_set_collate (settings,
 | |
| 				    devmode->dmCollate == DMCOLLATE_TRUE);
 | |
|   
 | |
|   if (devmode->dmFields & DM_MEDIATYPE)
 | |
|     {
 | |
|       char *media_type;
 | |
|       switch (devmode->dmMediaType)
 | |
| 	{
 | |
| 	default:
 | |
| 	case DMMEDIA_STANDARD:
 | |
| 	  media_type = "stationery";
 | |
| 	  break;
 | |
| 	case DMMEDIA_TRANSPARENCY:
 | |
| 	  media_type = "transparency";
 | |
| 	  break;
 | |
| 	case DMMEDIA_GLOSSY:
 | |
| 	  media_type = "photographic-glossy";
 | |
| 	  break;
 | |
| 	}
 | |
|       gtk_print_settings_set_media_type (settings, media_type);
 | |
|       gtk_print_settings_set_int (settings, "win32-media-type", devmode->dmMediaType);
 | |
|     }
 | |
|   
 | |
|   if (devmode->dmFields & DM_DITHERTYPE)
 | |
|     {
 | |
|       char *dither;
 | |
|       switch (devmode->dmDitherType)
 | |
| 	{
 | |
| 	default:
 | |
| 	case DMDITHER_FINE:
 | |
| 	  dither = "fine";
 | |
| 	  break;
 | |
| 	case DMDITHER_NONE:
 | |
| 	  dither = "none";
 | |
| 	  break;
 | |
| 	case DMDITHER_COARSE:
 | |
| 	  dither = "coarse";
 | |
| 	  break;
 | |
| 	case DMDITHER_LINEART:
 | |
| 	  dither = "lineart";
 | |
| 	  break;
 | |
| 	case DMDITHER_GRAYSCALE:
 | |
| 	  dither = "grayscale";
 | |
| 	  break;
 | |
| 	case DMDITHER_ERRORDIFFUSION:
 | |
| 	  dither = "error-diffusion";
 | |
| 	  break;
 | |
| 	}
 | |
|       gtk_print_settings_set_dither (settings, dither);
 | |
|       gtk_print_settings_set_int (settings, "win32-dither-type", devmode->dmDitherType);
 | |
|     }
 | |
|   
 | |
|   GlobalUnlock (hDevMode);
 | |
| }
 | |
| 
 | |
| static void
 | |
| dialog_to_print_settings (GtkPrintOperation *op,
 | |
| 			  LPPRINTDLGEXW printdlgex)
 | |
| {
 | |
|   guint i;
 | |
|   GtkPrintSettings *settings;
 | |
| 
 | |
|   settings = gtk_print_settings_new ();
 | |
| 
 | |
|   gtk_print_settings_set_print_pages (settings,
 | |
| 				      GTK_PRINT_PAGES_ALL);
 | |
|   if (printdlgex->Flags & PD_CURRENTPAGE)
 | |
|     gtk_print_settings_set_print_pages (settings,
 | |
| 					GTK_PRINT_PAGES_CURRENT);
 | |
|   else if (printdlgex->Flags & PD_PAGENUMS)
 | |
|     gtk_print_settings_set_print_pages (settings,
 | |
| 					GTK_PRINT_PAGES_RANGES);
 | |
| 
 | |
|   if (printdlgex->nPageRanges > 0)
 | |
|     {
 | |
|       GtkPageRange *ranges;
 | |
|       ranges = g_new (GtkPageRange, printdlgex->nPageRanges);
 | |
| 
 | |
|       for (i = 0; i < printdlgex->nPageRanges; i++)
 | |
| 	{
 | |
| 	  ranges[i].start = printdlgex->lpPageRanges[i].nFromPage - 1;
 | |
| 	  ranges[i].end = printdlgex->lpPageRanges[i].nToPage - 1;
 | |
| 	}
 | |
| 
 | |
|       gtk_print_settings_set_page_ranges (settings, ranges,
 | |
| 					  printdlgex->nPageRanges);
 | |
|       g_free (ranges);
 | |
|     }
 | |
|   
 | |
|   if (printdlgex->hDevNames != NULL)
 | |
|     devnames_to_settings (settings, printdlgex->hDevNames);
 | |
| 
 | |
|   if (printdlgex->hDevMode != NULL)
 | |
|     devmode_to_settings (settings, printdlgex->hDevMode);
 | |
|   
 | |
|   gtk_print_operation_set_print_settings (op, settings);
 | |
| }
 | |
| 
 | |
| static HANDLE
 | |
| devmode_from_settings (GtkPrintSettings *settings,
 | |
| 		       GtkPageSetup *page_setup)
 | |
| {
 | |
|   HANDLE hDevMode;
 | |
|   LPDEVMODEW devmode;
 | |
|   guchar *extras;
 | |
|   GtkPaperSize *paper_size;
 | |
|   const char *extras_base64;
 | |
|   gsize extras_len;
 | |
|   const char *val;
 | |
| 
 | |
|   extras = NULL;
 | |
|   extras_len = 0;
 | |
|   extras_base64 = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA);
 | |
|   if (extras_base64)
 | |
|     extras = g_base64_decode (extras_base64, &extras_len);
 | |
|   
 | |
|   hDevMode = GlobalAlloc (GMEM_MOVEABLE, 
 | |
| 			  sizeof (DEVMODEW) + extras_len);
 | |
| 
 | |
|   devmode = GlobalLock (hDevMode);
 | |
| 
 | |
|   memset (devmode, 0, sizeof (DEVMODEW));
 | |
|   
 | |
|   devmode->dmSpecVersion = DM_SPECVERSION;
 | |
|   devmode->dmSize = sizeof (DEVMODEW);
 | |
|   
 | |
|   devmode->dmDriverExtra = 0;
 | |
|   if (extras && extras_len > 0)
 | |
|     {
 | |
|       devmode->dmDriverExtra = extras_len;
 | |
|       memcpy (((char *)devmode) + sizeof (DEVMODEW), extras, extras_len);
 | |
|     }
 | |
|   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);
 | |
|   
 | |
|   if (page_setup ||
 | |
|       gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
 | |
|     {
 | |
|       GtkPageOrientation orientation = gtk_print_settings_get_orientation (settings);
 | |
|       if (page_setup)
 | |
| 	orientation = gtk_page_setup_get_orientation (page_setup);
 | |
|       devmode->dmFields |= DM_ORIENTATION;
 | |
|       devmode->dmOrientation = orientation_to_win32 (orientation);
 | |
|     }
 | |
| 
 | |
|   if (page_setup)
 | |
|     paper_size = gtk_paper_size_copy (gtk_page_setup_get_paper_size (page_setup));
 | |
|   else
 | |
|     {
 | |
|       int size;
 | |
|       if (gtk_print_settings_has_key (settings, "win32-paper-size") &&
 | |
| 	  (size = gtk_print_settings_get_int (settings, "win32-paper-size")) != 0)
 | |
| 	{
 | |
| 	  devmode->dmFields |= DM_PAPERSIZE;
 | |
| 	  devmode->dmPaperSize = size;
 | |
| 	  paper_size = NULL;
 | |
| 	}
 | |
|       else
 | |
| 	paper_size = gtk_print_settings_get_paper_size (settings);
 | |
|     }
 | |
|   if (paper_size)
 | |
|     {
 | |
|       devmode->dmFields |= DM_PAPERSIZE;
 | |
|       devmode->dmPaperSize = paper_size_to_win32 (paper_size);
 | |
|       if (devmode->dmPaperSize == 0)
 | |
| 	{
 | |
| 	  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;
 | |
| 	}
 | |
|       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);
 | |
|     }
 | |
|   
 | |
|   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_N_COPIES))
 | |
|     {
 | |
|       devmode->dmFields |= DM_COPIES;
 | |
|       devmode->dmCopies = gtk_print_settings_get_n_copies (settings);
 | |
|     }
 | |
| 
 | |
|   if (gtk_print_settings_has_key (settings, "win32-default-source"))
 | |
|     {
 | |
|       devmode->dmFields |= DM_DEFAULTSOURCE;
 | |
|       devmode->dmDefaultSource = gtk_print_settings_get_int (settings, "win32-default-source");
 | |
|     }
 | |
|   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE))
 | |
|     {
 | |
|       devmode->dmFields |= DM_DEFAULTSOURCE;
 | |
|       devmode->dmDefaultSource = DMBIN_AUTO;
 | |
| 
 | |
|       val = gtk_print_settings_get_default_source (settings);
 | |
|       if (strcmp (val, "auto") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_AUTO;
 | |
|       if (strcmp (val, "cassette") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_CASSETTE;
 | |
|       if (strcmp (val, "envelope") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_ENVELOPE;
 | |
|       if (strcmp (val, "envelope-manual") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_ENVMANUAL;
 | |
|       if (strcmp (val, "lower") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_LOWER;
 | |
|       if (strcmp (val, "manual") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_MANUAL;
 | |
|       if (strcmp (val, "middle") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_MIDDLE;
 | |
|       if (strcmp (val, "only-one") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_ONLYONE;
 | |
|       if (strcmp (val, "form-source") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_FORMSOURCE;
 | |
|       if (strcmp (val, "large-capacity") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_LARGECAPACITY;
 | |
|       if (strcmp (val, "large-format") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_LARGEFMT;
 | |
|       if (strcmp (val, "tractor") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_TRACTOR;
 | |
|       if (strcmp (val, "small-format") == 0)
 | |
| 	devmode->dmDefaultSource = DMBIN_SMALLFMT;
 | |
|     }
 | |
| 
 | |
|   if (gtk_print_settings_has_key (settings, "win32-print-quality"))
 | |
|     {
 | |
|       devmode->dmFields |= DM_PRINTQUALITY;
 | |
|       devmode->dmPrintQuality = gtk_print_settings_get_int (settings, "win32-print-quality");
 | |
|     }
 | |
|   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_RESOLUTION))
 | |
|     {
 | |
|       devmode->dmFields |= DM_PRINTQUALITY;
 | |
|       devmode->dmPrintQuality = gtk_print_settings_get_resolution (settings);
 | |
|     } 
 | |
|   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_QUALITY))
 | |
|     {
 | |
|       devmode->dmFields |= DM_PRINTQUALITY;
 | |
|       switch (gtk_print_settings_get_quality (settings))
 | |
| 	{
 | |
| 	case GTK_PRINT_QUALITY_LOW:
 | |
| 	  devmode->dmPrintQuality = DMRES_LOW;
 | |
| 	  break;
 | |
| 	case GTK_PRINT_QUALITY_DRAFT:
 | |
| 	  devmode->dmPrintQuality = DMRES_DRAFT;
 | |
| 	  break;
 | |
| 	default:
 | |
| 	case GTK_PRINT_QUALITY_NORMAL:
 | |
| 	  devmode->dmPrintQuality = DMRES_MEDIUM;
 | |
| 	  break;
 | |
| 	case GTK_PRINT_QUALITY_HIGH:
 | |
| 	  devmode->dmPrintQuality = DMRES_HIGH;
 | |
| 	  break;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_USE_COLOR))
 | |
|     {
 | |
|       devmode->dmFields |= DM_COLOR;
 | |
|       if (gtk_print_settings_get_use_color (settings))
 | |
| 	devmode->dmColor = DMCOLOR_COLOR;
 | |
|       else
 | |
| 	devmode->dmColor = DMCOLOR_MONOCHROME;
 | |
|     }
 | |
| 
 | |
|   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DUPLEX))
 | |
|     {
 | |
|       devmode->dmFields |= DM_DUPLEX;
 | |
|       switch (gtk_print_settings_get_duplex (settings))
 | |
| 	{
 | |
| 	default:
 | |
| 	case GTK_PRINT_DUPLEX_SIMPLEX:
 | |
| 	  devmode->dmDuplex = DMDUP_SIMPLEX;
 | |
| 	  break;
 | |
| 	case GTK_PRINT_DUPLEX_HORIZONTAL:
 | |
| 	  devmode->dmDuplex = DMDUP_HORIZONTAL;
 | |
| 	  break;
 | |
| 	case GTK_PRINT_DUPLEX_VERTICAL:
 | |
| 	  devmode->dmDuplex = DMDUP_VERTICAL;
 | |
| 	  break;
 | |
| 	}
 | |
|     }
 | |
| 
 | |
|   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_COLLATE))
 | |
|     {
 | |
|       devmode->dmFields |= DM_COLLATE;
 | |
|       if (gtk_print_settings_get_collate (settings))
 | |
| 	devmode->dmCollate = DMCOLLATE_TRUE;
 | |
|       else
 | |
| 	devmode->dmCollate = DMCOLLATE_FALSE;
 | |
|     }
 | |
| 
 | |
|   if (gtk_print_settings_has_key (settings, "win32-media-type"))
 | |
|     {
 | |
|       devmode->dmFields |= DM_MEDIATYPE;
 | |
|       devmode->dmMediaType = gtk_print_settings_get_int (settings, "win32-media-type");
 | |
|     }
 | |
|   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_MEDIA_TYPE))
 | |
|     {
 | |
|       devmode->dmFields |= DM_MEDIATYPE;
 | |
|       devmode->dmMediaType = DMMEDIA_STANDARD;
 | |
|       
 | |
|       val = gtk_print_settings_get_media_type (settings);
 | |
|       if (strcmp (val, "transparency") == 0)
 | |
| 	devmode->dmMediaType = DMMEDIA_TRANSPARENCY;
 | |
|       if (strcmp (val, "photographic-glossy") == 0)
 | |
| 	devmode->dmMediaType = DMMEDIA_GLOSSY;
 | |
|     }
 | |
|  
 | |
|   if (gtk_print_settings_has_key (settings, "win32-dither-type"))
 | |
|     {
 | |
|       devmode->dmFields |= DM_DITHERTYPE;
 | |
|       devmode->dmDitherType = gtk_print_settings_get_int (settings, "win32-dither-type");
 | |
|     }
 | |
|   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DITHER))
 | |
|     {
 | |
|       devmode->dmFields |= DM_DITHERTYPE;
 | |
|       devmode->dmDitherType = DMDITHER_FINE;
 | |
|       
 | |
|       val = gtk_print_settings_get_dither (settings);
 | |
|       if (strcmp (val, "none") == 0)
 | |
| 	devmode->dmDitherType = DMDITHER_NONE;
 | |
|       if (strcmp (val, "coarse") == 0)
 | |
| 	devmode->dmDitherType = DMDITHER_COARSE;
 | |
|       if (strcmp (val, "fine") == 0)
 | |
| 	devmode->dmDitherType = DMDITHER_FINE;
 | |
|       if (strcmp (val, "lineart") == 0)
 | |
| 	devmode->dmDitherType = DMDITHER_LINEART;
 | |
|       if (strcmp (val, "grayscale") == 0)
 | |
| 	devmode->dmDitherType = DMDITHER_GRAYSCALE;
 | |
|       if (strcmp (val, "error-diffusion") == 0)
 | |
| 	devmode->dmDitherType = DMDITHER_ERRORDIFFUSION;
 | |
|     }
 | |
|   
 | |
|   GlobalUnlock (hDevMode);
 | |
| 
 | |
|   return hDevMode;
 | |
| }
 | |
| 
 | |
| static void
 | |
| dialog_from_print_settings (GtkPrintOperation *op,
 | |
| 			    LPPRINTDLGEXW printdlgex)
 | |
| {
 | |
|   GtkPrintSettings *settings = op->priv->print_settings;
 | |
|   const char *printer;
 | |
| 
 | |
|   if (settings == NULL)
 | |
|     return;
 | |
| 
 | |
|   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_PRINT_PAGES))
 | |
|     {
 | |
|       GtkPrintPages print_pages = gtk_print_settings_get_print_pages (settings);
 | |
| 
 | |
|       switch (print_pages)
 | |
| 	{
 | |
| 	default:
 | |
| 	case GTK_PRINT_PAGES_ALL:
 | |
| 	  printdlgex->Flags |= PD_ALLPAGES;
 | |
| 	  break;
 | |
| 	case GTK_PRINT_PAGES_CURRENT:
 | |
| 	  printdlgex->Flags |= PD_CURRENTPAGE;
 | |
| 	  break;
 | |
| 	case GTK_PRINT_PAGES_RANGES:
 | |
| 	  printdlgex->Flags |= PD_PAGENUMS;
 | |
| 	  break;
 | |
| 	}
 | |
|     }
 | |
|   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_PAGE_RANGES))
 | |
|     {
 | |
|       GtkPageRange *ranges;
 | |
|       int num_ranges, i;
 | |
| 
 | |
|       ranges = gtk_print_settings_get_page_ranges (settings, &num_ranges);
 | |
| 
 | |
|       if (num_ranges > MAX_PAGE_RANGES)
 | |
| 	num_ranges = MAX_PAGE_RANGES;
 | |
| 
 | |
|       printdlgex->nPageRanges = num_ranges;
 | |
|       for (i = 0; i < num_ranges; i++)
 | |
| 	{
 | |
| 	  printdlgex->lpPageRanges[i].nFromPage = ranges[i].start + 1;
 | |
| 	  printdlgex->lpPageRanges[i].nToPage = ranges[i].end + 1;
 | |
| 	}
 | |
|     }
 | |
|   
 | |
|   printer = gtk_print_settings_get_printer (settings);
 | |
|   if (printer)
 | |
|     printdlgex->hDevNames = gtk_print_win32_devnames_to_win32_from_printer_name (printer);
 | |
|   
 | |
|   printdlgex->hDevMode = devmode_from_settings (settings,
 | |
| 						op->priv->default_page_setup);
 | |
| }
 | |
| 
 | |
| typedef struct {
 | |
|   IPrintDialogCallback iPrintDialogCallback;
 | |
|   gboolean set_hwnd;
 | |
|   int ref_count;
 | |
| } PrintDialogCallback;
 | |
| 
 | |
| 
 | |
| static ULONG STDMETHODCALLTYPE
 | |
| iprintdialogcallback_addref (IPrintDialogCallback *This)
 | |
| {
 | |
|   PrintDialogCallback *callback = (PrintDialogCallback *)This;
 | |
|   return ++callback->ref_count;
 | |
| }
 | |
| 
 | |
| static ULONG STDMETHODCALLTYPE
 | |
| iprintdialogcallback_release (IPrintDialogCallback *This)
 | |
| {
 | |
|   PrintDialogCallback *callback = (PrintDialogCallback *)This;
 | |
|   int ref_count = --callback->ref_count;
 | |
| 
 | |
|   if (ref_count == 0)
 | |
|     g_free (This);
 | |
| 
 | |
|   return ref_count;
 | |
| }
 | |
| 
 | |
| static HRESULT STDMETHODCALLTYPE
 | |
| iprintdialogcallback_queryinterface (IPrintDialogCallback *This,
 | |
| 				     REFIID       riid,
 | |
| 				     LPVOID      *ppvObject)
 | |
| {
 | |
|    if (IsEqualIID (riid, &IID_IUnknown) ||
 | |
|        IsEqualIID (riid, &myIID_IPrintDialogCallback))
 | |
|      {
 | |
|        *ppvObject = This;
 | |
|        IUnknown_AddRef ((IUnknown *)This);
 | |
|        return NOERROR;
 | |
|      }
 | |
|    else
 | |
|      {
 | |
|        *ppvObject = NULL;
 | |
|        return E_NOINTERFACE;
 | |
|      }
 | |
| }
 | |
| 
 | |
| static HRESULT STDMETHODCALLTYPE
 | |
| iprintdialogcallback_initdone (IPrintDialogCallback *This)
 | |
| {
 | |
|   return S_FALSE;
 | |
| }
 | |
| 
 | |
| static HRESULT STDMETHODCALLTYPE
 | |
| iprintdialogcallback_selectionchange (IPrintDialogCallback *This)
 | |
| {
 | |
|   return S_FALSE;
 | |
| }
 | |
| 
 | |
| static HRESULT STDMETHODCALLTYPE
 | |
| iprintdialogcallback_handlemessage (IPrintDialogCallback *This,
 | |
| 				    HWND hDlg,
 | |
| 				    UINT uMsg,
 | |
| 				    WPARAM wParam,
 | |
| 				    LPARAM lParam,
 | |
| 				    LRESULT *pResult)
 | |
| {
 | |
|   PrintDialogCallback *callback = (PrintDialogCallback *)This;
 | |
| 
 | |
|   if (!callback->set_hwnd)
 | |
|     {
 | |
|       gdk_win32_set_modal_dialog_libgtk_only (hDlg);
 | |
|       callback->set_hwnd = TRUE;
 | |
|       while (gtk_events_pending ())
 | |
| 	gtk_main_iteration ();
 | |
|     }
 | |
|   else if (uMsg == got_gdk_events_message)
 | |
|     {
 | |
|       while (gtk_events_pending ())
 | |
| 	gtk_main_iteration ();
 | |
|       *pResult = TRUE;
 | |
|       return S_OK;
 | |
|     }
 | |
|   
 | |
|   *pResult = 0;
 | |
|   return S_FALSE;
 | |
| }
 | |
| 
 | |
| static IPrintDialogCallbackVtbl ipdc_vtbl = {
 | |
|   iprintdialogcallback_queryinterface,
 | |
|   iprintdialogcallback_addref,
 | |
|   iprintdialogcallback_release,
 | |
|   iprintdialogcallback_initdone,
 | |
|   iprintdialogcallback_selectionchange,
 | |
|   iprintdialogcallback_handlemessage
 | |
| };
 | |
| 
 | |
| static IPrintDialogCallback *
 | |
| print_callback_new  (void)
 | |
| {
 | |
|   PrintDialogCallback *callback;
 | |
| 
 | |
|   callback = g_new0 (PrintDialogCallback, 1);
 | |
|   callback->iPrintDialogCallback.lpVtbl = &ipdc_vtbl;
 | |
|   callback->ref_count = 1;
 | |
|   callback->set_hwnd = FALSE;
 | |
| 
 | |
|   return &callback->iPrintDialogCallback;
 | |
| }
 | |
| 
 | |
| static  void
 | |
| plug_grab_notify (GtkWidget        *widget,
 | |
| 		  gboolean          was_grabbed,
 | |
| 		  GtkPrintOperation *op)
 | |
| {
 | |
|   EnableWindow (GetAncestor (GDK_WINDOW_HWND (gtk_widget_get_window (widget)), GA_ROOT),
 | |
| 		was_grabbed);
 | |
| }
 | |
| 
 | |
| 
 | |
| static BOOL CALLBACK
 | |
| pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
 | |
| {
 | |
|   GtkPrintOperation *op;
 | |
|   GtkPrintOperationWin32 *op_win32;
 | |
|   
 | |
|   if (message == WM_INITDIALOG)
 | |
|     {
 | |
|       PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lparam;
 | |
|       GtkWidget *plug;
 | |
| 
 | |
|       op = GTK_PRINT_OPERATION ((gpointer)page->lParam);
 | |
|       op_win32 = op->priv->platform_data;
 | |
| 
 | |
|       SetWindowLongPtrW (wnd, GWLP_USERDATA, (LONG_PTR)op);
 | |
|       
 | |
|       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 (gtk_widget_get_window (plug), GDK_CURRENT_TIME);
 | |
| 
 | |
|       /* This dialog is modal, so we grab the embed widget */
 | |
|       gtk_grab_add (plug);
 | |
| 
 | |
|       /* When we lose the grab we need to disable the print dialog */
 | |
|       g_signal_connect (plug, "grab-notify", G_CALLBACK (plug_grab_notify), op);
 | |
|       return FALSE;
 | |
|     }
 | |
|   else if (message == WM_DESTROY)
 | |
|     {
 | |
|       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);
 | |
|       gtk_widget_destroy (op_win32->embed_widget);
 | |
|       op_win32->embed_widget = NULL;
 | |
|       op->priv->custom_widget = NULL;
 | |
|     }
 | |
|   else 
 | |
|     {
 | |
|       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),
 | |
| 						       wnd, message, wparam, lparam);
 | |
|     }
 | |
|   
 | |
|   return FALSE;
 | |
| }
 | |
| 
 | |
| static HPROPSHEETPAGE
 | |
| create_application_page (GtkPrintOperation *op)
 | |
| {
 | |
|   HPROPSHEETPAGE hpage;
 | |
|   PROPSHEETPAGEW page;
 | |
|   DLGTEMPLATE *template;
 | |
|   HGLOBAL htemplate;
 | |
|   LONG base_units;
 | |
|   WORD baseunitX, baseunitY;
 | |
|   WORD *array;
 | |
|   GtkRequisition requisition;
 | |
|   const char *tab_label;
 | |
| 
 | |
|   /* Make the template the size of the custom widget size request */
 | |
|   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);
 | |
|   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);
 | |
|   
 | |
|   array = (WORD *) (template+1);
 | |
|   *array++ = 0; /* menu */
 | |
|   *array++ = 0; /* class */
 | |
|   *array++ = 0; /* title */
 | |
|   
 | |
|   memset (&page, 0, sizeof (page));
 | |
|   page.dwSize = sizeof (page);
 | |
|   page.dwFlags = PSP_DLGINDIRECT | PSP_USETITLE | PSP_PREMATURE;
 | |
|   page.hInstance = GetModuleHandle (NULL);
 | |
|   page.pResource = template;
 | |
|   
 | |
|   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);
 | |
|   
 | |
|   GlobalUnlock (htemplate);
 | |
|   
 | |
|   /* TODO: We're leaking htemplate here... */
 | |
|   
 | |
|   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_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;
 | |
|   LPPRINTPAGERANGE page_ranges = NULL;
 | |
|   HWND parentHWnd;
 | |
|   GtkWidget *invisible = NULL;
 | |
|   GtkPrintOperationResult result;
 | |
|   GtkPrintOperationWin32 *op_win32;
 | |
|   GtkPrintOperationPrivate *priv;
 | |
|   IPrintDialogCallback *callback;
 | |
|   HPROPSHEETPAGE prop_page;
 | |
|   static volatile gsize common_controls_initialized = 0;
 | |
| 
 | |
|   if (g_once_init_enter (&common_controls_initialized))
 | |
|     {
 | |
|       BOOL initialized;
 | |
|       INITCOMMONCONTROLSEX icc;
 | |
| 
 | |
|       memset (&icc, 0, sizeof (icc));
 | |
|       icc.dwSize = sizeof (icc);
 | |
|       icc.dwICC = ICC_WIN95_CLASSES;
 | |
| 
 | |
|       initialized = InitCommonControlsEx (&icc);
 | |
|       if (!initialized)
 | |
|         g_warning ("Failed to InitCommonControlsEx: %lu\n", GetLastError ());
 | |
| 
 | |
|       _gtk_load_dll_with_libgtk3_manifest ("comdlg32.dll");
 | |
| 
 | |
|       g_once_init_leave (&common_controls_initialized, initialized ? 1 : 0);
 | |
|     }
 | |
|   
 | |
|   *do_print = FALSE;
 | |
| 
 | |
|   priv = op->priv;
 | |
|   
 | |
|   op_win32 = g_new0 (GtkPrintOperationWin32, 1);
 | |
|   priv->platform_data = op_win32;
 | |
|   priv->free_platform_data = (GDestroyNotify) op_win32_free;
 | |
|   
 | |
|   if (parent == NULL)
 | |
|     {
 | |
|       invisible = gtk_invisible_new ();
 | |
|       parentHWnd = get_parent_hwnd (invisible);
 | |
|     }
 | |
|   else 
 | |
|     parentHWnd = get_parent_hwnd (GTK_WIDGET (parent));
 | |
| 
 | |
|   printdlgex = (LPPRINTDLGEXW)GlobalAlloc (GPTR, sizeof (PRINTDLGEXW));
 | |
|   if (!printdlgex)
 | |
|     {
 | |
|       result = GTK_PRINT_OPERATION_RESULT_ERROR;
 | |
|       g_set_error_literal (&priv->error,
 | |
|                            GTK_PRINT_ERROR,
 | |
|                            GTK_PRINT_ERROR_NOMEM,
 | |
|                            _("Not enough free memory"));
 | |
|       goto out;
 | |
|     }      
 | |
| 
 | |
|   printdlgex->lStructSize = sizeof (PRINTDLGEXW);
 | |
|   printdlgex->hwndOwner = parentHWnd;
 | |
|   printdlgex->hDevMode = NULL;
 | |
|   printdlgex->hDevNames = NULL;
 | |
|   printdlgex->hDC = NULL;
 | |
|   printdlgex->Flags = PD_RETURNDC | PD_NOSELECTION;
 | |
|   if (op->priv->current_page == -1)
 | |
|     printdlgex->Flags |= PD_NOCURRENTPAGE;
 | |
|   printdlgex->Flags2 = 0;
 | |
|   printdlgex->ExclusionFlags = 0;
 | |
| 
 | |
|   page_ranges = (LPPRINTPAGERANGE) GlobalAlloc (GPTR, 
 | |
| 						MAX_PAGE_RANGES * sizeof (PRINTPAGERANGE));
 | |
|   if (!page_ranges) 
 | |
|     {
 | |
|       result = GTK_PRINT_OPERATION_RESULT_ERROR;
 | |
|       g_set_error_literal (&priv->error,
 | |
|                            GTK_PRINT_ERROR,
 | |
|                            GTK_PRINT_ERROR_NOMEM,
 | |
|                            _("Not enough free memory"));
 | |
|       goto out;
 | |
|     }
 | |
| 
 | |
|   printdlgex->nPageRanges = 0;
 | |
|   printdlgex->nMaxPageRanges = MAX_PAGE_RANGES;
 | |
|   printdlgex->lpPageRanges = page_ranges;
 | |
|   printdlgex->nMinPage = 1;
 | |
|   if (op->priv->nr_of_pages != -1)
 | |
|     printdlgex->nMaxPage = op->priv->nr_of_pages;
 | |
|   else
 | |
|     printdlgex->nMaxPage = 10000;
 | |
|   printdlgex->nCopies = 1;
 | |
|   printdlgex->hInstance = 0;
 | |
|   printdlgex->lpPrintTemplateName = NULL;
 | |
|   printdlgex->lpCallback = NULL;
 | |
| 
 | |
|   g_signal_emit_by_name (op, "create-custom-widget",
 | |
| 			 &op->priv->custom_widget);
 | |
|   if (op->priv->custom_widget) {
 | |
|     prop_page = create_application_page (op);
 | |
|     printdlgex->nPropertyPages = 1;
 | |
|     printdlgex->lphPropertyPages = &prop_page;
 | |
|   } else {
 | |
|     printdlgex->nPropertyPages = 0;
 | |
|     printdlgex->lphPropertyPages = NULL;
 | |
|   }
 | |
|   
 | |
|   printdlgex->nStartPage = START_PAGE_GENERAL;
 | |
|   printdlgex->dwResultAction = 0;
 | |
| 
 | |
|   dialog_from_print_settings (op, printdlgex);
 | |
| 
 | |
|   callback = print_callback_new ();
 | |
|   printdlgex->lpCallback = (IUnknown *)callback;
 | |
|   got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
 | |
| 
 | |
|   hResult = PrintDlgExW (printdlgex);
 | |
|   IUnknown_Release ((IUnknown *)callback);
 | |
|   gdk_win32_set_modal_dialog_libgtk_only (NULL);
 | |
| 
 | |
|   if (hResult != S_OK) 
 | |
|     {
 | |
|       result = GTK_PRINT_OPERATION_RESULT_ERROR;
 | |
|       if (hResult == E_OUTOFMEMORY)
 | |
| 	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_literal (&priv->error,
 | |
|                              GTK_PRINT_ERROR,
 | |
|                              GTK_PRINT_ERROR_INTERNAL_ERROR,
 | |
|                              _("Invalid argument to PrintDlgEx"));
 | |
|       else if (hResult == E_POINTER)
 | |
| 	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_literal (&priv->error,
 | |
|                              GTK_PRINT_ERROR,
 | |
|                              GTK_PRINT_ERROR_INTERNAL_ERROR,
 | |
|                              _("Invalid handle to PrintDlgEx"));
 | |
|       else /* E_FAIL */
 | |
| 	g_set_error_literal (&priv->error,
 | |
|                              GTK_PRINT_ERROR,
 | |
|                              GTK_PRINT_ERROR_GENERAL,
 | |
|                              _("Unspecified error"));
 | |
|       goto out;
 | |
|     }
 | |
| 
 | |
|   if (printdlgex->dwResultAction == PD_RESULT_PRINT ||
 | |
|       printdlgex->dwResultAction == PD_RESULT_APPLY)
 | |
|     {
 | |
|       result = GTK_PRINT_OPERATION_RESULT_APPLY;
 | |
|       dialog_to_print_settings (op, printdlgex);
 | |
|     }
 | |
|   else
 | |
|     result = GTK_PRINT_OPERATION_RESULT_CANCEL;
 | |
|   
 | |
|   if (printdlgex->dwResultAction == PD_RESULT_PRINT)
 | |
|     {
 | |
|       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_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);
 | |
| 
 | |
|       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); 
 | |
|       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; 
 | |
| 	} 
 | |
|       
 | |
|       op_win32->hdc = printdlgex->hDC;
 | |
|       op_win32->devmode = printdlgex->hDevMode;
 | |
|       op_win32->devnames = printdlgex->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 = printdlgex->nCopies;
 | |
|       op->priv->manual_collation = (printdlgex->Flags & PD_COLLATE) != 0;
 | |
|       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 && printdlgex && printdlgex->hDC != NULL)
 | |
|     DeleteDC (printdlgex->hDC);
 | |
| 
 | |
|   if (!*do_print && printdlgex && printdlgex->hDevMode != NULL) 
 | |
|     GlobalFree (printdlgex->hDevMode); 
 | |
| 
 | |
|   if (!*do_print && printdlgex && printdlgex->hDevNames != NULL) 
 | |
|     GlobalFree (printdlgex->hDevNames); 
 | |
| 
 | |
|   if (page_ranges)
 | |
|     GlobalFree (page_ranges);
 | |
| 
 | |
|   if (printdlgex)
 | |
|     GlobalFree (printdlgex);
 | |
| 
 | |
|   if (invisible)
 | |
|     gtk_widget_destroy (invisible);
 | |
| 
 | |
|   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,
 | |
| 						      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 *
 | |
| gtk_print_run_page_setup_dialog (GtkWindow        *parent,
 | |
| 				 GtkPageSetup     *page_setup,
 | |
| 				 GtkPrintSettings *settings)
 | |
| {
 | |
|   LPPAGESETUPDLGW pagesetupdlg = NULL;
 | |
|   BOOL res;
 | |
|   gboolean free_settings;
 | |
|   const char *printer;
 | |
|   GtkPaperSize *paper_size;
 | |
|   DWORD measure_system;
 | |
|   GtkUnit unit;
 | |
|   double scale;
 | |
| 
 | |
|   pagesetupdlg = (LPPAGESETUPDLGW)GlobalAlloc (GPTR, sizeof (PAGESETUPDLGW));
 | |
|   if (!pagesetupdlg)
 | |
|     return NULL;
 | |
| 
 | |
|   free_settings = FALSE;
 | |
|   if (settings == NULL)
 | |
|     {
 | |
|       settings = gtk_print_settings_new ();
 | |
|       free_settings = TRUE;
 | |
|     }
 | |
|   
 | |
|   memset (pagesetupdlg, 0, sizeof (PAGESETUPDLGW));
 | |
| 
 | |
|   pagesetupdlg->lStructSize = sizeof (PAGESETUPDLGW);
 | |
| 
 | |
|   if (parent != NULL)
 | |
|     pagesetupdlg->hwndOwner = get_parent_hwnd (GTK_WIDGET (parent));
 | |
|   else
 | |
|     pagesetupdlg->hwndOwner = NULL;
 | |
| 
 | |
|   pagesetupdlg->Flags = PSD_DEFAULTMINMARGINS;
 | |
|   pagesetupdlg->hDevMode = devmode_from_settings (settings, page_setup);
 | |
|   pagesetupdlg->hDevNames = NULL;
 | |
|   printer = gtk_print_settings_get_printer (settings);
 | |
|   if (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));
 | |
| 
 | |
|   if (measure_system == 0)
 | |
|     {
 | |
|       pagesetupdlg->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
 | |
|       unit = GTK_UNIT_MM;
 | |
|       scale = 100;
 | |
|     }
 | |
|   else
 | |
|     {
 | |
|       pagesetupdlg->Flags |= PSD_INTHOUSANDTHSOFINCHES;
 | |
|       unit = GTK_UNIT_INCH;
 | |
|       scale = 1000;
 | |
|     }
 | |
| 
 | |
|   /* This is the object we return, we allocate it here so that
 | |
|    * we can use the default page margins */
 | |
|   if (page_setup)
 | |
|     page_setup = gtk_page_setup_copy (page_setup);
 | |
|   else
 | |
|     page_setup = gtk_page_setup_new ();
 | |
|   
 | |
|   pagesetupdlg->Flags |= PSD_MARGINS;
 | |
|   pagesetupdlg->rtMargin.left =
 | |
|     floor (gtk_page_setup_get_left_margin (page_setup, unit) * scale + 0.5);
 | |
|   pagesetupdlg->rtMargin.right =
 | |
|     floor (gtk_page_setup_get_right_margin (page_setup, unit) * scale + 0.5);
 | |
|   pagesetupdlg->rtMargin.top = 
 | |
|     floor (gtk_page_setup_get_top_margin (page_setup, unit) * scale + 0.5);
 | |
|   pagesetupdlg->rtMargin.bottom =
 | |
|     floor (gtk_page_setup_get_bottom_margin (page_setup, unit) * scale + 0.5);
 | |
| 
 | |
|   pagesetupdlg->Flags |= PSD_ENABLEPAGESETUPHOOK;
 | |
|   pagesetupdlg->lpfnPageSetupHook = run_mainloop_hook;
 | |
|   got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
 | |
|   
 | |
|   res = PageSetupDlgW (pagesetupdlg);
 | |
|   gdk_win32_set_modal_dialog_libgtk_only (NULL);
 | |
| 
 | |
|   if (res)
 | |
|     {  
 | |
|       if (pagesetupdlg->hDevNames != NULL)
 | |
| 	devnames_to_settings (settings, pagesetupdlg->hDevNames);
 | |
| 
 | |
|       if (pagesetupdlg->hDevMode != NULL)
 | |
| 	devmode_to_settings (settings, pagesetupdlg->hDevMode);
 | |
|     }
 | |
|   
 | |
|   if (res)
 | |
|     {
 | |
|       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);
 | |
| 	}
 | |
| 
 | |
|       if (pagesetupdlg->Flags & PSD_INHUNDREDTHSOFMILLIMETERS)
 | |
| 	{
 | |
| 	  unit = GTK_UNIT_MM;
 | |
| 	  scale = 100;
 | |
| 	}
 | |
|       else
 | |
| 	{
 | |
| 	  unit = GTK_UNIT_INCH;
 | |
| 	  scale = 1000;
 | |
| 	}
 | |
| 
 | |
|       gtk_page_setup_set_left_margin (page_setup,
 | |
| 				      pagesetupdlg->rtMargin.left / scale,
 | |
| 				      unit);
 | |
|       gtk_page_setup_set_right_margin (page_setup,
 | |
| 				       pagesetupdlg->rtMargin.right / scale,
 | |
| 				       unit);
 | |
|       gtk_page_setup_set_top_margin (page_setup,
 | |
| 				     pagesetupdlg->rtMargin.top / scale,
 | |
| 				     unit);
 | |
|       gtk_page_setup_set_bottom_margin (page_setup,
 | |
| 					pagesetupdlg->rtMargin.bottom / scale,
 | |
| 					unit);
 | |
|     }
 | |
|   
 | |
|   if (free_settings)
 | |
|     g_object_unref (settings);
 | |
| 
 | |
|   return page_setup;
 | |
| }
 | |
| 
 | |
| void
 | |
| gtk_print_run_page_setup_dialog_async (GtkWindow            *parent,
 | |
| 				       GtkPageSetup         *page_setup,
 | |
| 				       GtkPrintSettings     *settings,
 | |
| 				       GtkPageSetupDoneFunc  done_cb,
 | |
| 				       gpointer              data)
 | |
| {
 | |
|   GtkPageSetup *new_page_setup;
 | |
| 
 | |
|   new_page_setup = gtk_print_run_page_setup_dialog (parent, page_setup, settings);
 | |
|   done_cb (new_page_setup, data);
 | |
|   g_object_unref (new_page_setup);
 | |
| }
 | 
