1 /* GTK - The GIMP Toolkit
2 * gtkprintoperation-win32.c: Print Operation Details for Win32
3 * Copyright (C) 2006, Red Hat, Inc.
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.
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.
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.
22 #define _WIN32_WINNT 0x0500
23 #define WINVER _WIN32_WINNT
30 #include <cairo-win32.h>
32 #include "gtkprintoperation-private.h"
33 #include "gtkprint-win32.h"
35 #include "gtkinvisible.h"
40 #include "gtkwin32embedwidget.h"
42 #define MAX_PAGE_RANGES 20
43 #define STATUS_POLLING_TIME 2000
45 #ifndef JOB_STATUS_RESTART
46 #define JOB_STATUS_RESTART 0x800
49 #ifndef JOB_STATUS_COMPLETE
50 #define JOB_STATUS_COMPLETE 0x1000
61 GtkWidget *embed_widget;
62 } GtkPrintOperationWin32;
64 static void win32_poll_status (GtkPrintOperation *op);
66 static const GUID myIID_IPrintDialogCallback = {0x5852a2c3,0x6530,0x11d1,{0xb6,0xa3,0x0,0x0,0xf8,0x75,0x7b,0xf9}};
69 #define INTERFACE IPrintDialogCallback
70 DECLARE_INTERFACE_ (IPrintDialogCallback, IUnknown)
72 STDMETHOD (QueryInterface)(THIS_ REFIID,LPVOID*) PURE;
73 STDMETHOD_ (ULONG, AddRef)(THIS) PURE;
74 STDMETHOD_ (ULONG, Release)(THIS) PURE;
75 STDMETHOD (InitDone)(THIS) PURE;
76 STDMETHOD (SelectionChange)(THIS) PURE;
77 STDMETHOD (HandleMessage)(THIS_ HWND,UINT,WPARAM,LPARAM,LRESULT*) PURE;
80 static UINT got_gdk_events_message;
83 run_mainloop_hook (HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
85 if (uiMsg == WM_INITDIALOG)
87 gdk_win32_set_modal_dialog_libgtk_only (hdlg);
88 while (gtk_events_pending ())
89 gtk_main_iteration ();
91 else if (uiMsg == got_gdk_events_message)
93 while (gtk_events_pending ())
94 gtk_main_iteration ();
100 static GtkPageOrientation
101 orientation_from_win32 (short orientation)
103 if (orientation == DMORIENT_LANDSCAPE)
104 return GTK_PAGE_ORIENTATION_LANDSCAPE;
105 return GTK_PAGE_ORIENTATION_PORTRAIT;
109 orientation_to_win32 (GtkPageOrientation orientation)
111 if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE ||
112 orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
113 return DMORIENT_LANDSCAPE;
114 return DMORIENT_PORTRAIT;
117 static GtkPaperSize *
118 paper_size_from_win32 (short size)
124 case DMPAPER_LETTER_TRANSVERSE:
126 case DMPAPER_LETTERSMALL:
129 case DMPAPER_TABLOID:
136 case DMPAPER_STATEMENT:
139 case DMPAPER_EXECUTIVE:
140 name = "na_executive";
143 case DMPAPER_A3_TRANSVERSE:
147 case DMPAPER_A4SMALL:
148 case DMPAPER_A4_TRANSVERSE:
152 case DMPAPER_A5_TRANSVERSE:
159 case DMPAPER_B5_TRANSVERSE:
175 name = "na_number-9";
178 name = "na_number-10";
181 name = "na_number-11";
184 name = "na_number-12";
187 name = "na_number-14";
213 case DMPAPER_ENV_C65:
225 case DMPAPER_ENV_ITALY:
228 case DMPAPER_ENV_MONARCH:
231 case DMPAPER_ENV_PERSONAL:
232 name = "na_personal";
234 case DMPAPER_FANFOLD_US:
235 name = "na_fanfold-us";
237 case DMPAPER_FANFOLD_STD_GERMAN:
238 name = "na_fanfold-eur";
240 case DMPAPER_FANFOLD_LGL_GERMAN:
241 name = "na_foolscap";
246 case DMPAPER_JAPANESE_POSTCARD:
255 case DMPAPER_ENV_INVITE:
258 case DMPAPER_LETTER_EXTRA:
259 case DMPAPER_LETTER_EXTRA_TRANSVERSE:
260 name = "na_letter-extra";
262 case DMPAPER_LEGAL_EXTRA:
263 name = "na_legal-extra";
265 case DMPAPER_TABLOID_EXTRA:
268 case DMPAPER_A4_EXTRA:
269 name = "iso_a4-extra";
274 case DMPAPER_LETTER_PLUS:
275 name = "na_letter-plus";
277 case DMPAPER_A3_EXTRA:
278 case DMPAPER_A3_EXTRA_TRANSVERSE:
279 name = "iso_a3-extra";
281 case DMPAPER_A5_EXTRA:
282 name = "iso_a5-extra";
284 case DMPAPER_B5_EXTRA:
285 name = "iso_b5-extra";
297 return gtk_paper_size_new (name);
303 paper_size_to_win32 (GtkPaperSize *paper_size)
307 if (gtk_paper_size_is_custom (paper_size))
310 format = gtk_paper_size_get_name (paper_size);
312 if (strcmp (format, "na_letter") == 0)
313 return DMPAPER_LETTER;
314 if (strcmp (format, "na_ledger") == 0)
315 return DMPAPER_LEDGER;
316 if (strcmp (format, "na_legal") == 0)
317 return DMPAPER_LEGAL;
318 if (strcmp (format, "na_invoice") == 0)
319 return DMPAPER_STATEMENT;
320 if (strcmp (format, "na_executive") == 0)
321 return DMPAPER_EXECUTIVE;
322 if (strcmp (format, "iso_a2") == 0)
324 if (strcmp (format, "iso_a3") == 0)
326 if (strcmp (format, "iso_a4") == 0)
328 if (strcmp (format, "iso_a5") == 0)
330 if (strcmp (format, "iso_b4") == 0)
332 if (strcmp (format, "iso_b5") == 0)
334 if (strcmp (format, "na_quarto") == 0)
335 return DMPAPER_QUARTO;
336 if (strcmp (format, "na_10x14") == 0)
337 return DMPAPER_10X14;
338 if (strcmp (format, "na_number-9") == 0)
339 return DMPAPER_ENV_9;
340 if (strcmp (format, "na_number-10") == 0)
341 return DMPAPER_ENV_10;
342 if (strcmp (format, "na_number-11") == 0)
343 return DMPAPER_ENV_11;
344 if (strcmp (format, "na_number-12") == 0)
345 return DMPAPER_ENV_12;
346 if (strcmp (format, "na_number-14") == 0)
347 return DMPAPER_ENV_14;
348 if (strcmp (format, "na_c") == 0)
349 return DMPAPER_CSHEET;
350 if (strcmp (format, "na_d") == 0)
351 return DMPAPER_DSHEET;
352 if (strcmp (format, "na_e") == 0)
353 return DMPAPER_ESHEET;
354 if (strcmp (format, "iso_dl") == 0)
355 return DMPAPER_ENV_DL;
356 if (strcmp (format, "iso_c3") == 0)
357 return DMPAPER_ENV_C3;
358 if (strcmp (format, "iso_c4") == 0)
359 return DMPAPER_ENV_C4;
360 if (strcmp (format, "iso_c5") == 0)
361 return DMPAPER_ENV_C5;
362 if (strcmp (format, "iso_c6") == 0)
363 return DMPAPER_ENV_C6;
364 if (strcmp (format, "iso_c5c6") == 0)
365 return DMPAPER_ENV_C65;
366 if (strcmp (format, "iso_b6") == 0)
367 return DMPAPER_ENV_B6;
368 if (strcmp (format, "om_italian") == 0)
369 return DMPAPER_ENV_ITALY;
370 if (strcmp (format, "na_monarch") == 0)
371 return DMPAPER_ENV_MONARCH;
372 if (strcmp (format, "na_personal") == 0)
373 return DMPAPER_ENV_PERSONAL;
374 if (strcmp (format, "na_fanfold-us") == 0)
375 return DMPAPER_FANFOLD_US;
376 if (strcmp (format, "na_fanfold-eur") == 0)
377 return DMPAPER_FANFOLD_STD_GERMAN;
378 if (strcmp (format, "na_foolscap") == 0)
379 return DMPAPER_FANFOLD_LGL_GERMAN;
380 if (strcmp (format, "jpn_hagaki") == 0)
381 return DMPAPER_JAPANESE_POSTCARD;
382 if (strcmp (format, "na_9x11") == 0)
384 if (strcmp (format, "na_10x11") == 0)
385 return DMPAPER_10X11;
386 if (strcmp (format, "om_invite") == 0)
387 return DMPAPER_ENV_INVITE;
388 if (strcmp (format, "na_letter-extra") == 0)
389 return DMPAPER_LETTER_EXTRA;
390 if (strcmp (format, "na_legal-extra") == 0)
391 return DMPAPER_LEGAL_EXTRA;
392 if (strcmp (format, "na_arch") == 0)
393 return DMPAPER_TABLOID_EXTRA;
394 if (strcmp (format, "iso_a3-extra") == 0)
395 return DMPAPER_A3_EXTRA;
396 if (strcmp (format, "iso_a4-extra") == 0)
397 return DMPAPER_A4_EXTRA;
398 if (strcmp (format, "iso_a5-extra") == 0)
399 return DMPAPER_A5_EXTRA;
400 if (strcmp (format, "iso_b5-extra") == 0)
401 return DMPAPER_B5_EXTRA;
402 if (strcmp (format, "na_b-plus") == 0)
403 return DMPAPER_B_PLUS;
404 if (strcmp (format, "na_letter-plus") == 0)
405 return DMPAPER_LETTER_PLUS;
411 win32_start_page (GtkPrintOperation *op,
412 GtkPrintContext *print_context,
413 GtkPageSetup *page_setup)
415 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
417 GtkPaperSize *paper_size;
419 devmode = GlobalLock (op_win32->devmode);
421 devmode->dmFields |= DM_ORIENTATION;
422 devmode->dmOrientation =
423 orientation_to_win32 (gtk_page_setup_get_orientation (page_setup));
425 paper_size = gtk_page_setup_get_paper_size (page_setup);
426 devmode->dmFields |= DM_PAPERSIZE;
427 devmode->dmFields &= ~(DM_PAPERWIDTH | DM_PAPERLENGTH);
428 devmode->dmPaperSize = paper_size_to_win32 (paper_size);
429 if (devmode->dmPaperSize == 0)
431 devmode->dmPaperSize = DMPAPER_USER;
432 devmode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
433 devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) * 10.0;
434 devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) * 10.0;
437 ResetDCW (op_win32->hdc, devmode);
439 GlobalUnlock (op_win32->devmode);
441 StartPage (op_win32->hdc);
445 win32_end_page (GtkPrintOperation *op,
446 GtkPrintContext *print_context)
448 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
449 EndPage (op_win32->hdc);
453 win32_poll_status_timeout (GtkPrintOperation *op)
455 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
457 op_win32->timeout_id = 0;
458 /* We need to ref this, as setting the status to finished
459 might unref the object */
461 win32_poll_status (op);
463 if (!gtk_print_operation_is_finished (op))
464 op_win32->timeout_id = g_timeout_add (STATUS_POLLING_TIME,
465 (GSourceFunc)win32_poll_status_timeout,
473 win32_end_run (GtkPrintOperation *op,
477 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
479 HANDLE printerHandle = 0;
481 EndDoc (op_win32->hdc);
483 if (op->priv->track_print_status)
485 devnames = GlobalLock (op_win32->devnames);
486 if (!OpenPrinterW (((gunichar2 *)devnames) + devnames->wDeviceOffset,
487 &printerHandle, NULL))
489 GlobalUnlock (op_win32->devnames);
492 GlobalFree(op_win32->devmode);
493 GlobalFree(op_win32->devnames);
495 cairo_surface_finish (op->priv->surface);
496 cairo_surface_destroy (op->priv->surface);
497 op->priv->surface = NULL;
499 DeleteDC(op_win32->hdc);
501 if (printerHandle != 0)
503 op_win32->printerHandle = printerHandle;
504 win32_poll_status (op);
505 op_win32->timeout_id = g_timeout_add (STATUS_POLLING_TIME,
506 (GSourceFunc)win32_poll_status_timeout,
510 /* Dunno what happened, pretend its finished */
511 _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
515 win32_poll_status (GtkPrintOperation *op)
517 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
520 JOB_INFO_1W *job_info;
521 GtkPrintStatus status;
525 GetJobW (op_win32->printerHandle, op_win32->job_id,
526 1,(LPBYTE)NULL, 0, &needed);
527 data = g_malloc (needed);
528 ret = GetJobW (op_win32->printerHandle, op_win32->job_id,
529 1, (LPBYTE)data, needed, &needed);
534 job_info = (JOB_INFO_1W *)data;
535 DWORD win32_status = job_info->Status;
537 if (job_info->pStatus)
538 status_str = g_utf16_to_utf8 (job_info->pStatus,
539 -1, NULL, NULL, NULL);
542 (JOB_STATUS_COMPLETE | JOB_STATUS_PRINTED))
543 status = GTK_PRINT_STATUS_FINISHED;
544 else if (win32_status &
545 (JOB_STATUS_OFFLINE |
546 JOB_STATUS_PAPEROUT |
548 JOB_STATUS_USER_INTERVENTION))
550 status = GTK_PRINT_STATUS_PENDING_ISSUE;
551 if (status_str == NULL)
553 if (win32_status & JOB_STATUS_OFFLINE)
554 status_str = g_strdup (_("Printer offline"));
555 else if (win32_status & JOB_STATUS_PAPEROUT)
556 status_str = g_strdup (_("Out of paper"));
557 else if (win32_status & JOB_STATUS_PAUSED)
558 status_str = g_strdup (_("Paused"));
559 else if (win32_status & JOB_STATUS_USER_INTERVENTION)
560 status_str = g_strdup (_("Need user intervention"));
563 else if (win32_status &
564 (JOB_STATUS_BLOCKED_DEVQ |
567 status = GTK_PRINT_STATUS_FINISHED_ABORTED;
568 else if (win32_status &
569 (JOB_STATUS_SPOOLING |
570 JOB_STATUS_DELETING))
571 status = GTK_PRINT_STATUS_PENDING;
572 else if (win32_status & JOB_STATUS_PRINTING)
573 status = GTK_PRINT_STATUS_PRINTING;
575 status = GTK_PRINT_STATUS_FINISHED;
578 status = GTK_PRINT_STATUS_FINISHED;
582 _gtk_print_operation_set_status (op, status, status_str);
588 op_win32_free (GtkPrintOperationWin32 *op_win32)
590 if (op_win32->printerHandle)
591 ClosePrinter (op_win32->printerHandle);
592 if (op_win32->timeout_id != 0)
593 g_source_remove (op_win32->timeout_id);
598 get_parent_hwnd (GtkWidget *widget)
600 gtk_widget_realize (widget);
601 return gdk_win32_drawable_get_handle (widget->window);
605 devnames_to_settings (GtkPrintSettings *settings,
608 GtkPrintWin32Devnames *devnames = gtk_print_win32_devnames_from_win32 (hDevNames);
609 gtk_print_settings_set_printer (settings, devnames->device);
610 gtk_print_win32_devnames_free (devnames);
614 devmode_to_settings (GtkPrintSettings *settings,
619 devmode = GlobalLock (hDevMode);
621 gtk_print_settings_set_int (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION,
622 devmode->dmDriverVersion);
623 if (devmode->dmDriverExtra != 0)
625 char *extra = g_base64_encode (((char *)devmode) + sizeof (DEVMODEW),
626 devmode->dmDriverExtra);
627 gtk_print_settings_set (settings,
628 GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA,
633 if (devmode->dmFields & DM_ORIENTATION)
634 gtk_print_settings_set_orientation (settings,
635 orientation_from_win32 (devmode->dmOrientation));
638 if (devmode->dmFields & DM_PAPERSIZE &&
639 devmode->dmPaperSize != 0)
641 GtkPaperSize *paper_size = paper_size_from_win32 (devmode->dmPaperSize);
644 gtk_print_settings_set_paper_size (settings, paper_size);
645 gtk_paper_size_free (paper_size);
647 gtk_print_settings_set_int (settings, "win32-paper-size", (int)devmode->dmPaperSize);
649 else if ((devmode->dmFields & DM_PAPERSIZE &&
650 devmode->dmPaperSize == 0) ||
651 ((devmode->dmFields & DM_PAPERWIDTH) &&
652 (devmode->dmFields & DM_PAPERLENGTH)))
654 GtkPaperSize *paper_size;
655 char *form_name = NULL;
656 if (devmode->dmFields & DM_FORMNAME)
657 form_name = g_utf16_to_utf8 (devmode->dmFormName,
658 -1, NULL, NULL, NULL);
659 if (form_name == NULL || form_name[0] == 0)
660 form_name = g_strdup (_("Custom size"));
661 paper_size = gtk_paper_size_new_custom (form_name,
663 devmode->dmPaperWidth * 10.0,
664 devmode->dmPaperLength * 10.0,
666 gtk_print_settings_set_paper_size (settings, paper_size);
667 gtk_paper_size_free (paper_size);
670 if (devmode->dmFields & DM_SCALE)
671 gtk_print_settings_set_scale (settings,
672 devmode->dmScale / 100.0);
674 if (devmode->dmFields & DM_COPIES)
675 gtk_print_settings_set_n_copies (settings,
678 if (devmode->dmFields & DM_DEFAULTSOURCE)
681 switch (devmode->dmDefaultSource)
693 case DMBIN_ENVMANUAL:
694 source = "envelope-manual";
708 case DMBIN_FORMSOURCE:
709 source = "form-source";
711 case DMBIN_LARGECAPACITY:
712 source = "large-capacity";
715 source = "large-format";
721 source = "small-format";
724 gtk_print_settings_set_default_source (settings, source);
725 gtk_print_settings_set_int (settings, "win32-default-source", devmode->dmDefaultSource);
728 if (devmode->dmFields & DM_PRINTQUALITY)
730 GtkPrintQuality quality;
731 switch (devmode->dmPrintQuality)
734 quality = GTK_PRINT_QUALITY_LOW;
737 quality = GTK_PRINT_QUALITY_NORMAL;
741 quality = GTK_PRINT_QUALITY_HIGH;
744 quality = GTK_PRINT_QUALITY_DRAFT;
747 gtk_print_settings_set_quality (settings, quality);
748 gtk_print_settings_set_int (settings, "win32-print-quality", devmode->dmPrintQuality);
751 if (devmode->dmFields & DM_COLOR)
752 gtk_print_settings_set_use_color (settings, devmode->dmFields == DMCOLOR_COLOR);
754 if (devmode->dmFields & DM_DUPLEX)
756 GtkPrintDuplex duplex;
757 switch (devmode->dmDuplex)
761 duplex = GTK_PRINT_DUPLEX_SIMPLEX;
763 case DMDUP_HORIZONTAL:
764 duplex = GTK_PRINT_DUPLEX_HORIZONTAL;
767 duplex = GTK_PRINT_DUPLEX_VERTICAL;
771 gtk_print_settings_set_duplex (settings, duplex);
774 if (devmode->dmFields & DM_COLLATE)
775 gtk_print_settings_set_collate (settings,
776 devmode->dmCollate == DMCOLLATE_TRUE);
778 if (devmode->dmFields & DM_MEDIATYPE)
781 switch (devmode->dmMediaType)
784 case DMMEDIA_STANDARD:
785 media_type = "stationery";
787 case DMMEDIA_TRANSPARENCY:
788 media_type = "transparency";
791 media_type = "photographic-glossy";
794 gtk_print_settings_set_media_type (settings, media_type);
795 gtk_print_settings_set_int (settings, "win32-media-type", devmode->dmMediaType);
798 if (devmode->dmFields & DM_DITHERTYPE)
801 switch (devmode->dmDitherType)
810 case DMDITHER_COARSE:
813 case DMDITHER_LINEART:
816 case DMDITHER_GRAYSCALE:
817 dither = "grayscale";
819 case DMDITHER_ERRORDIFFUSION:
820 dither = "error-diffusion";
823 gtk_print_settings_set_dither (settings, dither);
824 gtk_print_settings_set_int (settings, "win32-dither-type", devmode->dmDitherType);
827 GlobalUnlock (hDevMode);
831 dialog_to_print_settings (GtkPrintOperation *op,
832 LPPRINTDLGEXW printdlgex)
835 GtkPrintSettings *settings;
837 settings = gtk_print_settings_new ();
839 gtk_print_settings_set_print_pages (settings,
840 GTK_PRINT_PAGES_ALL);
841 if (printdlgex->Flags & PD_CURRENTPAGE)
842 gtk_print_settings_set_print_pages (settings,
843 GTK_PRINT_PAGES_CURRENT);
844 else if (printdlgex->Flags & PD_PAGENUMS)
845 gtk_print_settings_set_print_pages (settings,
846 GTK_PRINT_PAGES_RANGES);
848 if (printdlgex->nPageRanges > 0)
850 GtkPageRange *ranges;
851 ranges = g_new (GtkPageRange, printdlgex->nPageRanges);
853 for (i = 0; i < printdlgex->nPageRanges; i++)
855 ranges[i].start = printdlgex->lpPageRanges[i].nFromPage - 1;
856 ranges[i].end = printdlgex->lpPageRanges[i].nToPage - 1;
859 gtk_print_settings_set_page_ranges (settings, ranges,
860 printdlgex->nPageRanges);
864 if (printdlgex->hDevNames != NULL)
865 devnames_to_settings (settings, printdlgex->hDevNames);
867 if (printdlgex->hDevMode != NULL)
868 devmode_to_settings (settings, printdlgex->hDevMode);
870 gtk_print_operation_set_print_settings (op, settings);
874 devmode_from_settings (GtkPrintSettings *settings,
875 GtkPageSetup *page_setup)
880 GtkPaperSize *paper_size;
881 const char *extras_base64;
887 extras_base64 = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA);
889 extras = g_base64_decode (extras_base64, &extras_len);
891 hDevMode = GlobalAlloc (GMEM_MOVEABLE,
892 sizeof (DEVMODEW) + extras_len);
894 devmode = GlobalLock (hDevMode);
896 memset (devmode, 0, sizeof (DEVMODEW));
898 devmode->dmSpecVersion = DM_SPECVERSION;
899 devmode->dmSize = sizeof (DEVMODEW);
901 devmode->dmDriverExtra = 0;
902 if (extras && extras_len > 0)
904 devmode->dmDriverExtra = extras_len;
905 memcpy (((char *)devmode) + sizeof (DEVMODEW), extras, extras_len);
908 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION))
909 devmode->dmDriverVersion = gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION);
912 gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
914 GtkPageOrientation orientation = gtk_print_settings_get_orientation (settings);
916 orientation = gtk_page_setup_get_orientation (page_setup);
917 devmode->dmFields |= DM_ORIENTATION;
918 devmode->dmOrientation = orientation_to_win32 (orientation);
922 paper_size = gtk_paper_size_copy (gtk_page_setup_get_paper_size (page_setup));
926 if (gtk_print_settings_has_key (settings, "win32-paper-size") &&
927 (size = gtk_print_settings_get_int (settings, "win32-paper-size")) != 0)
929 devmode->dmFields |= DM_PAPERSIZE;
930 devmode->dmPaperSize = size;
934 paper_size = gtk_print_settings_get_paper_size (settings);
938 devmode->dmFields |= DM_PAPERSIZE;
939 devmode->dmPaperSize = paper_size_to_win32 (paper_size);
940 if (devmode->dmPaperSize == 0)
942 devmode->dmPaperSize = DMPAPER_USER;
943 devmode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
944 devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) / 10.0;
945 devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) / 10.0;
947 gtk_paper_size_free (paper_size);
950 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_SCALE))
952 devmode->dmFields |= DM_SCALE;
953 devmode->dmScale = gtk_print_settings_get_scale (settings) * 100;
956 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_N_COPIES))
958 devmode->dmFields |= DM_COPIES;
959 devmode->dmCopies = gtk_print_settings_get_n_copies (settings);
962 if (gtk_print_settings_has_key (settings, "win32-default-source"))
964 devmode->dmFields |= DM_DEFAULTSOURCE;
965 devmode->dmDefaultSource = gtk_print_settings_get_int (settings, "win32-default-source");
967 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE))
969 devmode->dmFields |= DM_DEFAULTSOURCE;
970 devmode->dmDefaultSource = DMBIN_AUTO;
972 val = gtk_print_settings_get_default_source (settings);
973 if (strcmp (val, "auto") == 0)
974 devmode->dmDefaultSource = DMBIN_AUTO;
975 if (strcmp (val, "cassette") == 0)
976 devmode->dmDefaultSource = DMBIN_CASSETTE;
977 if (strcmp (val, "envelope") == 0)
978 devmode->dmDefaultSource = DMBIN_ENVELOPE;
979 if (strcmp (val, "envelope-manual") == 0)
980 devmode->dmDefaultSource = DMBIN_ENVMANUAL;
981 if (strcmp (val, "lower") == 0)
982 devmode->dmDefaultSource = DMBIN_LOWER;
983 if (strcmp (val, "manual") == 0)
984 devmode->dmDefaultSource = DMBIN_MANUAL;
985 if (strcmp (val, "middle") == 0)
986 devmode->dmDefaultSource = DMBIN_MIDDLE;
987 if (strcmp (val, "only-one") == 0)
988 devmode->dmDefaultSource = DMBIN_ONLYONE;
989 if (strcmp (val, "form-source") == 0)
990 devmode->dmDefaultSource = DMBIN_FORMSOURCE;
991 if (strcmp (val, "large-capacity") == 0)
992 devmode->dmDefaultSource = DMBIN_LARGECAPACITY;
993 if (strcmp (val, "large-format") == 0)
994 devmode->dmDefaultSource = DMBIN_LARGEFMT;
995 if (strcmp (val, "tractor") == 0)
996 devmode->dmDefaultSource = DMBIN_TRACTOR;
997 if (strcmp (val, "small-format") == 0)
998 devmode->dmDefaultSource = DMBIN_SMALLFMT;
1001 if (gtk_print_settings_has_key (settings, "win32-print-quality"))
1003 devmode->dmFields |= DM_PRINTQUALITY;
1004 devmode->dmPrintQuality = gtk_print_settings_get_int (settings, "win32-print-quality");
1006 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_RESOLUTION))
1008 devmode->dmFields |= DM_PRINTQUALITY;
1009 devmode->dmPrintQuality = gtk_print_settings_get_resolution (settings);
1011 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_QUALITY))
1013 devmode->dmFields |= DM_PRINTQUALITY;
1014 switch (gtk_print_settings_get_quality (settings))
1016 case GTK_PRINT_QUALITY_LOW:
1017 devmode->dmPrintQuality = DMRES_LOW;
1019 case GTK_PRINT_QUALITY_DRAFT:
1020 devmode->dmPrintQuality = DMRES_DRAFT;
1023 case GTK_PRINT_QUALITY_NORMAL:
1024 devmode->dmPrintQuality = DMRES_MEDIUM;
1026 case GTK_PRINT_QUALITY_HIGH:
1027 devmode->dmPrintQuality = DMRES_HIGH;
1032 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_USE_COLOR))
1034 devmode->dmFields |= DM_COLOR;
1035 if (gtk_print_settings_get_use_color (settings))
1036 devmode->dmColor = DMCOLOR_COLOR;
1038 devmode->dmColor = DMCOLOR_MONOCHROME;
1041 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DUPLEX))
1043 devmode->dmFields |= DM_DUPLEX;
1044 switch (gtk_print_settings_get_duplex (settings))
1047 case GTK_PRINT_DUPLEX_SIMPLEX:
1048 devmode->dmDuplex = DMDUP_SIMPLEX;
1050 case GTK_PRINT_DUPLEX_HORIZONTAL:
1051 devmode->dmDuplex = DMDUP_HORIZONTAL;
1053 case GTK_PRINT_DUPLEX_VERTICAL:
1054 devmode->dmDuplex = DMDUP_VERTICAL;
1059 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_COLLATE))
1061 devmode->dmFields |= DM_COLLATE;
1062 if (gtk_print_settings_get_collate (settings))
1063 devmode->dmCollate = DMCOLLATE_TRUE;
1065 devmode->dmCollate = DMCOLLATE_FALSE;
1068 if (gtk_print_settings_has_key (settings, "win32-media-type"))
1070 devmode->dmFields |= DM_MEDIATYPE;
1071 devmode->dmMediaType = gtk_print_settings_get_int (settings, "win32-media-type");
1073 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_MEDIA_TYPE))
1075 devmode->dmFields |= DM_MEDIATYPE;
1076 devmode->dmMediaType = DMMEDIA_STANDARD;
1078 val = gtk_print_settings_get_media_type (settings);
1079 if (strcmp (val, "transparency") == 0)
1080 devmode->dmMediaType = DMMEDIA_TRANSPARENCY;
1081 if (strcmp (val, "photographic-glossy") == 0)
1082 devmode->dmMediaType = DMMEDIA_GLOSSY;
1085 if (gtk_print_settings_has_key (settings, "win32-dither-type"))
1087 devmode->dmFields |= DM_DITHERTYPE;
1088 devmode->dmDitherType = gtk_print_settings_get_int (settings, "win32-dither-type");
1090 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DITHER))
1092 devmode->dmFields |= DM_DITHERTYPE;
1093 devmode->dmDitherType = DMDITHER_FINE;
1095 val = gtk_print_settings_get_dither (settings);
1096 if (strcmp (val, "none") == 0)
1097 devmode->dmDitherType = DMDITHER_NONE;
1098 if (strcmp (val, "coarse") == 0)
1099 devmode->dmDitherType = DMDITHER_COARSE;
1100 if (strcmp (val, "fine") == 0)
1101 devmode->dmDitherType = DMDITHER_FINE;
1102 if (strcmp (val, "lineart") == 0)
1103 devmode->dmDitherType = DMDITHER_LINEART;
1104 if (strcmp (val, "grayscale") == 0)
1105 devmode->dmDitherType = DMDITHER_GRAYSCALE;
1106 if (strcmp (val, "error-diffusion") == 0)
1107 devmode->dmDitherType = DMDITHER_ERRORDIFFUSION;
1110 GlobalUnlock (hDevMode);
1116 dialog_from_print_settings (GtkPrintOperation *op,
1117 LPPRINTDLGEXW printdlgex)
1119 GtkPrintSettings *settings = op->priv->print_settings;
1120 const char *printer;
1122 if (settings == NULL)
1125 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_PRINT_PAGES))
1127 GtkPrintPages print_pages = gtk_print_settings_get_print_pages (settings);
1129 switch (print_pages)
1132 case GTK_PRINT_PAGES_ALL:
1133 printdlgex->Flags |= PD_ALLPAGES;
1135 case GTK_PRINT_PAGES_CURRENT:
1136 printdlgex->Flags |= PD_CURRENTPAGE;
1138 case GTK_PRINT_PAGES_RANGES:
1139 printdlgex->Flags |= PD_PAGENUMS;
1143 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_PAGE_RANGES))
1145 GtkPageRange *ranges;
1148 ranges = gtk_print_settings_get_page_ranges (settings, &num_ranges);
1150 if (num_ranges > MAX_PAGE_RANGES)
1151 num_ranges = MAX_PAGE_RANGES;
1153 printdlgex->nPageRanges = num_ranges;
1154 for (i = 0; i < num_ranges; i++)
1156 printdlgex->lpPageRanges[i].nFromPage = ranges[i].start + 1;
1157 printdlgex->lpPageRanges[i].nToPage = ranges[i].end + 1;
1161 printer = gtk_print_settings_get_printer (settings);
1163 printdlgex->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
1165 printdlgex->hDevMode = devmode_from_settings (settings,
1166 op->priv->default_page_setup);
1170 IPrintDialogCallback iPrintDialogCallback;
1173 } PrintDialogCallback;
1176 static ULONG STDMETHODCALLTYPE
1177 iprintdialogcallback_addref (IPrintDialogCallback *This)
1179 PrintDialogCallback *callback = (PrintDialogCallback *)This;
1180 return ++callback->ref_count;
1183 static ULONG STDMETHODCALLTYPE
1184 iprintdialogcallback_release (IPrintDialogCallback *This)
1186 PrintDialogCallback *callback = (PrintDialogCallback *)This;
1187 int ref_count = --callback->ref_count;
1195 static HRESULT STDMETHODCALLTYPE
1196 iprintdialogcallback_queryinterface (IPrintDialogCallback *This,
1200 if (IsEqualIID (riid, &IID_IUnknown) ||
1201 IsEqualIID (riid, &myIID_IPrintDialogCallback))
1204 IUnknown_AddRef ((IUnknown *)This);
1210 return E_NOINTERFACE;
1214 static HRESULT STDMETHODCALLTYPE
1215 iprintdialogcallback_initdone (IPrintDialogCallback *This)
1220 static HRESULT STDMETHODCALLTYPE
1221 iprintdialogcallback_selectionchange (IPrintDialogCallback *This)
1226 static HRESULT STDMETHODCALLTYPE
1227 iprintdialogcallback_handlemessage (IPrintDialogCallback *This,
1234 PrintDialogCallback *callback = (PrintDialogCallback *)This;
1236 if (!callback->set_hwnd)
1238 gdk_win32_set_modal_dialog_libgtk_only (hDlg);
1239 callback->set_hwnd = TRUE;
1240 while (gtk_events_pending ())
1241 gtk_main_iteration ();
1243 else if (uMsg == got_gdk_events_message)
1245 while (gtk_events_pending ())
1246 gtk_main_iteration ();
1255 static IPrintDialogCallbackVtbl ipdc_vtbl = {
1256 iprintdialogcallback_queryinterface,
1257 iprintdialogcallback_addref,
1258 iprintdialogcallback_release,
1259 iprintdialogcallback_initdone,
1260 iprintdialogcallback_selectionchange,
1261 iprintdialogcallback_handlemessage
1264 static IPrintDialogCallback *
1265 print_callback_new (void)
1267 PrintDialogCallback *callback;
1269 callback = g_new0 (PrintDialogCallback, 1);
1270 callback->iPrintDialogCallback.lpVtbl = &ipdc_vtbl;
1271 callback->ref_count = 1;
1272 callback->set_hwnd = FALSE;
1274 return &callback->iPrintDialogCallback;
1278 plug_grab_notify (GtkWidget *widget,
1279 gboolean was_grabbed,
1280 GtkPrintOperation *op)
1282 EnableWindow(GetAncestor (GDK_WINDOW_HWND (widget->window), GA_ROOT),
1287 static BOOL CALLBACK
1288 pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
1290 GtkPrintOperation *op;
1291 GtkPrintOperationWin32 *op_win32;
1293 if (message == WM_INITDIALOG)
1295 PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lparam;
1298 op = GTK_PRINT_OPERATION ((gpointer)page->lParam);
1299 op_win32 = op->priv->platform_data;
1301 SetWindowLongPtrW(wnd, GWLP_USERDATA, (LONG_PTR)op);
1303 plug = _gtk_win32_embed_widget_new ((GdkNativeWindow) wnd);
1304 op_win32->embed_widget = plug;
1305 gtk_container_add (GTK_CONTAINER (plug), op->priv->custom_widget);
1306 gtk_widget_show (op->priv->custom_widget);
1307 gtk_widget_show (plug);
1308 gdk_window_focus (plug->window, GDK_CURRENT_TIME);
1310 /* This dialog is modal, so we grab the embed widget */
1311 gtk_grab_add (plug);
1313 /* When we lose the grab we need to disable the print dialog */
1314 g_signal_connect (plug, "grab-notify", G_CALLBACK (plug_grab_notify), op);
1317 else if (message == WM_DESTROY)
1319 op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
1320 op_win32 = op->priv->platform_data;
1322 g_signal_emit_by_name (op, "custom-widget-apply", op->priv->custom_widget);
1323 gtk_widget_destroy (op_win32->embed_widget);
1324 op_win32->embed_widget = NULL;
1325 op->priv->custom_widget = NULL;
1329 op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
1330 op_win32 = op->priv->platform_data;
1332 return _gtk_win32_embed_widget_dialog_procedure (GTK_WIN32_EMBED_WIDGET (op_win32->embed_widget),
1333 wnd, message, wparam, lparam);
1339 static HPROPSHEETPAGE
1340 create_application_page (GtkPrintOperation *op)
1342 HPROPSHEETPAGE hpage;
1343 PROPSHEETPAGEW page;
1344 DLGTEMPLATE *template;
1347 WORD baseunitX, baseunitY;
1349 GtkRequisition requisition;
1350 const char *app_name;
1352 /* Make the template the size of the custom widget size request */
1353 gtk_widget_size_request (op->priv->custom_widget, &requisition);
1355 base_units = GetDialogBaseUnits();
1356 baseunitX = LOWORD(base_units);
1357 baseunitY = HIWORD(base_units);
1359 htemplate = GlobalAlloc (GMEM_MOVEABLE,
1360 sizeof (DLGTEMPLATE) + sizeof(WORD) * 3);
1361 template = GlobalLock (htemplate);
1362 template->style = WS_CHILDWINDOW | DS_CONTROL;
1363 template->dwExtendedStyle = WS_EX_CONTROLPARENT;
1365 template->x = MulDiv(0, 4, baseunitX);
1366 template->y = MulDiv(0, 8, baseunitY);
1367 template->cx = MulDiv(requisition.width, 4, baseunitX);
1368 template->cy = MulDiv(requisition.height, 8, baseunitY);
1370 array = (WORD *) (template+1);
1371 *array++ = 0; /* menu */
1372 *array++ = 0; /* class */
1373 *array++ = 0; /* title */
1375 memset(&page, 0, sizeof (page));
1376 page.dwSize = sizeof (page);
1377 page.dwFlags = PSP_DLGINDIRECT | PSP_USETITLE | PSP_PREMATURE;
1378 page.hInstance = GetModuleHandle (NULL);
1379 page.pResource = template;
1380 app_name = g_get_application_name ();
1381 if (app_name == NULL)
1382 app_name = _("Application");
1383 page.pszTitle = g_utf8_to_utf16 (app_name,
1384 -1, NULL, NULL, NULL);
1385 page.pfnDlgProc = pageDlgProc;
1386 page.pfnCallback = NULL;
1387 page.lParam = (LPARAM) op;
1388 hpage = CreatePropertySheetPageW(&page);
1390 GlobalUnlock (htemplate);
1392 /* TODO: We're leaking htemplate here... */
1397 GtkPrintOperationResult
1398 _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
1404 LPPRINTDLGEXW printdlgex = NULL;
1405 LPPRINTPAGERANGE page_ranges = NULL;
1407 GtkWidget *invisible = NULL;
1408 GtkPrintOperationResult result;
1409 GtkPrintOperationWin32 *op_win32;
1410 IPrintDialogCallback *callback;
1411 HPROPSHEETPAGE prop_page;
1415 op_win32 = g_new0 (GtkPrintOperationWin32, 1);
1416 op->priv->platform_data = op_win32;
1417 op->priv->free_platform_data = (GDestroyNotify) op_win32_free;
1421 invisible = gtk_invisible_new ();
1422 parentHWnd = get_parent_hwnd (invisible);
1425 parentHWnd = get_parent_hwnd (GTK_WIDGET (parent));
1427 printdlgex = (LPPRINTDLGEXW)GlobalAlloc (GPTR, sizeof (PRINTDLGEXW));
1430 result = GTK_PRINT_OPERATION_RESULT_ERROR;
1433 GTK_PRINT_ERROR_NOMEM,
1434 _("Not enough free memory"));
1438 printdlgex->lStructSize = sizeof(PRINTDLGEXW);
1439 printdlgex->hwndOwner = parentHWnd;
1440 printdlgex->hDevMode = NULL;
1441 printdlgex->hDevNames = NULL;
1442 printdlgex->hDC = NULL;
1443 printdlgex->Flags = PD_RETURNDC | PD_NOSELECTION;
1444 if (op->priv->current_page == -1)
1445 printdlgex->Flags |= PD_NOCURRENTPAGE;
1446 printdlgex->Flags2 = 0;
1447 printdlgex->ExclusionFlags = 0;
1449 page_ranges = (LPPRINTPAGERANGE) GlobalAlloc (GPTR,
1450 MAX_PAGE_RANGES * sizeof (PRINTPAGERANGE));
1453 result = GTK_PRINT_OPERATION_RESULT_ERROR;
1456 GTK_PRINT_ERROR_NOMEM,
1457 _("Not enough free memory"));
1461 printdlgex->nPageRanges = 0;
1462 printdlgex->nMaxPageRanges = MAX_PAGE_RANGES;
1463 printdlgex->lpPageRanges = page_ranges;
1464 printdlgex->nMinPage = 1;
1465 if (op->priv->nr_of_pages != -1)
1466 printdlgex->nMaxPage = op->priv->nr_of_pages;
1468 printdlgex->nMaxPage = 10000;
1469 printdlgex->nCopies = 1;
1470 printdlgex->hInstance = 0;
1471 printdlgex->lpPrintTemplateName = NULL;
1472 printdlgex->lpCallback = NULL;
1474 g_signal_emit_by_name (op, "create-custom-widget",
1475 &op->priv->custom_widget);
1476 if (op->priv->custom_widget) {
1477 prop_page = create_application_page (op);
1478 printdlgex->nPropertyPages = 1;
1479 printdlgex->lphPropertyPages = &prop_page;
1481 printdlgex->nPropertyPages = 0;
1482 printdlgex->lphPropertyPages = NULL;
1485 printdlgex->nStartPage = START_PAGE_GENERAL;
1486 printdlgex->dwResultAction = 0;
1488 dialog_from_print_settings (op, printdlgex);
1490 callback = print_callback_new ();
1491 printdlgex->lpCallback = (IUnknown *)callback;
1492 got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
1494 hResult = PrintDlgExW(printdlgex);
1495 IUnknown_Release ((IUnknown *)callback);
1496 gdk_win32_set_modal_dialog_libgtk_only (NULL);
1498 if (hResult != S_OK)
1500 result = GTK_PRINT_OPERATION_RESULT_ERROR;
1501 if (hResult == E_OUTOFMEMORY)
1504 GTK_PRINT_ERROR_NOMEM,
1505 _("Not enough free memory"));
1506 else if (hResult == E_INVALIDARG)
1509 GTK_PRINT_ERROR_INTERNAL_ERROR,
1510 _("Invalid argument to PrintDlgEx"));
1511 else if (hResult == E_POINTER)
1514 GTK_PRINT_ERROR_INTERNAL_ERROR,
1515 _("Invalid pointer to PrintDlgEx"));
1516 else if (hResult == E_HANDLE)
1519 GTK_PRINT_ERROR_INTERNAL_ERROR,
1520 _("Invalid handle to PrintDlgEx"));
1524 GTK_PRINT_ERROR_GENERAL,
1525 _("Unspecified error"));
1529 if (printdlgex->dwResultAction == PD_RESULT_PRINT ||
1530 printdlgex->dwResultAction == PD_RESULT_APPLY)
1532 result = GTK_PRINT_OPERATION_RESULT_APPLY;
1533 dialog_to_print_settings (op, printdlgex);
1536 result = GTK_PRINT_OPERATION_RESULT_CANCEL;
1538 if (printdlgex->dwResultAction == PD_RESULT_PRINT)
1545 op->priv->surface = cairo_win32_surface_create (printdlgex->hDC);
1546 op->priv->dpi_x = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSX);
1547 op->priv->dpi_y = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSY);
1549 memset( &docinfo, 0, sizeof (DOCINFOW));
1550 docinfo.cbSize = sizeof (DOCINFOW);
1551 docinfo.lpszDocName = g_utf8_to_utf16 (op->priv->job_name, -1, NULL, NULL, NULL);
1552 docinfo.lpszOutput = (LPCWSTR) NULL;
1553 docinfo.lpszDatatype = (LPCWSTR) NULL;
1556 job_id = StartDocW(printdlgex->hDC, &docinfo);
1557 g_free ((void *)docinfo.lpszDocName);
1560 result = GTK_PRINT_OPERATION_RESULT_ERROR;
1563 GTK_PRINT_ERROR_GENERAL,
1564 _("Error from StartDoc"));
1566 cairo_surface_destroy (op->priv->surface);
1567 op->priv->surface = NULL;
1571 op_win32->hdc = printdlgex->hDC;
1572 op_win32->devmode = printdlgex->hDevMode;
1573 op_win32->devnames = printdlgex->hDevNames;
1574 op_win32->job_id = job_id;
1576 op->priv->print_pages = gtk_print_settings_get_print_pages (op->priv->print_settings);
1577 op->priv->num_page_ranges = 0;
1578 if (op->priv->print_pages == GTK_PRINT_PAGES_RANGES)
1579 op->priv->page_ranges = gtk_print_settings_get_page_ranges (op->priv->print_settings,
1580 &op->priv->num_page_ranges);
1581 op->priv->manual_num_copies = printdlgex->nCopies;
1582 op->priv->manual_collation = (printdlgex->Flags & PD_COLLATE) != 0;
1583 op->priv->manual_reverse = FALSE;
1584 op->priv->manual_orientation = FALSE;
1585 op->priv->manual_scale = 1.0;
1586 op->priv->manual_page_set = GTK_PAGE_SET_ALL;
1589 op->priv->start_page = win32_start_page;
1590 op->priv->end_page = win32_end_page;
1591 op->priv->end_run = win32_end_run;
1594 if (!*do_print && printdlgex && printdlgex->hDevMode != NULL)
1595 GlobalFree(printdlgex->hDevMode);
1597 if (!*do_print && printdlgex && printdlgex->hDevNames != NULL)
1598 GlobalFree(printdlgex->hDevNames);
1601 GlobalFree (page_ranges);
1604 GlobalFree (printdlgex);
1607 gtk_widget_destroy (invisible);
1613 _gtk_print_operation_platform_backend_run_dialog_async (GtkPrintOperation *op,
1615 GtkPrintOperationPrintFunc print_cb)
1619 _gtk_print_operation_platform_backend_run_dialog (op, parent, &do_print, NULL);
1621 print_cb (op, parent, FALSE);
1623 _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED_ABORTED, NULL);
1627 gtk_print_run_page_setup_dialog (GtkWindow *parent,
1628 GtkPageSetup *page_setup,
1629 GtkPrintSettings *settings)
1631 LPPAGESETUPDLGW pagesetupdlg = NULL;
1633 gboolean free_settings;
1634 const char *printer;
1635 GtkPaperSize *paper_size;
1636 DWORD measure_system;
1640 pagesetupdlg = (LPPAGESETUPDLGW)GlobalAlloc (GPTR, sizeof (PAGESETUPDLGW));
1644 free_settings = FALSE;
1645 if (settings == NULL)
1647 settings = gtk_print_settings_new ();
1648 free_settings = TRUE;
1651 memset (pagesetupdlg, 0, sizeof (PAGESETUPDLGW));
1653 pagesetupdlg->lStructSize = sizeof(PAGESETUPDLGW);
1656 pagesetupdlg->hwndOwner = get_parent_hwnd (GTK_WIDGET (parent));
1658 pagesetupdlg->hwndOwner = NULL;
1660 pagesetupdlg->Flags = PSD_DEFAULTMINMARGINS;
1661 pagesetupdlg->hDevMode = devmode_from_settings (settings, page_setup);
1662 pagesetupdlg->hDevNames = NULL;
1663 printer = gtk_print_settings_get_printer (settings);
1665 pagesetupdlg->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
1667 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IMEASURE|LOCALE_RETURN_NUMBER,
1668 (LPWSTR)&measure_system, sizeof (DWORD));
1670 if (measure_system == 0)
1672 pagesetupdlg->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
1678 pagesetupdlg->Flags |= PSD_INTHOUSANDTHSOFINCHES;
1679 unit = GTK_UNIT_INCH;
1683 /* This is the object we return, we allocate it here so that
1684 * we can use the default page margins */
1686 page_setup = gtk_page_setup_copy (page_setup);
1688 page_setup = gtk_page_setup_new ();
1690 pagesetupdlg->Flags |= PSD_MARGINS;
1691 pagesetupdlg->rtMargin.left =
1692 floor (gtk_page_setup_get_left_margin (page_setup, unit) * scale + 0.5);
1693 pagesetupdlg->rtMargin.right =
1694 floor (gtk_page_setup_get_right_margin (page_setup, unit) * scale + 0.5);
1695 pagesetupdlg->rtMargin.top =
1696 floor (gtk_page_setup_get_top_margin (page_setup, unit) * scale + 0.5);
1697 pagesetupdlg->rtMargin.bottom =
1698 floor (gtk_page_setup_get_bottom_margin (page_setup, unit) * scale + 0.5);
1700 pagesetupdlg->Flags |= PSD_ENABLEPAGESETUPHOOK;
1701 pagesetupdlg->lpfnPageSetupHook = run_mainloop_hook;
1702 got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
1704 res = PageSetupDlgW (pagesetupdlg);
1705 gdk_win32_set_modal_dialog_libgtk_only (NULL);
1709 if (pagesetupdlg->hDevNames != NULL)
1710 devnames_to_settings (settings, pagesetupdlg->hDevNames);
1712 if (pagesetupdlg->hDevMode != NULL)
1713 devmode_to_settings (settings, pagesetupdlg->hDevMode);
1717 g_object_unref (settings);
1721 gtk_page_setup_set_orientation (page_setup,
1722 gtk_print_settings_get_orientation (settings));
1723 paper_size = gtk_print_settings_get_paper_size (settings);
1726 gtk_page_setup_set_paper_size (page_setup, paper_size);
1727 gtk_paper_size_free (paper_size);
1730 if (pagesetupdlg->Flags & PSD_INHUNDREDTHSOFMILLIMETERS)
1737 unit = GTK_UNIT_INCH;
1741 gtk_page_setup_set_left_margin (page_setup,
1742 pagesetupdlg->rtMargin.left / scale,
1744 gtk_page_setup_set_right_margin (page_setup,
1745 pagesetupdlg->rtMargin.right / scale,
1747 gtk_page_setup_set_top_margin (page_setup,
1748 pagesetupdlg->rtMargin.top / scale,
1750 gtk_page_setup_set_bottom_margin (page_setup,
1751 pagesetupdlg->rtMargin.bottom / scale,
1759 gtk_print_run_page_setup_dialog_async (GtkWindow *parent,
1760 GtkPageSetup *page_setup,
1761 GtkPrintSettings *settings,
1762 GtkPageSetupDoneFunc done_cb,
1765 GtkPageSetup *new_page_setup;
1767 new_page_setup = gtk_print_run_page_setup_dialog (parent, page_setup, settings);
1768 done_cb (new_page_setup, data);
1769 g_object_unref (new_page_setup);