]> Pileus Git - ~andy/gtk/blob - gtk/gtkprintoperation-win32.c
Fix variable declared in the middle of the block. (#526021, reported by
[~andy/gtk] / gtk / gtkprintoperation-win32.c
1 /* GTK - The GIMP Toolkit
2  * gtkprintoperation-win32.c: Print Operation Details for Win32
3  * Copyright (C) 2006, Red Hat, Inc.
4  *
5  * This library is free software; you can redistribute it and/or
6  * modify it under the terms of the GNU Lesser General Public
7  * License as published by the Free Software Foundation; either
8  * version 2 of the License, or (at your option) any later version.
9  *
10  * This library is distributed in the hope that it will be useful,
11  * but WITHOUT ANY WARRANTY; without even the implied warranty of
12  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
13  * Lesser General Public License for more details.
14  *
15  * You should have received a copy of the GNU Lesser General Public
16  * License along with this library; if not, write to the
17  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18  * Boston, MA 02111-1307, USA.
19  */
20
21 #ifndef _MSC_VER
22 #define _WIN32_WINNT 0x0500
23 #define WINVER _WIN32_WINNT
24 #endif
25
26 #define COBJMACROS
27 #include "config.h"
28 #include <math.h>
29 #ifdef HAVE_UNISTD_H
30 #include <unistd.h>
31 #endif
32 #include <io.h>
33 #include <stdio.h>
34 #include <stdlib.h>
35 #include <windows.h>
36 #include <cairo-win32.h>
37 #include <glib.h>
38 #include "gtkprintoperation-private.h"
39 #include "gtkprint-win32.h"
40 #include "gtkintl.h"
41 #include "gtkinvisible.h"
42 #include "gtkplug.h"
43 #include "gtkstock.h"
44 #include "gtk.h"
45 #include "gtkwin32embedwidget.h"
46 #include "gtkalias.h"
47
48 #define MAX_PAGE_RANGES 20
49 #define STATUS_POLLING_TIME 2000
50
51 #ifndef JOB_STATUS_RESTART
52 #define JOB_STATUS_RESTART 0x800
53 #endif
54
55 #ifndef JOB_STATUS_COMPLETE
56 #define JOB_STATUS_COMPLETE 0x1000
57 #endif
58
59 typedef struct {
60   HDC hdc;
61   HGLOBAL devmode;
62   HGLOBAL devnames;
63   HANDLE printerHandle;
64   int job_id;
65   guint timeout_id;
66
67   cairo_surface_t *surface;
68   GtkWidget *embed_widget;
69 } GtkPrintOperationWin32;
70
71 static void win32_poll_status (GtkPrintOperation *op);
72
73 static const GUID myIID_IPrintDialogCallback  = {0x5852a2c3,0x6530,0x11d1,{0xb6,0xa3,0x0,0x0,0xf8,0x75,0x7b,0xf9}};
74
75 #ifndef _MSC_VER
76 #undef INTERFACE
77 #define INTERFACE IPrintDialogCallback
78 DECLARE_INTERFACE_ (IPrintDialogCallback, IUnknown)
79 {
80     STDMETHOD (QueryInterface)(THIS_ REFIID,LPVOID*) PURE;
81     STDMETHOD_ (ULONG, AddRef)(THIS) PURE;
82     STDMETHOD_ (ULONG, Release)(THIS) PURE;
83     STDMETHOD (InitDone)(THIS) PURE;
84     STDMETHOD (SelectionChange)(THIS) PURE;
85     STDMETHOD (HandleMessage)(THIS_ HWND,UINT,WPARAM,LPARAM,LRESULT*) PURE;
86 }; 
87 #endif
88
89 static UINT got_gdk_events_message;
90
91 UINT_PTR CALLBACK
92 run_mainloop_hook (HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
93 {
94   if (uiMsg == WM_INITDIALOG)
95     {
96       gdk_win32_set_modal_dialog_libgtk_only (hdlg);
97       while (gtk_events_pending ())
98         gtk_main_iteration ();
99     }
100   else if (uiMsg == got_gdk_events_message)
101     {
102       while (gtk_events_pending ())
103         gtk_main_iteration ();
104       return 1;
105     }
106   return 0;
107 }
108
109 static GtkPageOrientation
110 orientation_from_win32 (short orientation)
111 {
112   if (orientation == DMORIENT_LANDSCAPE)
113     return GTK_PAGE_ORIENTATION_LANDSCAPE;
114   return GTK_PAGE_ORIENTATION_PORTRAIT;
115 }
116
117 static short
118 orientation_to_win32 (GtkPageOrientation orientation)
119 {
120   if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE ||
121       orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
122     return DMORIENT_LANDSCAPE;
123   return DMORIENT_PORTRAIT;
124 }
125
126 static GtkPaperSize *
127 paper_size_from_win32 (short size)
128 {
129   const char *name;
130   
131   switch (size)
132     {
133     case DMPAPER_LETTER_TRANSVERSE:
134     case DMPAPER_LETTER:
135     case DMPAPER_LETTERSMALL:
136       name = "na_letter";
137       break;
138     case DMPAPER_TABLOID:
139     case DMPAPER_LEDGER:
140       name = "na_ledger";
141       break;
142     case DMPAPER_LEGAL:
143       name = "na_legal";
144       break;
145     case DMPAPER_STATEMENT:
146       name = "na_invoice";
147       break;
148     case DMPAPER_EXECUTIVE:
149       name = "na_executive";
150       break;
151     case DMPAPER_A3:
152     case DMPAPER_A3_TRANSVERSE:
153       name = "iso_a3";
154       break;
155     case DMPAPER_A4:
156     case DMPAPER_A4SMALL:
157     case DMPAPER_A4_TRANSVERSE:
158       name = "iso_a4";
159       break;
160     case DMPAPER_A5:
161     case DMPAPER_A5_TRANSVERSE:
162       name = "iso_a5";
163       break;
164     case DMPAPER_B4:
165       name = "jis_b4";
166       break;
167     case DMPAPER_B5:
168     case DMPAPER_B5_TRANSVERSE:
169       name = "jis_b5";
170       break;
171     case DMPAPER_QUARTO:
172       name = "na_quarto";
173       break;
174     case DMPAPER_10X14:
175       name = "na_10x14";
176       break;
177     case DMPAPER_11X17:
178       name = "na_ledger";
179       break;
180     case DMPAPER_NOTE:
181       name = "na_letter";
182       break;
183     case DMPAPER_ENV_9:
184       name = "na_number-9";
185       break;
186     case DMPAPER_ENV_10:
187       name = "na_number-10";
188       break;
189     case DMPAPER_ENV_11:
190       name = "na_number-11";
191       break;
192     case DMPAPER_ENV_12:
193       name = "na_number-12";
194       break;
195     case DMPAPER_ENV_14:
196       name = "na_number-14";
197       break;
198     case DMPAPER_CSHEET:
199       name = "na_c";
200       break;
201     case DMPAPER_DSHEET:
202       name = "na_d";
203       break;
204     case DMPAPER_ESHEET:
205       name = "na_e";
206       break;
207     case DMPAPER_ENV_DL:
208       name = "iso_dl";
209       break;
210     case DMPAPER_ENV_C5:
211       name = "iso_c5";
212       break;
213     case DMPAPER_ENV_C3:
214       name = "iso_c3";
215       break;
216     case DMPAPER_ENV_C4:
217       name = "iso_c4";
218       break;
219     case DMPAPER_ENV_C6:
220       name = "iso_c6";
221       break;
222     case DMPAPER_ENV_C65:
223       name = "iso_c6c5";
224       break;
225     case DMPAPER_ENV_B4:
226       name = "iso_b4";
227       break;
228     case DMPAPER_ENV_B5:
229       name = "iso_b5";
230       break;
231     case DMPAPER_ENV_B6:
232       name = "iso_b6";
233       break;
234     case DMPAPER_ENV_ITALY:
235       name = "om_italian";
236       break;
237     case DMPAPER_ENV_MONARCH:
238       name = "na_monarch";
239       break;
240     case DMPAPER_ENV_PERSONAL:
241       name = "na_personal";
242       break;
243     case DMPAPER_FANFOLD_US:
244       name = "na_fanfold-us";
245       break;
246     case DMPAPER_FANFOLD_STD_GERMAN:
247       name = "na_fanfold-eur";
248       break;
249     case DMPAPER_FANFOLD_LGL_GERMAN:
250       name = "na_foolscap";
251       break;
252     case DMPAPER_ISO_B4:
253       name = "iso_b4";
254       break;
255     case DMPAPER_JAPANESE_POSTCARD:
256       name = "jpn_hagaki";
257       break;
258     case DMPAPER_9X11:
259       name = "na_9x11";
260       break;
261     case DMPAPER_10X11:
262       name = "na_10x11";
263       break;
264     case DMPAPER_ENV_INVITE:
265       name = "om_invite";
266        break;
267     case DMPAPER_LETTER_EXTRA:
268     case DMPAPER_LETTER_EXTRA_TRANSVERSE:
269       name = "na_letter-extra";
270       break;
271     case DMPAPER_LEGAL_EXTRA:
272       name = "na_legal-extra";
273       break;
274     case DMPAPER_TABLOID_EXTRA:
275       name = "na_arch";
276       break;
277     case DMPAPER_A4_EXTRA:
278       name = "iso_a4-extra";
279       break;
280     case DMPAPER_B_PLUS:
281       name = "na_b-plus";
282       break;
283     case DMPAPER_LETTER_PLUS:
284       name = "na_letter-plus";
285       break;
286     case DMPAPER_A3_EXTRA:
287     case DMPAPER_A3_EXTRA_TRANSVERSE:
288       name = "iso_a3-extra";
289       break;
290     case DMPAPER_A5_EXTRA:
291       name = "iso_a5-extra";
292       break;
293     case DMPAPER_B5_EXTRA:
294       name = "iso_b5-extra";
295       break;
296     case DMPAPER_A2:
297       name = "iso_a2";
298       break;
299       
300     default:
301       name = NULL;
302       break;
303     }
304
305   if (name)
306     return gtk_paper_size_new (name);
307   else 
308     return NULL;
309 }
310
311 static short
312 paper_size_to_win32 (GtkPaperSize *paper_size)
313 {
314   const char *format;
315
316   if (gtk_paper_size_is_custom (paper_size))
317     return 0;
318   
319   format = gtk_paper_size_get_name (paper_size);
320
321   if (strcmp (format, "na_letter") == 0)
322     return DMPAPER_LETTER;
323   if (strcmp (format, "na_ledger") == 0)
324     return DMPAPER_LEDGER;
325   if (strcmp (format, "na_legal") == 0)
326     return DMPAPER_LEGAL;
327   if (strcmp (format, "na_invoice") == 0)
328     return DMPAPER_STATEMENT;
329   if (strcmp (format, "na_executive") == 0)
330     return DMPAPER_EXECUTIVE;
331   if (strcmp (format, "iso_a2") == 0)
332     return DMPAPER_A2;
333   if (strcmp (format, "iso_a3") == 0)
334     return DMPAPER_A3;
335   if (strcmp (format, "iso_a4") == 0)
336     return DMPAPER_A4;
337   if (strcmp (format, "iso_a5") == 0)
338     return DMPAPER_A5;
339   if (strcmp (format, "iso_b4") == 0)
340     return DMPAPER_B4;
341   if (strcmp (format, "iso_b5") == 0)
342     return DMPAPER_B5;
343   if (strcmp (format, "na_quarto") == 0)
344     return DMPAPER_QUARTO;
345   if (strcmp (format, "na_10x14") == 0)
346     return DMPAPER_10X14;
347   if (strcmp (format, "na_number-9") == 0)
348     return DMPAPER_ENV_9;
349   if (strcmp (format, "na_number-10") == 0)
350     return DMPAPER_ENV_10;
351   if (strcmp (format, "na_number-11") == 0)
352     return DMPAPER_ENV_11;
353   if (strcmp (format, "na_number-12") == 0)
354     return DMPAPER_ENV_12;
355   if (strcmp (format, "na_number-14") == 0)
356     return DMPAPER_ENV_14;
357   if (strcmp (format, "na_c") == 0)
358     return DMPAPER_CSHEET;
359   if (strcmp (format, "na_d") == 0)
360     return DMPAPER_DSHEET;
361   if (strcmp (format, "na_e") == 0)
362     return DMPAPER_ESHEET;
363   if (strcmp (format, "iso_dl") == 0)
364     return DMPAPER_ENV_DL;
365   if (strcmp (format, "iso_c3") == 0)
366     return DMPAPER_ENV_C3;
367   if (strcmp (format, "iso_c4") == 0)
368     return DMPAPER_ENV_C4;
369   if (strcmp (format, "iso_c5") == 0)
370     return DMPAPER_ENV_C5;
371   if (strcmp (format, "iso_c6") == 0)
372     return DMPAPER_ENV_C6;
373   if (strcmp (format, "iso_c5c6") == 0)
374     return DMPAPER_ENV_C65;
375   if (strcmp (format, "iso_b6") == 0)
376     return DMPAPER_ENV_B6;
377   if (strcmp (format, "om_italian") == 0)
378     return DMPAPER_ENV_ITALY;
379   if (strcmp (format, "na_monarch") == 0)
380     return DMPAPER_ENV_MONARCH;
381   if (strcmp (format, "na_personal") == 0)
382     return DMPAPER_ENV_PERSONAL;
383   if (strcmp (format, "na_fanfold-us") == 0)
384     return DMPAPER_FANFOLD_US;
385   if (strcmp (format, "na_fanfold-eur") == 0)
386     return DMPAPER_FANFOLD_STD_GERMAN;
387   if (strcmp (format, "na_foolscap") == 0)
388     return DMPAPER_FANFOLD_LGL_GERMAN;
389   if (strcmp (format, "jpn_hagaki") == 0)
390     return DMPAPER_JAPANESE_POSTCARD;
391   if (strcmp (format, "na_9x11") == 0)
392     return DMPAPER_9X11;
393   if (strcmp (format, "na_10x11") == 0)
394     return DMPAPER_10X11;
395   if (strcmp (format, "om_invite") == 0)
396     return DMPAPER_ENV_INVITE;
397   if (strcmp (format, "na_letter-extra") == 0)
398     return DMPAPER_LETTER_EXTRA;
399   if (strcmp (format, "na_legal-extra") == 0)
400     return DMPAPER_LEGAL_EXTRA;
401   if (strcmp (format, "na_arch") == 0)
402     return DMPAPER_TABLOID_EXTRA;
403   if (strcmp (format, "iso_a3-extra") == 0)
404     return DMPAPER_A3_EXTRA;
405   if (strcmp (format, "iso_a4-extra") == 0)
406     return DMPAPER_A4_EXTRA;
407   if (strcmp (format, "iso_a5-extra") == 0)
408     return DMPAPER_A5_EXTRA;
409   if (strcmp (format, "iso_b5-extra") == 0)
410     return DMPAPER_B5_EXTRA;
411   if (strcmp (format, "na_b-plus") == 0)
412     return DMPAPER_B_PLUS;
413   if (strcmp (format, "na_letter-plus") == 0)
414     return DMPAPER_LETTER_PLUS;
415
416   return 0;
417 }
418
419 void
420 win32_start_page (GtkPrintOperation *op,
421                   GtkPrintContext *print_context,
422                   GtkPageSetup *page_setup)
423 {
424   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
425   LPDEVMODEW devmode;
426   GtkPaperSize *paper_size;
427
428   devmode = GlobalLock (op_win32->devmode);
429   
430   devmode->dmFields |= DM_ORIENTATION;
431   devmode->dmOrientation =
432     orientation_to_win32 (gtk_page_setup_get_orientation (page_setup));
433   
434   paper_size = gtk_page_setup_get_paper_size (page_setup);
435   devmode->dmFields |= DM_PAPERSIZE;
436   devmode->dmFields &= ~(DM_PAPERWIDTH | DM_PAPERLENGTH);
437   devmode->dmPaperSize = paper_size_to_win32 (paper_size);
438   if (devmode->dmPaperSize == 0)
439     {
440       devmode->dmPaperSize = DMPAPER_USER;
441       devmode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
442       devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) * 10.0;
443       devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) * 10.0;
444     }
445   
446   ResetDCW (op_win32->hdc, devmode);
447   
448   GlobalUnlock (op_win32->devmode);
449   
450   StartPage (op_win32->hdc);
451 }
452
453 static void
454 win32_end_page (GtkPrintOperation *op,
455                 GtkPrintContext *print_context)
456 {
457   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
458
459   cairo_surface_show_page (op_win32->surface);
460
461   EndPage (op_win32->hdc);
462 }
463
464 static gboolean
465 win32_poll_status_timeout (GtkPrintOperation *op)
466 {
467   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
468   
469   op_win32->timeout_id = 0;
470   /* We need to ref this, as setting the status to finished
471      might unref the object */
472   g_object_ref (op);
473   win32_poll_status (op);
474
475   if (!gtk_print_operation_is_finished (op))
476     op_win32->timeout_id = gdk_threads_add_timeout (STATUS_POLLING_TIME,
477                                           (GSourceFunc)win32_poll_status_timeout,
478                                           op);
479   g_object_unref (op);
480   return FALSE;
481 }
482
483
484 static void
485 win32_end_run (GtkPrintOperation *op,
486                gboolean           wait,
487                gboolean           cancelled)
488 {
489   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
490   LPDEVNAMES devnames;
491   HANDLE printerHandle = 0;
492
493   cairo_surface_finish (op_win32->surface);
494   
495   EndDoc (op_win32->hdc);
496
497   if (op->priv->track_print_status)
498     {
499       devnames = GlobalLock (op_win32->devnames);
500       if (!OpenPrinterW (((gunichar2 *)devnames) + devnames->wDeviceOffset,
501                          &printerHandle, NULL))
502         printerHandle = 0;
503       GlobalUnlock (op_win32->devnames);
504     }
505   
506   GlobalFree(op_win32->devmode);
507   GlobalFree(op_win32->devnames);
508
509   cairo_surface_destroy (op_win32->surface);
510   op_win32->surface = NULL;
511
512   DeleteDC(op_win32->hdc);
513   
514   if (printerHandle != 0)
515     {
516       op_win32->printerHandle = printerHandle;
517       win32_poll_status (op);
518       op_win32->timeout_id = gdk_threads_add_timeout (STATUS_POLLING_TIME,
519                                             (GSourceFunc)win32_poll_status_timeout,
520                                             op);
521     }
522   else
523     /* Dunno what happened, pretend its finished */
524     _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
525 }
526
527 static void
528 win32_poll_status (GtkPrintOperation *op)
529 {
530   GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
531   guchar *data;
532   DWORD needed;
533   JOB_INFO_1W *job_info;
534   GtkPrintStatus status;
535   char *status_str;
536   BOOL ret;
537
538   GetJobW (op_win32->printerHandle, op_win32->job_id,
539            1,(LPBYTE)NULL, 0, &needed);
540   data = g_malloc (needed);
541   ret = GetJobW (op_win32->printerHandle, op_win32->job_id,
542                  1, (LPBYTE)data, needed, &needed);
543
544   status_str = NULL;
545   if (ret)
546     {
547       DWORD win32_status;
548       job_info = (JOB_INFO_1W *)data;
549       win32_status = job_info->Status;
550
551       if (job_info->pStatus)
552         status_str = g_utf16_to_utf8 (job_info->pStatus, 
553                                       -1, NULL, NULL, NULL);
554      
555       if (win32_status &
556           (JOB_STATUS_COMPLETE | JOB_STATUS_PRINTED))
557         status = GTK_PRINT_STATUS_FINISHED;
558       else if (win32_status &
559                (JOB_STATUS_OFFLINE |
560                 JOB_STATUS_PAPEROUT |
561                 JOB_STATUS_PAUSED |
562                 JOB_STATUS_USER_INTERVENTION))
563         {
564           status = GTK_PRINT_STATUS_PENDING_ISSUE;
565           if (status_str == NULL)
566             {
567               if (win32_status & JOB_STATUS_OFFLINE)
568                 status_str = g_strdup (_("Printer offline"));
569               else if (win32_status & JOB_STATUS_PAPEROUT)
570                 status_str = g_strdup (_("Out of paper"));
571               else if (win32_status & JOB_STATUS_PAUSED)
572                 status_str = g_strdup (_("Paused"));
573               else if (win32_status & JOB_STATUS_USER_INTERVENTION)
574                 status_str = g_strdup (_("Need user intervention"));
575             }
576         }
577       else if (win32_status &
578                (JOB_STATUS_BLOCKED_DEVQ |
579                 JOB_STATUS_DELETED |
580                 JOB_STATUS_ERROR))
581         status = GTK_PRINT_STATUS_FINISHED_ABORTED;
582       else if (win32_status &
583                (JOB_STATUS_SPOOLING |
584                 JOB_STATUS_DELETING))
585         status = GTK_PRINT_STATUS_PENDING;
586       else if (win32_status & JOB_STATUS_PRINTING)
587         status = GTK_PRINT_STATUS_PRINTING;
588       else
589         status = GTK_PRINT_STATUS_FINISHED;
590     }
591   else
592     status = GTK_PRINT_STATUS_FINISHED;
593
594   g_free (data);
595
596   _gtk_print_operation_set_status (op, status, status_str);
597  
598   g_free (status_str);
599 }
600
601 static void
602 op_win32_free (GtkPrintOperationWin32 *op_win32)
603 {
604   if (op_win32->printerHandle)
605     ClosePrinter (op_win32->printerHandle);
606   if (op_win32->timeout_id != 0)
607     g_source_remove (op_win32->timeout_id);
608   g_free (op_win32);
609 }
610
611 static HWND
612 get_parent_hwnd (GtkWidget *widget)
613 {
614   gtk_widget_realize (widget);
615   return gdk_win32_drawable_get_handle (widget->window);
616 }
617
618 static void
619 devnames_to_settings (GtkPrintSettings *settings,
620                       HANDLE hDevNames)
621 {
622   GtkPrintWin32Devnames *devnames = gtk_print_win32_devnames_from_win32 (hDevNames);
623   gtk_print_settings_set_printer (settings, devnames->device);
624   gtk_print_win32_devnames_free (devnames);
625 }
626
627 static void
628 devmode_to_settings (GtkPrintSettings *settings,
629                      HANDLE hDevMode)
630 {
631   LPDEVMODEW devmode;
632
633   devmode = GlobalLock (hDevMode);
634   
635   gtk_print_settings_set_int (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION,
636                               devmode->dmDriverVersion);
637   if (devmode->dmDriverExtra != 0)
638     {
639       char *extra = g_base64_encode (((char *)devmode) + sizeof (DEVMODEW),
640                                      devmode->dmDriverExtra);
641       gtk_print_settings_set (settings,
642                               GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA,
643                               extra);
644       g_free (extra);
645     }
646   
647   if (devmode->dmFields & DM_ORIENTATION)
648     gtk_print_settings_set_orientation (settings,
649                                         orientation_from_win32 (devmode->dmOrientation));
650   
651   
652   if (devmode->dmFields & DM_PAPERSIZE &&
653       devmode->dmPaperSize != 0)
654     {
655       GtkPaperSize *paper_size = paper_size_from_win32 (devmode->dmPaperSize);
656       if (paper_size)
657         {
658           gtk_print_settings_set_paper_size (settings, paper_size);
659           gtk_paper_size_free (paper_size);
660         }
661       gtk_print_settings_set_int (settings, "win32-paper-size", (int)devmode->dmPaperSize);
662     }
663   else if ((devmode->dmFields & DM_PAPERSIZE &&
664             devmode->dmPaperSize == 0) ||
665            ((devmode->dmFields & DM_PAPERWIDTH) &&
666             (devmode->dmFields & DM_PAPERLENGTH)))
667     {
668       GtkPaperSize *paper_size;
669       char *form_name = NULL;
670       if (devmode->dmFields & DM_FORMNAME)
671         form_name = g_utf16_to_utf8 (devmode->dmFormName, 
672                                      -1, NULL, NULL, NULL);
673       if (form_name == NULL || form_name[0] == 0)
674         form_name = g_strdup (_("Custom size"));
675       paper_size = gtk_paper_size_new_custom (form_name,
676                                               form_name,
677                                               devmode->dmPaperWidth * 10.0,
678                                               devmode->dmPaperLength * 10.0,
679                                               GTK_UNIT_MM);
680       gtk_print_settings_set_paper_size (settings, paper_size);
681       gtk_paper_size_free (paper_size);
682     }
683   
684   if (devmode->dmFields & DM_SCALE)
685     gtk_print_settings_set_scale (settings, devmode->dmScale);
686   
687   if (devmode->dmFields & DM_COPIES)
688     gtk_print_settings_set_n_copies (settings,
689                                      devmode->dmCopies);
690   
691   if (devmode->dmFields & DM_DEFAULTSOURCE)
692     {
693       char *source;
694       switch (devmode->dmDefaultSource)
695         {
696         default:
697         case DMBIN_AUTO:
698           source = "auto";
699           break;
700         case DMBIN_CASSETTE:
701           source = "cassette";
702           break;
703         case DMBIN_ENVELOPE:
704           source = "envelope";
705           break;
706         case DMBIN_ENVMANUAL:
707           source = "envelope-manual";
708           break;
709         case DMBIN_LOWER:
710           source = "lower";
711           break;
712         case DMBIN_MANUAL:
713           source = "manual";
714           break;
715         case DMBIN_MIDDLE:
716           source = "middle";
717           break;
718         case DMBIN_ONLYONE:
719           source = "only-one";
720           break;
721         case DMBIN_FORMSOURCE:
722           source = "form-source";
723           break;
724         case DMBIN_LARGECAPACITY:
725           source = "large-capacity";
726           break;
727         case DMBIN_LARGEFMT:
728           source = "large-format";
729           break;
730         case DMBIN_TRACTOR:
731           source = "tractor";
732           break;
733         case DMBIN_SMALLFMT:
734           source = "small-format";
735           break;
736         }
737       gtk_print_settings_set_default_source (settings, source);
738       gtk_print_settings_set_int (settings, "win32-default-source", devmode->dmDefaultSource);
739     }
740   
741   if (devmode->dmFields & DM_PRINTQUALITY)
742     {
743       GtkPrintQuality quality;
744       switch (devmode->dmPrintQuality)
745         {
746         case DMRES_LOW:
747           quality = GTK_PRINT_QUALITY_LOW;
748           break;
749         case DMRES_MEDIUM:
750           quality = GTK_PRINT_QUALITY_NORMAL;
751           break;
752         default:
753         case DMRES_HIGH:
754           quality = GTK_PRINT_QUALITY_HIGH;
755           break;
756         case DMRES_DRAFT:
757           quality = GTK_PRINT_QUALITY_DRAFT;
758           break;
759         }
760       gtk_print_settings_set_quality (settings, quality);
761       gtk_print_settings_set_int (settings, "win32-print-quality", devmode->dmPrintQuality);
762     }
763   
764   if (devmode->dmFields & DM_COLOR)
765     gtk_print_settings_set_use_color (settings, devmode->dmFields == DMCOLOR_COLOR);
766   
767   if (devmode->dmFields & DM_DUPLEX)
768     {
769       GtkPrintDuplex duplex;
770       switch (devmode->dmDuplex)
771         {
772         default:
773         case DMDUP_SIMPLEX:
774           duplex = GTK_PRINT_DUPLEX_SIMPLEX;
775           break;
776         case DMDUP_HORIZONTAL:
777           duplex = GTK_PRINT_DUPLEX_HORIZONTAL;
778           break;
779         case DMDUP_VERTICAL:
780           duplex = GTK_PRINT_DUPLEX_VERTICAL;
781           break;
782         }
783       
784       gtk_print_settings_set_duplex (settings, duplex);
785     }
786   
787   if (devmode->dmFields & DM_COLLATE)
788     gtk_print_settings_set_collate (settings,
789                                     devmode->dmCollate == DMCOLLATE_TRUE);
790   
791   if (devmode->dmFields & DM_MEDIATYPE)
792     {
793       char *media_type;
794       switch (devmode->dmMediaType)
795         {
796         default:
797         case DMMEDIA_STANDARD:
798           media_type = "stationery";
799           break;
800         case DMMEDIA_TRANSPARENCY:
801           media_type = "transparency";
802           break;
803         case DMMEDIA_GLOSSY:
804           media_type = "photographic-glossy";
805           break;
806         }
807       gtk_print_settings_set_media_type (settings, media_type);
808       gtk_print_settings_set_int (settings, "win32-media-type", devmode->dmMediaType);
809     }
810   
811   if (devmode->dmFields & DM_DITHERTYPE)
812     {
813       char *dither;
814       switch (devmode->dmDitherType)
815         {
816         default:
817         case DMDITHER_FINE:
818           dither = "fine";
819           break;
820         case DMDITHER_NONE:
821           dither = "none";
822           break;
823         case DMDITHER_COARSE:
824           dither = "coarse";
825           break;
826         case DMDITHER_LINEART:
827           dither = "lineart";
828           break;
829         case DMDITHER_GRAYSCALE:
830           dither = "grayscale";
831           break;
832         case DMDITHER_ERRORDIFFUSION:
833           dither = "error-diffusion";
834           break;
835         }
836       gtk_print_settings_set_dither (settings, dither);
837       gtk_print_settings_set_int (settings, "win32-dither-type", devmode->dmDitherType);
838     }
839   
840   GlobalUnlock (hDevMode);
841 }
842
843 static void
844 dialog_to_print_settings (GtkPrintOperation *op,
845                           LPPRINTDLGEXW printdlgex)
846 {
847   int i;
848   GtkPrintSettings *settings;
849
850   settings = gtk_print_settings_new ();
851
852   gtk_print_settings_set_print_pages (settings,
853                                       GTK_PRINT_PAGES_ALL);
854   if (printdlgex->Flags & PD_CURRENTPAGE)
855     gtk_print_settings_set_print_pages (settings,
856                                         GTK_PRINT_PAGES_CURRENT);
857   else if (printdlgex->Flags & PD_PAGENUMS)
858     gtk_print_settings_set_print_pages (settings,
859                                         GTK_PRINT_PAGES_RANGES);
860
861   if (printdlgex->nPageRanges > 0)
862     {
863       GtkPageRange *ranges;
864       ranges = g_new (GtkPageRange, printdlgex->nPageRanges);
865
866       for (i = 0; i < printdlgex->nPageRanges; i++)
867         {
868           ranges[i].start = printdlgex->lpPageRanges[i].nFromPage - 1;
869           ranges[i].end = printdlgex->lpPageRanges[i].nToPage - 1;
870         }
871
872       gtk_print_settings_set_page_ranges (settings, ranges,
873                                           printdlgex->nPageRanges);
874       g_free (ranges);
875     }
876   
877   if (printdlgex->hDevNames != NULL)
878     devnames_to_settings (settings, printdlgex->hDevNames);
879
880   if (printdlgex->hDevMode != NULL)
881     devmode_to_settings (settings, printdlgex->hDevMode);
882   
883   gtk_print_operation_set_print_settings (op, settings);
884 }
885
886 static HANDLE
887 devmode_from_settings (GtkPrintSettings *settings,
888                        GtkPageSetup *page_setup)
889 {
890   HANDLE hDevMode;
891   LPDEVMODEW devmode;
892   char *extras;
893   GtkPaperSize *paper_size;
894   const char *extras_base64;
895   int extras_len;
896   const char *val;
897
898   extras = NULL;
899   extras_len = 0;
900   extras_base64 = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA);
901   if (extras_base64)
902     extras = g_base64_decode (extras_base64, &extras_len);
903   
904   hDevMode = GlobalAlloc (GMEM_MOVEABLE, 
905                           sizeof (DEVMODEW) + extras_len);
906
907   devmode = GlobalLock (hDevMode);
908
909   memset (devmode, 0, sizeof (DEVMODEW));
910   
911   devmode->dmSpecVersion = DM_SPECVERSION;
912   devmode->dmSize = sizeof (DEVMODEW);
913   
914   devmode->dmDriverExtra = 0;
915   if (extras && extras_len > 0)
916     {
917       devmode->dmDriverExtra = extras_len;
918       memcpy (((char *)devmode) + sizeof (DEVMODEW), extras, extras_len);
919       g_free (extras);
920     }
921   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION))
922     devmode->dmDriverVersion = gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION);
923   
924   if (page_setup ||
925       gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
926     {
927       GtkPageOrientation orientation = gtk_print_settings_get_orientation (settings);
928       if (page_setup)
929         orientation = gtk_page_setup_get_orientation (page_setup);
930       devmode->dmFields |= DM_ORIENTATION;
931       devmode->dmOrientation = orientation_to_win32 (orientation);
932     }
933
934   if (page_setup)
935     paper_size = gtk_paper_size_copy (gtk_page_setup_get_paper_size (page_setup));
936   else
937     {
938       int size;
939       if (gtk_print_settings_has_key (settings, "win32-paper-size") &&
940           (size = gtk_print_settings_get_int (settings, "win32-paper-size")) != 0)
941         {
942           devmode->dmFields |= DM_PAPERSIZE;
943           devmode->dmPaperSize = size;
944           paper_size = NULL;
945         }
946       else
947         paper_size = gtk_print_settings_get_paper_size (settings);
948     }
949   if (paper_size)
950     {
951       devmode->dmFields |= DM_PAPERSIZE;
952       devmode->dmPaperSize = paper_size_to_win32 (paper_size);
953       if (devmode->dmPaperSize == 0)
954         {
955           devmode->dmPaperSize = DMPAPER_USER;
956           devmode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
957           devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) / 10.0;
958           devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) / 10.0;
959         }
960       gtk_paper_size_free (paper_size);
961     }
962
963   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_SCALE))
964     {
965       devmode->dmFields |= DM_SCALE;
966       devmode->dmScale = gtk_print_settings_get_scale (settings);
967     }
968   
969   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_N_COPIES))
970     {
971       devmode->dmFields |= DM_COPIES;
972       devmode->dmCopies = gtk_print_settings_get_n_copies (settings);
973     }
974
975   if (gtk_print_settings_has_key (settings, "win32-default-source"))
976     {
977       devmode->dmFields |= DM_DEFAULTSOURCE;
978       devmode->dmDefaultSource = gtk_print_settings_get_int (settings, "win32-default-source");
979     }
980   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE))
981     {
982       devmode->dmFields |= DM_DEFAULTSOURCE;
983       devmode->dmDefaultSource = DMBIN_AUTO;
984
985       val = gtk_print_settings_get_default_source (settings);
986       if (strcmp (val, "auto") == 0)
987         devmode->dmDefaultSource = DMBIN_AUTO;
988       if (strcmp (val, "cassette") == 0)
989         devmode->dmDefaultSource = DMBIN_CASSETTE;
990       if (strcmp (val, "envelope") == 0)
991         devmode->dmDefaultSource = DMBIN_ENVELOPE;
992       if (strcmp (val, "envelope-manual") == 0)
993         devmode->dmDefaultSource = DMBIN_ENVMANUAL;
994       if (strcmp (val, "lower") == 0)
995         devmode->dmDefaultSource = DMBIN_LOWER;
996       if (strcmp (val, "manual") == 0)
997         devmode->dmDefaultSource = DMBIN_MANUAL;
998       if (strcmp (val, "middle") == 0)
999         devmode->dmDefaultSource = DMBIN_MIDDLE;
1000       if (strcmp (val, "only-one") == 0)
1001         devmode->dmDefaultSource = DMBIN_ONLYONE;
1002       if (strcmp (val, "form-source") == 0)
1003         devmode->dmDefaultSource = DMBIN_FORMSOURCE;
1004       if (strcmp (val, "large-capacity") == 0)
1005         devmode->dmDefaultSource = DMBIN_LARGECAPACITY;
1006       if (strcmp (val, "large-format") == 0)
1007         devmode->dmDefaultSource = DMBIN_LARGEFMT;
1008       if (strcmp (val, "tractor") == 0)
1009         devmode->dmDefaultSource = DMBIN_TRACTOR;
1010       if (strcmp (val, "small-format") == 0)
1011         devmode->dmDefaultSource = DMBIN_SMALLFMT;
1012     }
1013
1014   if (gtk_print_settings_has_key (settings, "win32-print-quality"))
1015     {
1016       devmode->dmFields |= DM_PRINTQUALITY;
1017       devmode->dmPrintQuality = gtk_print_settings_get_int (settings, "win32-print-quality");
1018     }
1019   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_RESOLUTION))
1020     {
1021       devmode->dmFields |= DM_PRINTQUALITY;
1022       devmode->dmPrintQuality = gtk_print_settings_get_resolution (settings);
1023     } 
1024   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_QUALITY))
1025     {
1026       devmode->dmFields |= DM_PRINTQUALITY;
1027       switch (gtk_print_settings_get_quality (settings))
1028         {
1029         case GTK_PRINT_QUALITY_LOW:
1030           devmode->dmPrintQuality = DMRES_LOW;
1031           break;
1032         case GTK_PRINT_QUALITY_DRAFT:
1033           devmode->dmPrintQuality = DMRES_DRAFT;
1034           break;
1035         default:
1036         case GTK_PRINT_QUALITY_NORMAL:
1037           devmode->dmPrintQuality = DMRES_MEDIUM;
1038           break;
1039         case GTK_PRINT_QUALITY_HIGH:
1040           devmode->dmPrintQuality = DMRES_HIGH;
1041           break;
1042         }
1043     }
1044
1045   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_USE_COLOR))
1046     {
1047       devmode->dmFields |= DM_COLOR;
1048       if (gtk_print_settings_get_use_color (settings))
1049         devmode->dmColor = DMCOLOR_COLOR;
1050       else
1051         devmode->dmColor = DMCOLOR_MONOCHROME;
1052     }
1053
1054   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DUPLEX))
1055     {
1056       devmode->dmFields |= DM_DUPLEX;
1057       switch (gtk_print_settings_get_duplex (settings))
1058         {
1059         default:
1060         case GTK_PRINT_DUPLEX_SIMPLEX:
1061           devmode->dmDuplex = DMDUP_SIMPLEX;
1062           break;
1063         case GTK_PRINT_DUPLEX_HORIZONTAL:
1064           devmode->dmDuplex = DMDUP_HORIZONTAL;
1065           break;
1066         case GTK_PRINT_DUPLEX_VERTICAL:
1067           devmode->dmDuplex = DMDUP_VERTICAL;
1068           break;
1069         }
1070     }
1071
1072   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_COLLATE))
1073     {
1074       devmode->dmFields |= DM_COLLATE;
1075       if (gtk_print_settings_get_collate (settings))
1076         devmode->dmCollate = DMCOLLATE_TRUE;
1077       else
1078         devmode->dmCollate = DMCOLLATE_FALSE;
1079     }
1080
1081   if (gtk_print_settings_has_key (settings, "win32-media-type"))
1082     {
1083       devmode->dmFields |= DM_MEDIATYPE;
1084       devmode->dmMediaType = gtk_print_settings_get_int (settings, "win32-media-type");
1085     }
1086   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_MEDIA_TYPE))
1087     {
1088       devmode->dmFields |= DM_MEDIATYPE;
1089       devmode->dmMediaType = DMMEDIA_STANDARD;
1090       
1091       val = gtk_print_settings_get_media_type (settings);
1092       if (strcmp (val, "transparency") == 0)
1093         devmode->dmMediaType = DMMEDIA_TRANSPARENCY;
1094       if (strcmp (val, "photographic-glossy") == 0)
1095         devmode->dmMediaType = DMMEDIA_GLOSSY;
1096     }
1097  
1098   if (gtk_print_settings_has_key (settings, "win32-dither-type"))
1099     {
1100       devmode->dmFields |= DM_DITHERTYPE;
1101       devmode->dmDitherType = gtk_print_settings_get_int (settings, "win32-dither-type");
1102     }
1103   else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DITHER))
1104     {
1105       devmode->dmFields |= DM_DITHERTYPE;
1106       devmode->dmDitherType = DMDITHER_FINE;
1107       
1108       val = gtk_print_settings_get_dither (settings);
1109       if (strcmp (val, "none") == 0)
1110         devmode->dmDitherType = DMDITHER_NONE;
1111       if (strcmp (val, "coarse") == 0)
1112         devmode->dmDitherType = DMDITHER_COARSE;
1113       if (strcmp (val, "fine") == 0)
1114         devmode->dmDitherType = DMDITHER_FINE;
1115       if (strcmp (val, "lineart") == 0)
1116         devmode->dmDitherType = DMDITHER_LINEART;
1117       if (strcmp (val, "grayscale") == 0)
1118         devmode->dmDitherType = DMDITHER_GRAYSCALE;
1119       if (strcmp (val, "error-diffusion") == 0)
1120         devmode->dmDitherType = DMDITHER_ERRORDIFFUSION;
1121     }
1122   
1123   GlobalUnlock (hDevMode);
1124
1125   return hDevMode;
1126 }
1127
1128 static void
1129 dialog_from_print_settings (GtkPrintOperation *op,
1130                             LPPRINTDLGEXW printdlgex)
1131 {
1132   GtkPrintSettings *settings = op->priv->print_settings;
1133   const char *printer;
1134
1135   if (settings == NULL)
1136     return;
1137
1138   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_PRINT_PAGES))
1139     {
1140       GtkPrintPages print_pages = gtk_print_settings_get_print_pages (settings);
1141
1142       switch (print_pages)
1143         {
1144         default:
1145         case GTK_PRINT_PAGES_ALL:
1146           printdlgex->Flags |= PD_ALLPAGES;
1147           break;
1148         case GTK_PRINT_PAGES_CURRENT:
1149           printdlgex->Flags |= PD_CURRENTPAGE;
1150           break;
1151         case GTK_PRINT_PAGES_RANGES:
1152           printdlgex->Flags |= PD_PAGENUMS;
1153           break;
1154         }
1155     }
1156   if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_PAGE_RANGES))
1157     {
1158       GtkPageRange *ranges;
1159       int num_ranges, i;
1160
1161       ranges = gtk_print_settings_get_page_ranges (settings, &num_ranges);
1162
1163       if (num_ranges > MAX_PAGE_RANGES)
1164         num_ranges = MAX_PAGE_RANGES;
1165
1166       printdlgex->nPageRanges = num_ranges;
1167       for (i = 0; i < num_ranges; i++)
1168         {
1169           printdlgex->lpPageRanges[i].nFromPage = ranges[i].start + 1;
1170           printdlgex->lpPageRanges[i].nToPage = ranges[i].end + 1;
1171         }
1172     }
1173   
1174   printer = gtk_print_settings_get_printer (settings);
1175   if (printer)
1176     printdlgex->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
1177   
1178   printdlgex->hDevMode = devmode_from_settings (settings,
1179                                                 op->priv->default_page_setup);
1180 }
1181
1182 typedef struct {
1183   IPrintDialogCallback iPrintDialogCallback;
1184   gboolean set_hwnd;
1185   int ref_count;
1186 } PrintDialogCallback;
1187
1188
1189 static ULONG STDMETHODCALLTYPE
1190 iprintdialogcallback_addref (IPrintDialogCallback *This)
1191 {
1192   PrintDialogCallback *callback = (PrintDialogCallback *)This;
1193   return ++callback->ref_count;
1194 }
1195
1196 static ULONG STDMETHODCALLTYPE
1197 iprintdialogcallback_release (IPrintDialogCallback *This)
1198 {
1199   PrintDialogCallback *callback = (PrintDialogCallback *)This;
1200   int ref_count = --callback->ref_count;
1201
1202   if (ref_count == 0)
1203     g_free (This);
1204
1205   return ref_count;
1206 }
1207
1208 static HRESULT STDMETHODCALLTYPE
1209 iprintdialogcallback_queryinterface (IPrintDialogCallback *This,
1210                                      REFIID       riid,
1211                                      LPVOID      *ppvObject)
1212 {
1213    if (IsEqualIID (riid, &IID_IUnknown) ||
1214        IsEqualIID (riid, &myIID_IPrintDialogCallback))
1215      {
1216        *ppvObject = This;
1217        IUnknown_AddRef ((IUnknown *)This);
1218        return NOERROR;
1219      }
1220    else
1221      {
1222        *ppvObject = NULL;
1223        return E_NOINTERFACE;
1224      }
1225 }
1226
1227 static HRESULT STDMETHODCALLTYPE
1228 iprintdialogcallback_initdone (IPrintDialogCallback *This)
1229 {
1230   return S_FALSE;
1231 }
1232
1233 static HRESULT STDMETHODCALLTYPE
1234 iprintdialogcallback_selectionchange (IPrintDialogCallback *This)
1235 {
1236   return S_FALSE;
1237 }
1238
1239 static HRESULT STDMETHODCALLTYPE
1240 iprintdialogcallback_handlemessage (IPrintDialogCallback *This,
1241                                     HWND hDlg,
1242                                     UINT uMsg,
1243                                     WPARAM wParam,
1244                                     LPARAM lParam,
1245                                     LRESULT *pResult)
1246 {
1247   PrintDialogCallback *callback = (PrintDialogCallback *)This;
1248
1249   if (!callback->set_hwnd)
1250     {
1251       gdk_win32_set_modal_dialog_libgtk_only (hDlg);
1252       callback->set_hwnd = TRUE;
1253       while (gtk_events_pending ())
1254         gtk_main_iteration ();
1255     }
1256   else if (uMsg == got_gdk_events_message)
1257     {
1258       while (gtk_events_pending ())
1259         gtk_main_iteration ();
1260       *pResult = TRUE;
1261       return S_OK;
1262     }
1263   
1264   *pResult = 0;
1265   return S_FALSE;
1266 }
1267
1268 static IPrintDialogCallbackVtbl ipdc_vtbl = {
1269   iprintdialogcallback_queryinterface,
1270   iprintdialogcallback_addref,
1271   iprintdialogcallback_release,
1272   iprintdialogcallback_initdone,
1273   iprintdialogcallback_selectionchange,
1274   iprintdialogcallback_handlemessage
1275 };
1276
1277 static IPrintDialogCallback *
1278 print_callback_new  (void)
1279 {
1280   PrintDialogCallback *callback;
1281
1282   callback = g_new0 (PrintDialogCallback, 1);
1283   callback->iPrintDialogCallback.lpVtbl = &ipdc_vtbl;
1284   callback->ref_count = 1;
1285   callback->set_hwnd = FALSE;
1286
1287   return &callback->iPrintDialogCallback;
1288 }
1289
1290 static  void
1291 plug_grab_notify (GtkWidget        *widget,
1292                   gboolean          was_grabbed,
1293                   GtkPrintOperation *op)
1294 {
1295   EnableWindow(GetAncestor (GDK_WINDOW_HWND (widget->window), GA_ROOT),
1296                was_grabbed);
1297 }
1298
1299
1300 static BOOL CALLBACK
1301 pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
1302 {
1303   GtkPrintOperation *op;
1304   GtkPrintOperationWin32 *op_win32;
1305   
1306   if (message == WM_INITDIALOG)
1307     {
1308       PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lparam;
1309       GtkWidget *plug;
1310
1311       op = GTK_PRINT_OPERATION ((gpointer)page->lParam);
1312       op_win32 = op->priv->platform_data;
1313
1314       SetWindowLongPtrW(wnd, GWLP_USERDATA, (LONG_PTR)op);
1315       
1316       plug = _gtk_win32_embed_widget_new ((GdkNativeWindow) wnd);
1317       gtk_window_set_modal (GTK_WINDOW (plug), TRUE);
1318       op_win32->embed_widget = plug;
1319       gtk_container_add (GTK_CONTAINER (plug), op->priv->custom_widget);
1320       gtk_widget_show (op->priv->custom_widget);
1321       gtk_widget_show (plug);
1322       gdk_window_focus (plug->window, GDK_CURRENT_TIME);
1323
1324       /* This dialog is modal, so we grab the embed widget */
1325       gtk_grab_add (plug);
1326
1327       /* When we lose the grab we need to disable the print dialog */
1328       g_signal_connect (plug, "grab-notify", G_CALLBACK (plug_grab_notify), op);
1329       return FALSE;
1330     }
1331   else if (message == WM_DESTROY)
1332     {
1333       op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
1334       op_win32 = op->priv->platform_data;
1335       
1336       g_signal_emit_by_name (op, "custom-widget-apply", op->priv->custom_widget);
1337       gtk_widget_destroy (op_win32->embed_widget);
1338       op_win32->embed_widget = NULL;
1339       op->priv->custom_widget = NULL;
1340     }
1341   else 
1342     {
1343       op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
1344       op_win32 = op->priv->platform_data;
1345
1346       return _gtk_win32_embed_widget_dialog_procedure (GTK_WIN32_EMBED_WIDGET (op_win32->embed_widget),
1347                                                        wnd, message, wparam, lparam);
1348     }
1349   
1350   return FALSE;
1351 }
1352
1353 static HPROPSHEETPAGE
1354 create_application_page (GtkPrintOperation *op)
1355 {
1356   HPROPSHEETPAGE hpage;
1357   PROPSHEETPAGEW page;
1358   DLGTEMPLATE *template;
1359   HGLOBAL htemplate;
1360   LONG base_units;
1361   WORD baseunitX, baseunitY;
1362   WORD *array;
1363   GtkRequisition requisition;
1364   const char *tab_label;
1365
1366   /* Make the template the size of the custom widget size request */
1367   gtk_widget_size_request (op->priv->custom_widget, &requisition);
1368       
1369   base_units = GetDialogBaseUnits();
1370   baseunitX = LOWORD(base_units);
1371   baseunitY = HIWORD(base_units);
1372   
1373   htemplate = GlobalAlloc (GMEM_MOVEABLE, 
1374                            sizeof (DLGTEMPLATE) + sizeof(WORD) * 3);
1375   template = GlobalLock (htemplate);
1376   template->style = WS_CHILDWINDOW | DS_CONTROL;
1377   template->dwExtendedStyle = WS_EX_CONTROLPARENT;
1378   template->cdit = 0;
1379   template->x = MulDiv(0, 4, baseunitX);
1380   template->y = MulDiv(0, 8, baseunitY);
1381   template->cx = MulDiv(requisition.width, 4, baseunitX);
1382   template->cy = MulDiv(requisition.height, 8, baseunitY);
1383   
1384   array = (WORD *) (template+1);
1385   *array++ = 0; /* menu */
1386   *array++ = 0; /* class */
1387   *array++ = 0; /* title */
1388   
1389   memset(&page, 0, sizeof (page));
1390   page.dwSize = sizeof (page);
1391   page.dwFlags = PSP_DLGINDIRECT | PSP_USETITLE | PSP_PREMATURE;
1392   page.hInstance = GetModuleHandle (NULL);
1393   page.pResource = template;
1394   
1395   tab_label = op->priv->custom_tab_label;
1396   if (tab_label == NULL)
1397     tab_label = g_get_application_name ();
1398   if (tab_label == NULL)
1399     tab_label = _("Application");
1400   page.pszTitle = g_utf8_to_utf16 (tab_label, 
1401                                    -1, NULL, NULL, NULL);
1402   page.pfnDlgProc = pageDlgProc;
1403   page.pfnCallback = NULL;
1404   page.lParam = (LPARAM) op;
1405   hpage = CreatePropertySheetPageW(&page);
1406   
1407   GlobalUnlock (htemplate);
1408   
1409   /* TODO: We're leaking htemplate here... */
1410   
1411   return hpage;
1412 }
1413
1414 static GtkPageSetup *
1415 create_page_setup (GtkPrintOperation *op)
1416 {
1417   GtkPrintOperationPrivate *priv = op->priv;
1418   GtkPageSetup *page_setup;
1419   GtkPrintSettings *settings;
1420   
1421   if (priv->default_page_setup)
1422     page_setup = gtk_page_setup_copy (priv->default_page_setup);
1423   else
1424     page_setup = gtk_page_setup_new ();
1425
1426   settings = priv->print_settings;
1427   if (settings)
1428     {
1429       GtkPaperSize *paper_size;
1430       
1431       if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
1432         gtk_page_setup_set_orientation (page_setup,
1433                                         gtk_print_settings_get_orientation (settings));
1434
1435
1436       paper_size = gtk_print_settings_get_paper_size (settings);
1437       if (paper_size)
1438         {
1439           gtk_page_setup_set_paper_size (page_setup, paper_size);
1440           gtk_paper_size_free (paper_size);
1441         }
1442
1443       /* TODO: Margins? */
1444     }
1445   
1446   return page_setup;
1447 }
1448
1449 GtkPrintOperationResult
1450 _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
1451                                                   gboolean show_dialog,
1452                                                   GtkWindow *parent,
1453                                                   gboolean *do_print)
1454 {
1455   HRESULT hResult;
1456   LPPRINTDLGEXW printdlgex = NULL;
1457   LPPRINTPAGERANGE page_ranges = NULL;
1458   HWND parentHWnd;
1459   GtkWidget *invisible = NULL;
1460   GtkPrintOperationResult result;
1461   GtkPrintOperationWin32 *op_win32;
1462   GtkPrintOperationPrivate *priv;
1463   IPrintDialogCallback *callback;
1464   HPROPSHEETPAGE prop_page;
1465   
1466   *do_print = FALSE;
1467
1468   priv = op->priv;
1469   
1470   op_win32 = g_new0 (GtkPrintOperationWin32, 1);
1471   priv->platform_data = op_win32;
1472   priv->free_platform_data = (GDestroyNotify) op_win32_free;
1473   
1474   if (parent == NULL)
1475     {
1476       invisible = gtk_invisible_new ();
1477       parentHWnd = get_parent_hwnd (invisible);
1478     }
1479   else 
1480     parentHWnd = get_parent_hwnd (GTK_WIDGET (parent));
1481
1482   printdlgex = (LPPRINTDLGEXW)GlobalAlloc (GPTR, sizeof (PRINTDLGEXW));
1483   if (!printdlgex)
1484     {
1485       result = GTK_PRINT_OPERATION_RESULT_ERROR;
1486       g_set_error (&priv->error,
1487                    GTK_PRINT_ERROR,
1488                    GTK_PRINT_ERROR_NOMEM,
1489                    _("Not enough free memory"));
1490       goto out;
1491     }      
1492
1493   printdlgex->lStructSize = sizeof(PRINTDLGEXW);
1494   printdlgex->hwndOwner = parentHWnd;
1495   printdlgex->hDevMode = NULL;
1496   printdlgex->hDevNames = NULL;
1497   printdlgex->hDC = NULL;
1498   printdlgex->Flags = PD_RETURNDC | PD_NOSELECTION;
1499   if (op->priv->current_page == -1)
1500     printdlgex->Flags |= PD_NOCURRENTPAGE;
1501   printdlgex->Flags2 = 0;
1502   printdlgex->ExclusionFlags = 0;
1503
1504   page_ranges = (LPPRINTPAGERANGE) GlobalAlloc (GPTR, 
1505                                                 MAX_PAGE_RANGES * sizeof (PRINTPAGERANGE));
1506   if (!page_ranges) 
1507     {
1508       result = GTK_PRINT_OPERATION_RESULT_ERROR;
1509       g_set_error (&priv->error,
1510                    GTK_PRINT_ERROR,
1511                    GTK_PRINT_ERROR_NOMEM,
1512                    _("Not enough free memory"));
1513       goto out;
1514     }
1515
1516   printdlgex->nPageRanges = 0;
1517   printdlgex->nMaxPageRanges = MAX_PAGE_RANGES;
1518   printdlgex->lpPageRanges = page_ranges;
1519   printdlgex->nMinPage = 1;
1520   if (op->priv->nr_of_pages != -1)
1521     printdlgex->nMaxPage = op->priv->nr_of_pages;
1522   else
1523     printdlgex->nMaxPage = 10000;
1524   printdlgex->nCopies = 1;
1525   printdlgex->hInstance = 0;
1526   printdlgex->lpPrintTemplateName = NULL;
1527   printdlgex->lpCallback = NULL;
1528
1529   g_signal_emit_by_name (op, "create-custom-widget",
1530                          &op->priv->custom_widget);
1531   if (op->priv->custom_widget) {
1532     prop_page = create_application_page (op);
1533     printdlgex->nPropertyPages = 1;
1534     printdlgex->lphPropertyPages = &prop_page;
1535   } else {
1536     printdlgex->nPropertyPages = 0;
1537     printdlgex->lphPropertyPages = NULL;
1538   }
1539   
1540   printdlgex->nStartPage = START_PAGE_GENERAL;
1541   printdlgex->dwResultAction = 0;
1542
1543   dialog_from_print_settings (op, printdlgex);
1544
1545   callback = print_callback_new ();
1546   printdlgex->lpCallback = (IUnknown *)callback;
1547   got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
1548
1549   hResult = PrintDlgExW(printdlgex);
1550   IUnknown_Release ((IUnknown *)callback);
1551   gdk_win32_set_modal_dialog_libgtk_only (NULL);
1552
1553   if (hResult != S_OK) 
1554     {
1555       result = GTK_PRINT_OPERATION_RESULT_ERROR;
1556       if (hResult == E_OUTOFMEMORY)
1557         g_set_error (&priv->error,
1558                      GTK_PRINT_ERROR,
1559                      GTK_PRINT_ERROR_NOMEM,
1560                      _("Not enough free memory"));
1561       else if (hResult == E_INVALIDARG)
1562         g_set_error (&priv->error,
1563                      GTK_PRINT_ERROR,
1564                      GTK_PRINT_ERROR_INTERNAL_ERROR,
1565                      _("Invalid argument to PrintDlgEx"));
1566       else if (hResult == E_POINTER)
1567         g_set_error (&priv->error,
1568                      GTK_PRINT_ERROR,
1569                      GTK_PRINT_ERROR_INTERNAL_ERROR,
1570                      _("Invalid pointer to PrintDlgEx"));
1571       else if (hResult == E_HANDLE)
1572         g_set_error (&priv->error,
1573                      GTK_PRINT_ERROR,
1574                      GTK_PRINT_ERROR_INTERNAL_ERROR,
1575                      _("Invalid handle to PrintDlgEx"));
1576       else /* E_FAIL */
1577         g_set_error (&priv->error,
1578                      GTK_PRINT_ERROR,
1579                      GTK_PRINT_ERROR_GENERAL,
1580                      _("Unspecified error"));
1581       goto out;
1582     }
1583
1584   if (printdlgex->dwResultAction == PD_RESULT_PRINT ||
1585       printdlgex->dwResultAction == PD_RESULT_APPLY)
1586     {
1587       result = GTK_PRINT_OPERATION_RESULT_APPLY;
1588       dialog_to_print_settings (op, printdlgex);
1589     }
1590   else
1591     result = GTK_PRINT_OPERATION_RESULT_CANCEL;
1592   
1593   if (printdlgex->dwResultAction == PD_RESULT_PRINT)
1594     {
1595       DOCINFOW docinfo;
1596       int job_id;
1597       double dpi_x, dpi_y;
1598       cairo_t *cr;
1599       GtkPageSetup *page_setup;
1600
1601       priv->print_context = _gtk_print_context_new (op);
1602       page_setup = create_page_setup (op);
1603       _gtk_print_context_set_page_setup (priv->print_context, page_setup);
1604       g_object_unref (page_setup);
1605       
1606       *do_print = TRUE;
1607
1608       op_win32->surface = cairo_win32_printing_surface_create (printdlgex->hDC);
1609
1610       dpi_x = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSX);
1611       dpi_y = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSY);
1612
1613       cr = cairo_create (op_win32->surface);
1614       gtk_print_context_set_cairo_context (priv->print_context, cr, dpi_x, dpi_y);
1615       cairo_destroy (cr);
1616       
1617       memset( &docinfo, 0, sizeof (DOCINFOW));
1618       docinfo.cbSize = sizeof (DOCINFOW); 
1619       docinfo.lpszDocName = g_utf8_to_utf16 (op->priv->job_name, -1, NULL, NULL, NULL); 
1620       docinfo.lpszOutput = (LPCWSTR) NULL; 
1621       docinfo.lpszDatatype = (LPCWSTR) NULL; 
1622       docinfo.fwType = 0; 
1623
1624       job_id = StartDocW(printdlgex->hDC, &docinfo); 
1625       g_free ((void *)docinfo.lpszDocName);
1626       if (job_id <= 0) 
1627         {
1628           result = GTK_PRINT_OPERATION_RESULT_ERROR;
1629           g_set_error (&priv->error,
1630                        GTK_PRINT_ERROR,
1631                        GTK_PRINT_ERROR_GENERAL,
1632                      _("Error from StartDoc"));
1633           *do_print = FALSE;
1634           cairo_surface_destroy (op_win32->surface);
1635           op_win32->surface = NULL;
1636           goto out; 
1637         } 
1638       
1639       op_win32->hdc = printdlgex->hDC;
1640       op_win32->devmode = printdlgex->hDevMode;
1641       op_win32->devnames = printdlgex->hDevNames;
1642       op_win32->job_id = job_id;
1643       
1644       op->priv->print_pages = gtk_print_settings_get_print_pages (op->priv->print_settings);
1645       op->priv->num_page_ranges = 0;
1646       if (op->priv->print_pages == GTK_PRINT_PAGES_RANGES)
1647         op->priv->page_ranges = gtk_print_settings_get_page_ranges (op->priv->print_settings,
1648                                                                     &op->priv->num_page_ranges);
1649       op->priv->manual_num_copies = printdlgex->nCopies;
1650       op->priv->manual_collation = (printdlgex->Flags & PD_COLLATE) != 0;
1651       op->priv->manual_reverse = FALSE;
1652       op->priv->manual_orientation = FALSE;
1653       op->priv->manual_scale = 1.0;
1654       op->priv->manual_page_set = GTK_PAGE_SET_ALL;
1655     }
1656
1657   op->priv->start_page = win32_start_page;
1658   op->priv->end_page = win32_end_page;
1659   op->priv->end_run = win32_end_run;
1660   
1661   out:
1662   if (!*do_print && printdlgex && printdlgex->hDevMode != NULL) 
1663     GlobalFree(printdlgex->hDevMode); 
1664
1665   if (!*do_print && printdlgex && printdlgex->hDevNames != NULL) 
1666     GlobalFree(printdlgex->hDevNames); 
1667
1668   if (page_ranges)
1669     GlobalFree (page_ranges);
1670
1671   if (printdlgex)
1672     GlobalFree (printdlgex);
1673
1674   if (invisible)
1675     gtk_widget_destroy (invisible);
1676
1677   return result;
1678 }
1679
1680 void
1681 _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
1682                                                       cairo_surface_t   *surface,
1683                                                       GtkWindow         *parent,
1684                                                       const gchar       *filename)
1685 {
1686   HDC dc;
1687   HENHMETAFILE metafile;
1688   
1689   dc = cairo_win32_surface_get_dc (surface);
1690   cairo_surface_destroy (surface);
1691   metafile = CloseEnhMetaFile (dc);
1692   DeleteEnhMetaFile (metafile);
1693   
1694   ShellExecuteW (NULL, L"open", (gunichar2 *)filename, NULL, NULL, SW_SHOW);
1695 }
1696
1697 void
1698 _gtk_print_operation_platform_backend_preview_start_page (GtkPrintOperation *op,
1699                                                           cairo_surface_t *surface,
1700                                                           cairo_t *cr)
1701 {
1702   HDC dc = cairo_win32_surface_get_dc (surface);
1703   StartPage (dc);
1704 }
1705
1706 void
1707 _gtk_print_operation_platform_backend_preview_end_page (GtkPrintOperation *op,
1708                                                         cairo_surface_t *surface,
1709                                                         cairo_t *cr)
1710 {
1711   HDC dc;
1712
1713   cairo_surface_show_page (cr);
1714
1715   /* TODO: Enhanced metafiles don't support multiple pages.
1716    */
1717   dc = cairo_win32_surface_get_dc (surface);
1718   EndPage (dc);
1719 }
1720
1721 cairo_surface_t *
1722 _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *op,
1723                                                               GtkPageSetup      *page_setup,
1724                                                               gdouble           *dpi_x,
1725                                                               gdouble           *dpi_y,
1726                                                               gchar            **target)
1727 {
1728   GtkPaperSize *paper_size;
1729   double w, h;
1730   HDC metafile_dc;
1731   RECT rect;
1732   char *template;
1733   char *filename;
1734   gunichar2 *filename_utf16;
1735   int fd;
1736
1737   template = g_build_filename (g_get_tmp_dir (), "prXXXXXX", NULL);
1738   fd = g_mkstemp (template);
1739   close(fd);
1740
1741   filename = g_strconcat (template, ".emf", NULL);
1742   g_free (template);
1743   
1744   filename_utf16 = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
1745   g_free (filename);
1746
1747   paper_size = gtk_page_setup_get_paper_size (page_setup);
1748   w = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM);
1749   h = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM);
1750   
1751   rect.left = 0;
1752   rect.right = w*100;
1753   rect.top = 0;
1754   rect.bottom = h*100;
1755   
1756   metafile_dc = CreateEnhMetaFileW (NULL, filename_utf16,
1757                                     &rect, L"Gtk+\0Print Preview\0\0");
1758   if (metafile_dc == NULL)
1759     {
1760       g_warning ("Can't create metafile");
1761       return NULL;
1762     }
1763
1764   *target = (char *)filename_utf16;
1765   
1766   *dpi_x = (double)GetDeviceCaps (metafile_dc, LOGPIXELSX);
1767   *dpi_y = (double)GetDeviceCaps (metafile_dc, LOGPIXELSY);
1768
1769   return cairo_win32_printing_surface_create (metafile_dc);
1770 }
1771
1772 void
1773 _gtk_print_operation_platform_backend_resize_preview_surface (GtkPrintOperation *op,
1774                                                               GtkPageSetup      *page_setup,
1775                                                               cairo_surface_t   *surface)
1776 {
1777   /* TODO: Implement */
1778 }
1779
1780 GtkPageSetup *
1781 gtk_print_run_page_setup_dialog (GtkWindow        *parent,
1782                                  GtkPageSetup     *page_setup,
1783                                  GtkPrintSettings *settings)
1784 {
1785   LPPAGESETUPDLGW pagesetupdlg = NULL;
1786   BOOL res;
1787   gboolean free_settings;
1788   const char *printer;
1789   GtkPaperSize *paper_size;
1790   DWORD measure_system;
1791   GtkUnit unit;
1792   double scale;
1793
1794   pagesetupdlg = (LPPAGESETUPDLGW)GlobalAlloc (GPTR, sizeof (PAGESETUPDLGW));
1795   if (!pagesetupdlg)
1796     return NULL;
1797
1798   free_settings = FALSE;
1799   if (settings == NULL)
1800     {
1801       settings = gtk_print_settings_new ();
1802       free_settings = TRUE;
1803     }
1804   
1805   memset (pagesetupdlg, 0, sizeof (PAGESETUPDLGW));
1806
1807   pagesetupdlg->lStructSize = sizeof(PAGESETUPDLGW);
1808
1809   if (parent != NULL)
1810     pagesetupdlg->hwndOwner = get_parent_hwnd (GTK_WIDGET (parent));
1811   else
1812     pagesetupdlg->hwndOwner = NULL;
1813
1814   pagesetupdlg->Flags = PSD_DEFAULTMINMARGINS;
1815   pagesetupdlg->hDevMode = devmode_from_settings (settings, page_setup);
1816   pagesetupdlg->hDevNames = NULL;
1817   printer = gtk_print_settings_get_printer (settings);
1818   if (printer)
1819     pagesetupdlg->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
1820
1821   GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IMEASURE|LOCALE_RETURN_NUMBER,
1822                  (LPWSTR)&measure_system, sizeof (DWORD));
1823
1824   if (measure_system == 0)
1825     {
1826       pagesetupdlg->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
1827       unit = GTK_UNIT_MM;
1828       scale = 100;
1829     }
1830   else
1831     {
1832       pagesetupdlg->Flags |= PSD_INTHOUSANDTHSOFINCHES;
1833       unit = GTK_UNIT_INCH;
1834       scale = 1000;
1835     }
1836
1837   /* This is the object we return, we allocate it here so that
1838    * we can use the default page margins */
1839   if (page_setup)
1840     page_setup = gtk_page_setup_copy (page_setup);
1841   else
1842     page_setup = gtk_page_setup_new ();
1843   
1844   pagesetupdlg->Flags |= PSD_MARGINS;
1845   pagesetupdlg->rtMargin.left =
1846     floor (gtk_page_setup_get_left_margin (page_setup, unit) * scale + 0.5);
1847   pagesetupdlg->rtMargin.right =
1848     floor (gtk_page_setup_get_right_margin (page_setup, unit) * scale + 0.5);
1849   pagesetupdlg->rtMargin.top = 
1850     floor (gtk_page_setup_get_top_margin (page_setup, unit) * scale + 0.5);
1851   pagesetupdlg->rtMargin.bottom =
1852     floor (gtk_page_setup_get_bottom_margin (page_setup, unit) * scale + 0.5);
1853
1854   pagesetupdlg->Flags |= PSD_ENABLEPAGESETUPHOOK;
1855   pagesetupdlg->lpfnPageSetupHook = run_mainloop_hook;
1856   got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
1857   
1858   res = PageSetupDlgW (pagesetupdlg);
1859   gdk_win32_set_modal_dialog_libgtk_only (NULL);
1860
1861   if (res)
1862     {  
1863       if (pagesetupdlg->hDevNames != NULL)
1864         devnames_to_settings (settings, pagesetupdlg->hDevNames);
1865
1866       if (pagesetupdlg->hDevMode != NULL)
1867         devmode_to_settings (settings, pagesetupdlg->hDevMode);
1868     }
1869   
1870   if (free_settings)
1871     g_object_unref (settings);
1872
1873   if (res)
1874     {
1875       gtk_page_setup_set_orientation (page_setup, 
1876                                       gtk_print_settings_get_orientation (settings));
1877       paper_size = gtk_print_settings_get_paper_size (settings);
1878       if (paper_size)
1879         {
1880           gtk_page_setup_set_paper_size (page_setup, paper_size);
1881           gtk_paper_size_free (paper_size);
1882         }
1883
1884       if (pagesetupdlg->Flags & PSD_INHUNDREDTHSOFMILLIMETERS)
1885         {
1886           unit = GTK_UNIT_MM;
1887           scale = 100;
1888         }
1889       else
1890         {
1891           unit = GTK_UNIT_INCH;
1892           scale = 1000;
1893         }
1894
1895       gtk_page_setup_set_left_margin (page_setup,
1896                                       pagesetupdlg->rtMargin.left / scale,
1897                                       unit);
1898       gtk_page_setup_set_right_margin (page_setup,
1899                                        pagesetupdlg->rtMargin.right / scale,
1900                                        unit);
1901       gtk_page_setup_set_top_margin (page_setup,
1902                                      pagesetupdlg->rtMargin.top / scale,
1903                                      unit);
1904       gtk_page_setup_set_bottom_margin (page_setup,
1905                                         pagesetupdlg->rtMargin.bottom / scale,
1906                                         unit);
1907     }
1908   
1909   return page_setup;
1910 }
1911
1912 void
1913 gtk_print_run_page_setup_dialog_async (GtkWindow            *parent,
1914                                        GtkPageSetup         *page_setup,
1915                                        GtkPrintSettings     *settings,
1916                                        GtkPageSetupDoneFunc  done_cb,
1917                                        gpointer              data)
1918 {
1919   GtkPageSetup *new_page_setup;
1920
1921   new_page_setup = gtk_print_run_page_setup_dialog (parent, page_setup, settings);
1922   done_cb (new_page_setup, data);
1923   g_object_unref (new_page_setup);
1924 }
1925
1926 #define __GTK_PRINT_OPERATION_WIN32_C__
1927 #include "gtkaliasdef.c"