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
35 #include <cairo-win32.h>
37 #include "gtkprintoperation-private.h"
38 #include "gtkprint-win32.h"
40 #include "gtkinvisible.h"
44 #include "gtkwin32embedwidget.h"
47 #define MAX_PAGE_RANGES 20
48 #define STATUS_POLLING_TIME 2000
50 #ifndef JOB_STATUS_RESTART
51 #define JOB_STATUS_RESTART 0x800
54 #ifndef JOB_STATUS_COMPLETE
55 #define JOB_STATUS_COMPLETE 0x1000
66 cairo_surface_t *surface;
67 GtkWidget *embed_widget;
68 } GtkPrintOperationWin32;
70 static void win32_poll_status (GtkPrintOperation *op);
72 static const GUID myIID_IPrintDialogCallback = {0x5852a2c3,0x6530,0x11d1,{0xb6,0xa3,0x0,0x0,0xf8,0x75,0x7b,0xf9}};
76 #define INTERFACE IPrintDialogCallback
77 DECLARE_INTERFACE_ (IPrintDialogCallback, IUnknown)
79 STDMETHOD (QueryInterface)(THIS_ REFIID,LPVOID*) PURE;
80 STDMETHOD_ (ULONG, AddRef)(THIS) PURE;
81 STDMETHOD_ (ULONG, Release)(THIS) PURE;
82 STDMETHOD (InitDone)(THIS) PURE;
83 STDMETHOD (SelectionChange)(THIS) PURE;
84 STDMETHOD (HandleMessage)(THIS_ HWND,UINT,WPARAM,LPARAM,LRESULT*) PURE;
88 static UINT got_gdk_events_message;
91 run_mainloop_hook (HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
93 if (uiMsg == WM_INITDIALOG)
95 gdk_win32_set_modal_dialog_libgtk_only (hdlg);
96 while (gtk_events_pending ())
97 gtk_main_iteration ();
99 else if (uiMsg == got_gdk_events_message)
101 while (gtk_events_pending ())
102 gtk_main_iteration ();
108 static GtkPageOrientation
109 orientation_from_win32 (short orientation)
111 if (orientation == DMORIENT_LANDSCAPE)
112 return GTK_PAGE_ORIENTATION_LANDSCAPE;
113 return GTK_PAGE_ORIENTATION_PORTRAIT;
117 orientation_to_win32 (GtkPageOrientation orientation)
119 if (orientation == GTK_PAGE_ORIENTATION_LANDSCAPE ||
120 orientation == GTK_PAGE_ORIENTATION_REVERSE_LANDSCAPE)
121 return DMORIENT_LANDSCAPE;
122 return DMORIENT_PORTRAIT;
125 static GtkPaperSize *
126 paper_size_from_win32 (short size)
132 case DMPAPER_LETTER_TRANSVERSE:
134 case DMPAPER_LETTERSMALL:
137 case DMPAPER_TABLOID:
144 case DMPAPER_STATEMENT:
147 case DMPAPER_EXECUTIVE:
148 name = "na_executive";
151 case DMPAPER_A3_TRANSVERSE:
155 case DMPAPER_A4SMALL:
156 case DMPAPER_A4_TRANSVERSE:
160 case DMPAPER_A5_TRANSVERSE:
167 case DMPAPER_B5_TRANSVERSE:
183 name = "na_number-9";
186 name = "na_number-10";
189 name = "na_number-11";
192 name = "na_number-12";
195 name = "na_number-14";
221 case DMPAPER_ENV_C65:
233 case DMPAPER_ENV_ITALY:
236 case DMPAPER_ENV_MONARCH:
239 case DMPAPER_ENV_PERSONAL:
240 name = "na_personal";
242 case DMPAPER_FANFOLD_US:
243 name = "na_fanfold-us";
245 case DMPAPER_FANFOLD_STD_GERMAN:
246 name = "na_fanfold-eur";
248 case DMPAPER_FANFOLD_LGL_GERMAN:
249 name = "na_foolscap";
254 case DMPAPER_JAPANESE_POSTCARD:
263 case DMPAPER_ENV_INVITE:
266 case DMPAPER_LETTER_EXTRA:
267 case DMPAPER_LETTER_EXTRA_TRANSVERSE:
268 name = "na_letter-extra";
270 case DMPAPER_LEGAL_EXTRA:
271 name = "na_legal-extra";
273 case DMPAPER_TABLOID_EXTRA:
276 case DMPAPER_A4_EXTRA:
277 name = "iso_a4-extra";
282 case DMPAPER_LETTER_PLUS:
283 name = "na_letter-plus";
285 case DMPAPER_A3_EXTRA:
286 case DMPAPER_A3_EXTRA_TRANSVERSE:
287 name = "iso_a3-extra";
289 case DMPAPER_A5_EXTRA:
290 name = "iso_a5-extra";
292 case DMPAPER_B5_EXTRA:
293 name = "iso_b5-extra";
305 return gtk_paper_size_new (name);
311 paper_size_to_win32 (GtkPaperSize *paper_size)
315 if (gtk_paper_size_is_custom (paper_size))
318 format = gtk_paper_size_get_name (paper_size);
320 if (strcmp (format, "na_letter") == 0)
321 return DMPAPER_LETTER;
322 if (strcmp (format, "na_ledger") == 0)
323 return DMPAPER_LEDGER;
324 if (strcmp (format, "na_legal") == 0)
325 return DMPAPER_LEGAL;
326 if (strcmp (format, "na_invoice") == 0)
327 return DMPAPER_STATEMENT;
328 if (strcmp (format, "na_executive") == 0)
329 return DMPAPER_EXECUTIVE;
330 if (strcmp (format, "iso_a2") == 0)
332 if (strcmp (format, "iso_a3") == 0)
334 if (strcmp (format, "iso_a4") == 0)
336 if (strcmp (format, "iso_a5") == 0)
338 if (strcmp (format, "iso_b4") == 0)
340 if (strcmp (format, "iso_b5") == 0)
342 if (strcmp (format, "na_quarto") == 0)
343 return DMPAPER_QUARTO;
344 if (strcmp (format, "na_10x14") == 0)
345 return DMPAPER_10X14;
346 if (strcmp (format, "na_number-9") == 0)
347 return DMPAPER_ENV_9;
348 if (strcmp (format, "na_number-10") == 0)
349 return DMPAPER_ENV_10;
350 if (strcmp (format, "na_number-11") == 0)
351 return DMPAPER_ENV_11;
352 if (strcmp (format, "na_number-12") == 0)
353 return DMPAPER_ENV_12;
354 if (strcmp (format, "na_number-14") == 0)
355 return DMPAPER_ENV_14;
356 if (strcmp (format, "na_c") == 0)
357 return DMPAPER_CSHEET;
358 if (strcmp (format, "na_d") == 0)
359 return DMPAPER_DSHEET;
360 if (strcmp (format, "na_e") == 0)
361 return DMPAPER_ESHEET;
362 if (strcmp (format, "iso_dl") == 0)
363 return DMPAPER_ENV_DL;
364 if (strcmp (format, "iso_c3") == 0)
365 return DMPAPER_ENV_C3;
366 if (strcmp (format, "iso_c4") == 0)
367 return DMPAPER_ENV_C4;
368 if (strcmp (format, "iso_c5") == 0)
369 return DMPAPER_ENV_C5;
370 if (strcmp (format, "iso_c6") == 0)
371 return DMPAPER_ENV_C6;
372 if (strcmp (format, "iso_c5c6") == 0)
373 return DMPAPER_ENV_C65;
374 if (strcmp (format, "iso_b6") == 0)
375 return DMPAPER_ENV_B6;
376 if (strcmp (format, "om_italian") == 0)
377 return DMPAPER_ENV_ITALY;
378 if (strcmp (format, "na_monarch") == 0)
379 return DMPAPER_ENV_MONARCH;
380 if (strcmp (format, "na_personal") == 0)
381 return DMPAPER_ENV_PERSONAL;
382 if (strcmp (format, "na_fanfold-us") == 0)
383 return DMPAPER_FANFOLD_US;
384 if (strcmp (format, "na_fanfold-eur") == 0)
385 return DMPAPER_FANFOLD_STD_GERMAN;
386 if (strcmp (format, "na_foolscap") == 0)
387 return DMPAPER_FANFOLD_LGL_GERMAN;
388 if (strcmp (format, "jpn_hagaki") == 0)
389 return DMPAPER_JAPANESE_POSTCARD;
390 if (strcmp (format, "na_9x11") == 0)
392 if (strcmp (format, "na_10x11") == 0)
393 return DMPAPER_10X11;
394 if (strcmp (format, "om_invite") == 0)
395 return DMPAPER_ENV_INVITE;
396 if (strcmp (format, "na_letter-extra") == 0)
397 return DMPAPER_LETTER_EXTRA;
398 if (strcmp (format, "na_legal-extra") == 0)
399 return DMPAPER_LEGAL_EXTRA;
400 if (strcmp (format, "na_arch") == 0)
401 return DMPAPER_TABLOID_EXTRA;
402 if (strcmp (format, "iso_a3-extra") == 0)
403 return DMPAPER_A3_EXTRA;
404 if (strcmp (format, "iso_a4-extra") == 0)
405 return DMPAPER_A4_EXTRA;
406 if (strcmp (format, "iso_a5-extra") == 0)
407 return DMPAPER_A5_EXTRA;
408 if (strcmp (format, "iso_b5-extra") == 0)
409 return DMPAPER_B5_EXTRA;
410 if (strcmp (format, "na_b-plus") == 0)
411 return DMPAPER_B_PLUS;
412 if (strcmp (format, "na_letter-plus") == 0)
413 return DMPAPER_LETTER_PLUS;
419 win32_start_page (GtkPrintOperation *op,
420 GtkPrintContext *print_context,
421 GtkPageSetup *page_setup)
423 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
425 GtkPaperSize *paper_size;
427 devmode = GlobalLock (op_win32->devmode);
429 devmode->dmFields |= DM_ORIENTATION;
430 devmode->dmOrientation =
431 orientation_to_win32 (gtk_page_setup_get_orientation (page_setup));
433 paper_size = gtk_page_setup_get_paper_size (page_setup);
434 devmode->dmFields |= DM_PAPERSIZE;
435 devmode->dmFields &= ~(DM_PAPERWIDTH | DM_PAPERLENGTH);
436 devmode->dmPaperSize = paper_size_to_win32 (paper_size);
437 if (devmode->dmPaperSize == 0)
439 devmode->dmPaperSize = DMPAPER_USER;
440 devmode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
441 devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) * 10.0;
442 devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) * 10.0;
445 ResetDCW (op_win32->hdc, devmode);
447 GlobalUnlock (op_win32->devmode);
449 StartPage (op_win32->hdc);
453 win32_end_page (GtkPrintOperation *op,
454 GtkPrintContext *print_context)
456 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
457 EndPage (op_win32->hdc);
461 win32_poll_status_timeout (GtkPrintOperation *op)
463 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
465 op_win32->timeout_id = 0;
466 /* We need to ref this, as setting the status to finished
467 might unref the object */
469 win32_poll_status (op);
471 if (!gtk_print_operation_is_finished (op))
472 op_win32->timeout_id = g_timeout_add (STATUS_POLLING_TIME,
473 (GSourceFunc)win32_poll_status_timeout,
481 win32_end_run (GtkPrintOperation *op,
485 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
487 HANDLE printerHandle = 0;
489 EndDoc (op_win32->hdc);
491 if (op->priv->track_print_status)
493 devnames = GlobalLock (op_win32->devnames);
494 if (!OpenPrinterW (((gunichar2 *)devnames) + devnames->wDeviceOffset,
495 &printerHandle, NULL))
497 GlobalUnlock (op_win32->devnames);
500 GlobalFree(op_win32->devmode);
501 GlobalFree(op_win32->devnames);
503 cairo_surface_finish (op_win32->surface);
504 cairo_surface_destroy (op_win32->surface);
505 op_win32->surface = NULL;
507 DeleteDC(op_win32->hdc);
509 if (printerHandle != 0)
511 op_win32->printerHandle = printerHandle;
512 win32_poll_status (op);
513 op_win32->timeout_id = g_timeout_add (STATUS_POLLING_TIME,
514 (GSourceFunc)win32_poll_status_timeout,
518 /* Dunno what happened, pretend its finished */
519 _gtk_print_operation_set_status (op, GTK_PRINT_STATUS_FINISHED, NULL);
523 win32_poll_status (GtkPrintOperation *op)
525 GtkPrintOperationWin32 *op_win32 = op->priv->platform_data;
528 JOB_INFO_1W *job_info;
529 GtkPrintStatus status;
533 GetJobW (op_win32->printerHandle, op_win32->job_id,
534 1,(LPBYTE)NULL, 0, &needed);
535 data = g_malloc (needed);
536 ret = GetJobW (op_win32->printerHandle, op_win32->job_id,
537 1, (LPBYTE)data, needed, &needed);
543 job_info = (JOB_INFO_1W *)data;
544 win32_status = job_info->Status;
546 if (job_info->pStatus)
547 status_str = g_utf16_to_utf8 (job_info->pStatus,
548 -1, NULL, NULL, NULL);
551 (JOB_STATUS_COMPLETE | JOB_STATUS_PRINTED))
552 status = GTK_PRINT_STATUS_FINISHED;
553 else if (win32_status &
554 (JOB_STATUS_OFFLINE |
555 JOB_STATUS_PAPEROUT |
557 JOB_STATUS_USER_INTERVENTION))
559 status = GTK_PRINT_STATUS_PENDING_ISSUE;
560 if (status_str == NULL)
562 if (win32_status & JOB_STATUS_OFFLINE)
563 status_str = g_strdup (_("Printer offline"));
564 else if (win32_status & JOB_STATUS_PAPEROUT)
565 status_str = g_strdup (_("Out of paper"));
566 else if (win32_status & JOB_STATUS_PAUSED)
567 status_str = g_strdup (_("Paused"));
568 else if (win32_status & JOB_STATUS_USER_INTERVENTION)
569 status_str = g_strdup (_("Need user intervention"));
572 else if (win32_status &
573 (JOB_STATUS_BLOCKED_DEVQ |
576 status = GTK_PRINT_STATUS_FINISHED_ABORTED;
577 else if (win32_status &
578 (JOB_STATUS_SPOOLING |
579 JOB_STATUS_DELETING))
580 status = GTK_PRINT_STATUS_PENDING;
581 else if (win32_status & JOB_STATUS_PRINTING)
582 status = GTK_PRINT_STATUS_PRINTING;
584 status = GTK_PRINT_STATUS_FINISHED;
587 status = GTK_PRINT_STATUS_FINISHED;
591 _gtk_print_operation_set_status (op, status, status_str);
597 op_win32_free (GtkPrintOperationWin32 *op_win32)
599 if (op_win32->printerHandle)
600 ClosePrinter (op_win32->printerHandle);
601 if (op_win32->timeout_id != 0)
602 g_source_remove (op_win32->timeout_id);
607 get_parent_hwnd (GtkWidget *widget)
609 gtk_widget_realize (widget);
610 return gdk_win32_drawable_get_handle (widget->window);
614 devnames_to_settings (GtkPrintSettings *settings,
617 GtkPrintWin32Devnames *devnames = gtk_print_win32_devnames_from_win32 (hDevNames);
618 gtk_print_settings_set_printer (settings, devnames->device);
619 gtk_print_win32_devnames_free (devnames);
623 devmode_to_settings (GtkPrintSettings *settings,
628 devmode = GlobalLock (hDevMode);
630 gtk_print_settings_set_int (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION,
631 devmode->dmDriverVersion);
632 if (devmode->dmDriverExtra != 0)
634 char *extra = g_base64_encode (((char *)devmode) + sizeof (DEVMODEW),
635 devmode->dmDriverExtra);
636 gtk_print_settings_set (settings,
637 GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA,
642 if (devmode->dmFields & DM_ORIENTATION)
643 gtk_print_settings_set_orientation (settings,
644 orientation_from_win32 (devmode->dmOrientation));
647 if (devmode->dmFields & DM_PAPERSIZE &&
648 devmode->dmPaperSize != 0)
650 GtkPaperSize *paper_size = paper_size_from_win32 (devmode->dmPaperSize);
653 gtk_print_settings_set_paper_size (settings, paper_size);
654 gtk_paper_size_free (paper_size);
656 gtk_print_settings_set_int (settings, "win32-paper-size", (int)devmode->dmPaperSize);
658 else if ((devmode->dmFields & DM_PAPERSIZE &&
659 devmode->dmPaperSize == 0) ||
660 ((devmode->dmFields & DM_PAPERWIDTH) &&
661 (devmode->dmFields & DM_PAPERLENGTH)))
663 GtkPaperSize *paper_size;
664 char *form_name = NULL;
665 if (devmode->dmFields & DM_FORMNAME)
666 form_name = g_utf16_to_utf8 (devmode->dmFormName,
667 -1, NULL, NULL, NULL);
668 if (form_name == NULL || form_name[0] == 0)
669 form_name = g_strdup (_("Custom size"));
670 paper_size = gtk_paper_size_new_custom (form_name,
672 devmode->dmPaperWidth * 10.0,
673 devmode->dmPaperLength * 10.0,
675 gtk_print_settings_set_paper_size (settings, paper_size);
676 gtk_paper_size_free (paper_size);
679 if (devmode->dmFields & DM_SCALE)
680 gtk_print_settings_set_scale (settings, devmode->dmScale);
682 if (devmode->dmFields & DM_COPIES)
683 gtk_print_settings_set_n_copies (settings,
686 if (devmode->dmFields & DM_DEFAULTSOURCE)
689 switch (devmode->dmDefaultSource)
701 case DMBIN_ENVMANUAL:
702 source = "envelope-manual";
716 case DMBIN_FORMSOURCE:
717 source = "form-source";
719 case DMBIN_LARGECAPACITY:
720 source = "large-capacity";
723 source = "large-format";
729 source = "small-format";
732 gtk_print_settings_set_default_source (settings, source);
733 gtk_print_settings_set_int (settings, "win32-default-source", devmode->dmDefaultSource);
736 if (devmode->dmFields & DM_PRINTQUALITY)
738 GtkPrintQuality quality;
739 switch (devmode->dmPrintQuality)
742 quality = GTK_PRINT_QUALITY_LOW;
745 quality = GTK_PRINT_QUALITY_NORMAL;
749 quality = GTK_PRINT_QUALITY_HIGH;
752 quality = GTK_PRINT_QUALITY_DRAFT;
755 gtk_print_settings_set_quality (settings, quality);
756 gtk_print_settings_set_int (settings, "win32-print-quality", devmode->dmPrintQuality);
759 if (devmode->dmFields & DM_COLOR)
760 gtk_print_settings_set_use_color (settings, devmode->dmFields == DMCOLOR_COLOR);
762 if (devmode->dmFields & DM_DUPLEX)
764 GtkPrintDuplex duplex;
765 switch (devmode->dmDuplex)
769 duplex = GTK_PRINT_DUPLEX_SIMPLEX;
771 case DMDUP_HORIZONTAL:
772 duplex = GTK_PRINT_DUPLEX_HORIZONTAL;
775 duplex = GTK_PRINT_DUPLEX_VERTICAL;
779 gtk_print_settings_set_duplex (settings, duplex);
782 if (devmode->dmFields & DM_COLLATE)
783 gtk_print_settings_set_collate (settings,
784 devmode->dmCollate == DMCOLLATE_TRUE);
786 if (devmode->dmFields & DM_MEDIATYPE)
789 switch (devmode->dmMediaType)
792 case DMMEDIA_STANDARD:
793 media_type = "stationery";
795 case DMMEDIA_TRANSPARENCY:
796 media_type = "transparency";
799 media_type = "photographic-glossy";
802 gtk_print_settings_set_media_type (settings, media_type);
803 gtk_print_settings_set_int (settings, "win32-media-type", devmode->dmMediaType);
806 if (devmode->dmFields & DM_DITHERTYPE)
809 switch (devmode->dmDitherType)
818 case DMDITHER_COARSE:
821 case DMDITHER_LINEART:
824 case DMDITHER_GRAYSCALE:
825 dither = "grayscale";
827 case DMDITHER_ERRORDIFFUSION:
828 dither = "error-diffusion";
831 gtk_print_settings_set_dither (settings, dither);
832 gtk_print_settings_set_int (settings, "win32-dither-type", devmode->dmDitherType);
835 GlobalUnlock (hDevMode);
839 dialog_to_print_settings (GtkPrintOperation *op,
840 LPPRINTDLGEXW printdlgex)
843 GtkPrintSettings *settings;
845 settings = gtk_print_settings_new ();
847 gtk_print_settings_set_print_pages (settings,
848 GTK_PRINT_PAGES_ALL);
849 if (printdlgex->Flags & PD_CURRENTPAGE)
850 gtk_print_settings_set_print_pages (settings,
851 GTK_PRINT_PAGES_CURRENT);
852 else if (printdlgex->Flags & PD_PAGENUMS)
853 gtk_print_settings_set_print_pages (settings,
854 GTK_PRINT_PAGES_RANGES);
856 if (printdlgex->nPageRanges > 0)
858 GtkPageRange *ranges;
859 ranges = g_new (GtkPageRange, printdlgex->nPageRanges);
861 for (i = 0; i < printdlgex->nPageRanges; i++)
863 ranges[i].start = printdlgex->lpPageRanges[i].nFromPage - 1;
864 ranges[i].end = printdlgex->lpPageRanges[i].nToPage - 1;
867 gtk_print_settings_set_page_ranges (settings, ranges,
868 printdlgex->nPageRanges);
872 if (printdlgex->hDevNames != NULL)
873 devnames_to_settings (settings, printdlgex->hDevNames);
875 if (printdlgex->hDevMode != NULL)
876 devmode_to_settings (settings, printdlgex->hDevMode);
878 gtk_print_operation_set_print_settings (op, settings);
882 devmode_from_settings (GtkPrintSettings *settings,
883 GtkPageSetup *page_setup)
888 GtkPaperSize *paper_size;
889 const char *extras_base64;
895 extras_base64 = gtk_print_settings_get (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_EXTRA);
897 extras = g_base64_decode (extras_base64, &extras_len);
899 hDevMode = GlobalAlloc (GMEM_MOVEABLE,
900 sizeof (DEVMODEW) + extras_len);
902 devmode = GlobalLock (hDevMode);
904 memset (devmode, 0, sizeof (DEVMODEW));
906 devmode->dmSpecVersion = DM_SPECVERSION;
907 devmode->dmSize = sizeof (DEVMODEW);
909 devmode->dmDriverExtra = 0;
910 if (extras && extras_len > 0)
912 devmode->dmDriverExtra = extras_len;
913 memcpy (((char *)devmode) + sizeof (DEVMODEW), extras, extras_len);
916 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION))
917 devmode->dmDriverVersion = gtk_print_settings_get_int (settings, GTK_PRINT_SETTINGS_WIN32_DRIVER_VERSION);
920 gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
922 GtkPageOrientation orientation = gtk_print_settings_get_orientation (settings);
924 orientation = gtk_page_setup_get_orientation (page_setup);
925 devmode->dmFields |= DM_ORIENTATION;
926 devmode->dmOrientation = orientation_to_win32 (orientation);
930 paper_size = gtk_paper_size_copy (gtk_page_setup_get_paper_size (page_setup));
934 if (gtk_print_settings_has_key (settings, "win32-paper-size") &&
935 (size = gtk_print_settings_get_int (settings, "win32-paper-size")) != 0)
937 devmode->dmFields |= DM_PAPERSIZE;
938 devmode->dmPaperSize = size;
942 paper_size = gtk_print_settings_get_paper_size (settings);
946 devmode->dmFields |= DM_PAPERSIZE;
947 devmode->dmPaperSize = paper_size_to_win32 (paper_size);
948 if (devmode->dmPaperSize == 0)
950 devmode->dmPaperSize = DMPAPER_USER;
951 devmode->dmFields |= DM_PAPERWIDTH | DM_PAPERLENGTH;
952 devmode->dmPaperWidth = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM) / 10.0;
953 devmode->dmPaperLength = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM) / 10.0;
955 gtk_paper_size_free (paper_size);
958 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_SCALE))
960 devmode->dmFields |= DM_SCALE;
961 devmode->dmScale = gtk_print_settings_get_scale (settings);
964 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_N_COPIES))
966 devmode->dmFields |= DM_COPIES;
967 devmode->dmCopies = gtk_print_settings_get_n_copies (settings);
970 if (gtk_print_settings_has_key (settings, "win32-default-source"))
972 devmode->dmFields |= DM_DEFAULTSOURCE;
973 devmode->dmDefaultSource = gtk_print_settings_get_int (settings, "win32-default-source");
975 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE))
977 devmode->dmFields |= DM_DEFAULTSOURCE;
978 devmode->dmDefaultSource = DMBIN_AUTO;
980 val = gtk_print_settings_get_default_source (settings);
981 if (strcmp (val, "auto") == 0)
982 devmode->dmDefaultSource = DMBIN_AUTO;
983 if (strcmp (val, "cassette") == 0)
984 devmode->dmDefaultSource = DMBIN_CASSETTE;
985 if (strcmp (val, "envelope") == 0)
986 devmode->dmDefaultSource = DMBIN_ENVELOPE;
987 if (strcmp (val, "envelope-manual") == 0)
988 devmode->dmDefaultSource = DMBIN_ENVMANUAL;
989 if (strcmp (val, "lower") == 0)
990 devmode->dmDefaultSource = DMBIN_LOWER;
991 if (strcmp (val, "manual") == 0)
992 devmode->dmDefaultSource = DMBIN_MANUAL;
993 if (strcmp (val, "middle") == 0)
994 devmode->dmDefaultSource = DMBIN_MIDDLE;
995 if (strcmp (val, "only-one") == 0)
996 devmode->dmDefaultSource = DMBIN_ONLYONE;
997 if (strcmp (val, "form-source") == 0)
998 devmode->dmDefaultSource = DMBIN_FORMSOURCE;
999 if (strcmp (val, "large-capacity") == 0)
1000 devmode->dmDefaultSource = DMBIN_LARGECAPACITY;
1001 if (strcmp (val, "large-format") == 0)
1002 devmode->dmDefaultSource = DMBIN_LARGEFMT;
1003 if (strcmp (val, "tractor") == 0)
1004 devmode->dmDefaultSource = DMBIN_TRACTOR;
1005 if (strcmp (val, "small-format") == 0)
1006 devmode->dmDefaultSource = DMBIN_SMALLFMT;
1009 if (gtk_print_settings_has_key (settings, "win32-print-quality"))
1011 devmode->dmFields |= DM_PRINTQUALITY;
1012 devmode->dmPrintQuality = gtk_print_settings_get_int (settings, "win32-print-quality");
1014 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_RESOLUTION))
1016 devmode->dmFields |= DM_PRINTQUALITY;
1017 devmode->dmPrintQuality = gtk_print_settings_get_resolution (settings);
1019 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_QUALITY))
1021 devmode->dmFields |= DM_PRINTQUALITY;
1022 switch (gtk_print_settings_get_quality (settings))
1024 case GTK_PRINT_QUALITY_LOW:
1025 devmode->dmPrintQuality = DMRES_LOW;
1027 case GTK_PRINT_QUALITY_DRAFT:
1028 devmode->dmPrintQuality = DMRES_DRAFT;
1031 case GTK_PRINT_QUALITY_NORMAL:
1032 devmode->dmPrintQuality = DMRES_MEDIUM;
1034 case GTK_PRINT_QUALITY_HIGH:
1035 devmode->dmPrintQuality = DMRES_HIGH;
1040 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_USE_COLOR))
1042 devmode->dmFields |= DM_COLOR;
1043 if (gtk_print_settings_get_use_color (settings))
1044 devmode->dmColor = DMCOLOR_COLOR;
1046 devmode->dmColor = DMCOLOR_MONOCHROME;
1049 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DUPLEX))
1051 devmode->dmFields |= DM_DUPLEX;
1052 switch (gtk_print_settings_get_duplex (settings))
1055 case GTK_PRINT_DUPLEX_SIMPLEX:
1056 devmode->dmDuplex = DMDUP_SIMPLEX;
1058 case GTK_PRINT_DUPLEX_HORIZONTAL:
1059 devmode->dmDuplex = DMDUP_HORIZONTAL;
1061 case GTK_PRINT_DUPLEX_VERTICAL:
1062 devmode->dmDuplex = DMDUP_VERTICAL;
1067 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_COLLATE))
1069 devmode->dmFields |= DM_COLLATE;
1070 if (gtk_print_settings_get_collate (settings))
1071 devmode->dmCollate = DMCOLLATE_TRUE;
1073 devmode->dmCollate = DMCOLLATE_FALSE;
1076 if (gtk_print_settings_has_key (settings, "win32-media-type"))
1078 devmode->dmFields |= DM_MEDIATYPE;
1079 devmode->dmMediaType = gtk_print_settings_get_int (settings, "win32-media-type");
1081 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_MEDIA_TYPE))
1083 devmode->dmFields |= DM_MEDIATYPE;
1084 devmode->dmMediaType = DMMEDIA_STANDARD;
1086 val = gtk_print_settings_get_media_type (settings);
1087 if (strcmp (val, "transparency") == 0)
1088 devmode->dmMediaType = DMMEDIA_TRANSPARENCY;
1089 if (strcmp (val, "photographic-glossy") == 0)
1090 devmode->dmMediaType = DMMEDIA_GLOSSY;
1093 if (gtk_print_settings_has_key (settings, "win32-dither-type"))
1095 devmode->dmFields |= DM_DITHERTYPE;
1096 devmode->dmDitherType = gtk_print_settings_get_int (settings, "win32-dither-type");
1098 else if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_DITHER))
1100 devmode->dmFields |= DM_DITHERTYPE;
1101 devmode->dmDitherType = DMDITHER_FINE;
1103 val = gtk_print_settings_get_dither (settings);
1104 if (strcmp (val, "none") == 0)
1105 devmode->dmDitherType = DMDITHER_NONE;
1106 if (strcmp (val, "coarse") == 0)
1107 devmode->dmDitherType = DMDITHER_COARSE;
1108 if (strcmp (val, "fine") == 0)
1109 devmode->dmDitherType = DMDITHER_FINE;
1110 if (strcmp (val, "lineart") == 0)
1111 devmode->dmDitherType = DMDITHER_LINEART;
1112 if (strcmp (val, "grayscale") == 0)
1113 devmode->dmDitherType = DMDITHER_GRAYSCALE;
1114 if (strcmp (val, "error-diffusion") == 0)
1115 devmode->dmDitherType = DMDITHER_ERRORDIFFUSION;
1118 GlobalUnlock (hDevMode);
1124 dialog_from_print_settings (GtkPrintOperation *op,
1125 LPPRINTDLGEXW printdlgex)
1127 GtkPrintSettings *settings = op->priv->print_settings;
1128 const char *printer;
1130 if (settings == NULL)
1133 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_PRINT_PAGES))
1135 GtkPrintPages print_pages = gtk_print_settings_get_print_pages (settings);
1137 switch (print_pages)
1140 case GTK_PRINT_PAGES_ALL:
1141 printdlgex->Flags |= PD_ALLPAGES;
1143 case GTK_PRINT_PAGES_CURRENT:
1144 printdlgex->Flags |= PD_CURRENTPAGE;
1146 case GTK_PRINT_PAGES_RANGES:
1147 printdlgex->Flags |= PD_PAGENUMS;
1151 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_PAGE_RANGES))
1153 GtkPageRange *ranges;
1156 ranges = gtk_print_settings_get_page_ranges (settings, &num_ranges);
1158 if (num_ranges > MAX_PAGE_RANGES)
1159 num_ranges = MAX_PAGE_RANGES;
1161 printdlgex->nPageRanges = num_ranges;
1162 for (i = 0; i < num_ranges; i++)
1164 printdlgex->lpPageRanges[i].nFromPage = ranges[i].start + 1;
1165 printdlgex->lpPageRanges[i].nToPage = ranges[i].end + 1;
1169 printer = gtk_print_settings_get_printer (settings);
1171 printdlgex->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
1173 printdlgex->hDevMode = devmode_from_settings (settings,
1174 op->priv->default_page_setup);
1178 IPrintDialogCallback iPrintDialogCallback;
1181 } PrintDialogCallback;
1184 static ULONG STDMETHODCALLTYPE
1185 iprintdialogcallback_addref (IPrintDialogCallback *This)
1187 PrintDialogCallback *callback = (PrintDialogCallback *)This;
1188 return ++callback->ref_count;
1191 static ULONG STDMETHODCALLTYPE
1192 iprintdialogcallback_release (IPrintDialogCallback *This)
1194 PrintDialogCallback *callback = (PrintDialogCallback *)This;
1195 int ref_count = --callback->ref_count;
1203 static HRESULT STDMETHODCALLTYPE
1204 iprintdialogcallback_queryinterface (IPrintDialogCallback *This,
1208 if (IsEqualIID (riid, &IID_IUnknown) ||
1209 IsEqualIID (riid, &myIID_IPrintDialogCallback))
1212 IUnknown_AddRef ((IUnknown *)This);
1218 return E_NOINTERFACE;
1222 static HRESULT STDMETHODCALLTYPE
1223 iprintdialogcallback_initdone (IPrintDialogCallback *This)
1228 static HRESULT STDMETHODCALLTYPE
1229 iprintdialogcallback_selectionchange (IPrintDialogCallback *This)
1234 static HRESULT STDMETHODCALLTYPE
1235 iprintdialogcallback_handlemessage (IPrintDialogCallback *This,
1242 PrintDialogCallback *callback = (PrintDialogCallback *)This;
1244 if (!callback->set_hwnd)
1246 gdk_win32_set_modal_dialog_libgtk_only (hDlg);
1247 callback->set_hwnd = TRUE;
1248 while (gtk_events_pending ())
1249 gtk_main_iteration ();
1251 else if (uMsg == got_gdk_events_message)
1253 while (gtk_events_pending ())
1254 gtk_main_iteration ();
1263 static IPrintDialogCallbackVtbl ipdc_vtbl = {
1264 iprintdialogcallback_queryinterface,
1265 iprintdialogcallback_addref,
1266 iprintdialogcallback_release,
1267 iprintdialogcallback_initdone,
1268 iprintdialogcallback_selectionchange,
1269 iprintdialogcallback_handlemessage
1272 static IPrintDialogCallback *
1273 print_callback_new (void)
1275 PrintDialogCallback *callback;
1277 callback = g_new0 (PrintDialogCallback, 1);
1278 callback->iPrintDialogCallback.lpVtbl = &ipdc_vtbl;
1279 callback->ref_count = 1;
1280 callback->set_hwnd = FALSE;
1282 return &callback->iPrintDialogCallback;
1286 plug_grab_notify (GtkWidget *widget,
1287 gboolean was_grabbed,
1288 GtkPrintOperation *op)
1290 EnableWindow(GetAncestor (GDK_WINDOW_HWND (widget->window), GA_ROOT),
1295 static BOOL CALLBACK
1296 pageDlgProc (HWND wnd, UINT message, WPARAM wparam, LPARAM lparam)
1298 GtkPrintOperation *op;
1299 GtkPrintOperationWin32 *op_win32;
1301 if (message == WM_INITDIALOG)
1303 PROPSHEETPAGEW *page = (PROPSHEETPAGEW *)lparam;
1306 op = GTK_PRINT_OPERATION ((gpointer)page->lParam);
1307 op_win32 = op->priv->platform_data;
1309 SetWindowLongPtrW(wnd, GWLP_USERDATA, (LONG_PTR)op);
1311 plug = _gtk_win32_embed_widget_new ((GdkNativeWindow) wnd);
1312 op_win32->embed_widget = plug;
1313 gtk_container_add (GTK_CONTAINER (plug), op->priv->custom_widget);
1314 gtk_widget_show (op->priv->custom_widget);
1315 gtk_widget_show (plug);
1316 gdk_window_focus (plug->window, GDK_CURRENT_TIME);
1318 /* This dialog is modal, so we grab the embed widget */
1319 gtk_grab_add (plug);
1321 /* When we lose the grab we need to disable the print dialog */
1322 g_signal_connect (plug, "grab-notify", G_CALLBACK (plug_grab_notify), op);
1325 else if (message == WM_DESTROY)
1327 op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
1328 op_win32 = op->priv->platform_data;
1330 g_signal_emit_by_name (op, "custom-widget-apply", op->priv->custom_widget);
1331 gtk_widget_destroy (op_win32->embed_widget);
1332 op_win32->embed_widget = NULL;
1333 op->priv->custom_widget = NULL;
1337 op = GTK_PRINT_OPERATION (GetWindowLongPtrW(wnd, GWLP_USERDATA));
1338 op_win32 = op->priv->platform_data;
1340 return _gtk_win32_embed_widget_dialog_procedure (GTK_WIN32_EMBED_WIDGET (op_win32->embed_widget),
1341 wnd, message, wparam, lparam);
1347 static HPROPSHEETPAGE
1348 create_application_page (GtkPrintOperation *op)
1350 HPROPSHEETPAGE hpage;
1351 PROPSHEETPAGEW page;
1352 DLGTEMPLATE *template;
1355 WORD baseunitX, baseunitY;
1357 GtkRequisition requisition;
1358 const char *app_name;
1360 /* Make the template the size of the custom widget size request */
1361 gtk_widget_size_request (op->priv->custom_widget, &requisition);
1363 base_units = GetDialogBaseUnits();
1364 baseunitX = LOWORD(base_units);
1365 baseunitY = HIWORD(base_units);
1367 htemplate = GlobalAlloc (GMEM_MOVEABLE,
1368 sizeof (DLGTEMPLATE) + sizeof(WORD) * 3);
1369 template = GlobalLock (htemplate);
1370 template->style = WS_CHILDWINDOW | DS_CONTROL;
1371 template->dwExtendedStyle = WS_EX_CONTROLPARENT;
1373 template->x = MulDiv(0, 4, baseunitX);
1374 template->y = MulDiv(0, 8, baseunitY);
1375 template->cx = MulDiv(requisition.width, 4, baseunitX);
1376 template->cy = MulDiv(requisition.height, 8, baseunitY);
1378 array = (WORD *) (template+1);
1379 *array++ = 0; /* menu */
1380 *array++ = 0; /* class */
1381 *array++ = 0; /* title */
1383 memset(&page, 0, sizeof (page));
1384 page.dwSize = sizeof (page);
1385 page.dwFlags = PSP_DLGINDIRECT | PSP_USETITLE | PSP_PREMATURE;
1386 page.hInstance = GetModuleHandle (NULL);
1387 page.pResource = template;
1388 app_name = g_get_application_name ();
1389 if (app_name == NULL)
1390 app_name = _("Application");
1391 page.pszTitle = g_utf8_to_utf16 (app_name,
1392 -1, NULL, NULL, NULL);
1393 page.pfnDlgProc = pageDlgProc;
1394 page.pfnCallback = NULL;
1395 page.lParam = (LPARAM) op;
1396 hpage = CreatePropertySheetPageW(&page);
1398 GlobalUnlock (htemplate);
1400 /* TODO: We're leaking htemplate here... */
1405 static GtkPageSetup *
1406 create_page_setup (GtkPrintOperation *op)
1408 GtkPrintOperationPrivate *priv = op->priv;
1409 GtkPageSetup *page_setup;
1410 GtkPrintSettings *settings;
1412 if (priv->default_page_setup)
1413 page_setup = gtk_page_setup_copy (priv->default_page_setup);
1415 page_setup = gtk_page_setup_new ();
1417 settings = priv->print_settings;
1420 GtkPaperSize *paper_size;
1422 if (gtk_print_settings_has_key (settings, GTK_PRINT_SETTINGS_ORIENTATION))
1423 gtk_page_setup_set_orientation (page_setup,
1424 gtk_print_settings_get_orientation (settings));
1427 paper_size = gtk_print_settings_get_paper_size (settings);
1430 gtk_page_setup_set_paper_size (page_setup, paper_size);
1431 gtk_paper_size_free (paper_size);
1434 /* TODO: Margins? */
1440 GtkPrintOperationResult
1441 _gtk_print_operation_platform_backend_run_dialog (GtkPrintOperation *op,
1442 gboolean show_dialog,
1447 LPPRINTDLGEXW printdlgex = NULL;
1448 LPPRINTPAGERANGE page_ranges = NULL;
1450 GtkWidget *invisible = NULL;
1451 GtkPrintOperationResult result;
1452 GtkPrintOperationWin32 *op_win32;
1453 GtkPrintOperationPrivate *priv;
1454 IPrintDialogCallback *callback;
1455 HPROPSHEETPAGE prop_page;
1461 op_win32 = g_new0 (GtkPrintOperationWin32, 1);
1462 priv->platform_data = op_win32;
1463 priv->free_platform_data = (GDestroyNotify) op_win32_free;
1467 invisible = gtk_invisible_new ();
1468 parentHWnd = get_parent_hwnd (invisible);
1471 parentHWnd = get_parent_hwnd (GTK_WIDGET (parent));
1473 printdlgex = (LPPRINTDLGEXW)GlobalAlloc (GPTR, sizeof (PRINTDLGEXW));
1476 result = GTK_PRINT_OPERATION_RESULT_ERROR;
1477 g_set_error (&priv->error,
1479 GTK_PRINT_ERROR_NOMEM,
1480 _("Not enough free memory"));
1484 printdlgex->lStructSize = sizeof(PRINTDLGEXW);
1485 printdlgex->hwndOwner = parentHWnd;
1486 printdlgex->hDevMode = NULL;
1487 printdlgex->hDevNames = NULL;
1488 printdlgex->hDC = NULL;
1489 printdlgex->Flags = PD_RETURNDC | PD_NOSELECTION;
1490 if (op->priv->current_page == -1)
1491 printdlgex->Flags |= PD_NOCURRENTPAGE;
1492 printdlgex->Flags2 = 0;
1493 printdlgex->ExclusionFlags = 0;
1495 page_ranges = (LPPRINTPAGERANGE) GlobalAlloc (GPTR,
1496 MAX_PAGE_RANGES * sizeof (PRINTPAGERANGE));
1499 result = GTK_PRINT_OPERATION_RESULT_ERROR;
1500 g_set_error (&priv->error,
1502 GTK_PRINT_ERROR_NOMEM,
1503 _("Not enough free memory"));
1507 printdlgex->nPageRanges = 0;
1508 printdlgex->nMaxPageRanges = MAX_PAGE_RANGES;
1509 printdlgex->lpPageRanges = page_ranges;
1510 printdlgex->nMinPage = 1;
1511 if (op->priv->nr_of_pages != -1)
1512 printdlgex->nMaxPage = op->priv->nr_of_pages;
1514 printdlgex->nMaxPage = 10000;
1515 printdlgex->nCopies = 1;
1516 printdlgex->hInstance = 0;
1517 printdlgex->lpPrintTemplateName = NULL;
1518 printdlgex->lpCallback = NULL;
1520 g_signal_emit_by_name (op, "create-custom-widget",
1521 &op->priv->custom_widget);
1522 if (op->priv->custom_widget) {
1523 prop_page = create_application_page (op);
1524 printdlgex->nPropertyPages = 1;
1525 printdlgex->lphPropertyPages = &prop_page;
1527 printdlgex->nPropertyPages = 0;
1528 printdlgex->lphPropertyPages = NULL;
1531 printdlgex->nStartPage = START_PAGE_GENERAL;
1532 printdlgex->dwResultAction = 0;
1534 dialog_from_print_settings (op, printdlgex);
1536 callback = print_callback_new ();
1537 printdlgex->lpCallback = (IUnknown *)callback;
1538 got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
1540 hResult = PrintDlgExW(printdlgex);
1541 IUnknown_Release ((IUnknown *)callback);
1542 gdk_win32_set_modal_dialog_libgtk_only (NULL);
1544 if (hResult != S_OK)
1546 result = GTK_PRINT_OPERATION_RESULT_ERROR;
1547 if (hResult == E_OUTOFMEMORY)
1548 g_set_error (&priv->error,
1550 GTK_PRINT_ERROR_NOMEM,
1551 _("Not enough free memory"));
1552 else if (hResult == E_INVALIDARG)
1553 g_set_error (&priv->error,
1555 GTK_PRINT_ERROR_INTERNAL_ERROR,
1556 _("Invalid argument to PrintDlgEx"));
1557 else if (hResult == E_POINTER)
1558 g_set_error (&priv->error,
1560 GTK_PRINT_ERROR_INTERNAL_ERROR,
1561 _("Invalid pointer to PrintDlgEx"));
1562 else if (hResult == E_HANDLE)
1563 g_set_error (&priv->error,
1565 GTK_PRINT_ERROR_INTERNAL_ERROR,
1566 _("Invalid handle to PrintDlgEx"));
1568 g_set_error (&priv->error,
1570 GTK_PRINT_ERROR_GENERAL,
1571 _("Unspecified error"));
1575 if (printdlgex->dwResultAction == PD_RESULT_PRINT ||
1576 printdlgex->dwResultAction == PD_RESULT_APPLY)
1578 result = GTK_PRINT_OPERATION_RESULT_APPLY;
1579 dialog_to_print_settings (op, printdlgex);
1582 result = GTK_PRINT_OPERATION_RESULT_CANCEL;
1584 if (printdlgex->dwResultAction == PD_RESULT_PRINT)
1588 double dpi_x, dpi_y;
1590 GtkPageSetup *page_setup;
1592 priv->print_context = _gtk_print_context_new (op);
1593 page_setup = create_page_setup (op);
1594 _gtk_print_context_set_page_setup (priv->print_context, page_setup);
1595 g_object_unref (page_setup);
1599 op_win32->surface = cairo_win32_surface_create (printdlgex->hDC);
1600 dpi_x = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSX);
1601 dpi_y = (double)GetDeviceCaps (printdlgex->hDC, LOGPIXELSY);
1603 cr = cairo_create (op_win32->surface);
1604 gtk_print_context_set_cairo_context (priv->print_context, cr, dpi_x, dpi_y);
1607 memset( &docinfo, 0, sizeof (DOCINFOW));
1608 docinfo.cbSize = sizeof (DOCINFOW);
1609 docinfo.lpszDocName = g_utf8_to_utf16 (op->priv->job_name, -1, NULL, NULL, NULL);
1610 docinfo.lpszOutput = (LPCWSTR) NULL;
1611 docinfo.lpszDatatype = (LPCWSTR) NULL;
1614 job_id = StartDocW(printdlgex->hDC, &docinfo);
1615 g_free ((void *)docinfo.lpszDocName);
1618 result = GTK_PRINT_OPERATION_RESULT_ERROR;
1619 g_set_error (&priv->error,
1621 GTK_PRINT_ERROR_GENERAL,
1622 _("Error from StartDoc"));
1624 cairo_surface_destroy (op_win32->surface);
1625 op_win32->surface = NULL;
1629 op_win32->hdc = printdlgex->hDC;
1630 op_win32->devmode = printdlgex->hDevMode;
1631 op_win32->devnames = printdlgex->hDevNames;
1632 op_win32->job_id = job_id;
1634 op->priv->print_pages = gtk_print_settings_get_print_pages (op->priv->print_settings);
1635 op->priv->num_page_ranges = 0;
1636 if (op->priv->print_pages == GTK_PRINT_PAGES_RANGES)
1637 op->priv->page_ranges = gtk_print_settings_get_page_ranges (op->priv->print_settings,
1638 &op->priv->num_page_ranges);
1639 op->priv->manual_num_copies = printdlgex->nCopies;
1640 op->priv->manual_collation = (printdlgex->Flags & PD_COLLATE) != 0;
1641 op->priv->manual_reverse = FALSE;
1642 op->priv->manual_orientation = FALSE;
1643 op->priv->manual_scale = 1.0;
1644 op->priv->manual_page_set = GTK_PAGE_SET_ALL;
1647 op->priv->start_page = win32_start_page;
1648 op->priv->end_page = win32_end_page;
1649 op->priv->end_run = win32_end_run;
1652 if (!*do_print && printdlgex && printdlgex->hDevMode != NULL)
1653 GlobalFree(printdlgex->hDevMode);
1655 if (!*do_print && printdlgex && printdlgex->hDevNames != NULL)
1656 GlobalFree(printdlgex->hDevNames);
1659 GlobalFree (page_ranges);
1662 GlobalFree (printdlgex);
1665 gtk_widget_destroy (invisible);
1671 _gtk_print_operation_platform_backend_launch_preview (GtkPrintOperation *op,
1672 cairo_surface_t *surface,
1674 const gchar *filename)
1677 HENHMETAFILE metafile;
1679 dc = cairo_win32_surface_get_dc (surface);
1680 cairo_surface_destroy (surface);
1681 metafile = CloseEnhMetaFile (dc);
1682 DeleteEnhMetaFile (metafile);
1684 ShellExecuteW (NULL, L"open", (gunichar2 *)filename, NULL, NULL, SW_SHOW);
1688 _gtk_print_operation_platform_backend_preview_start_page (GtkPrintOperation *op,
1689 cairo_surface_t *surface,
1692 HDC dc = cairo_win32_surface_get_dc (surface);
1697 _gtk_print_operation_platform_backend_preview_end_page (GtkPrintOperation *op,
1698 cairo_surface_t *surface,
1701 /* TODO: This doesn't actually seem to work.
1702 * Do enhanced metafiles really support multiple pages?
1704 HDC dc = cairo_win32_surface_get_dc (surface);
1709 _gtk_print_operation_platform_backend_create_preview_surface (GtkPrintOperation *op,
1710 GtkPageSetup *page_setup,
1715 GtkPaperSize *paper_size;
1721 gunichar2 *filename_utf16;
1724 template = g_build_filename (g_get_tmp_dir (), "prXXXXXX", NULL);
1725 fd = g_mkstemp (template);
1728 filename = g_strconcat (template, ".emf", NULL);
1731 filename_utf16 = g_utf8_to_utf16 (filename, -1, NULL, NULL, NULL);
1734 paper_size = gtk_page_setup_get_paper_size (page_setup);
1735 w = gtk_paper_size_get_width (paper_size, GTK_UNIT_MM);
1736 h = gtk_paper_size_get_height (paper_size, GTK_UNIT_MM);
1741 rect.bottom = h*100;
1743 metafile_dc = CreateEnhMetaFileW (NULL, filename_utf16,
1744 &rect, L"Gtk+\0Print Preview\0\0");
1745 if (metafile_dc == NULL)
1747 g_warning ("Can't create metafile");
1751 *target = (char *)filename_utf16;
1753 *dpi_x = (double)GetDeviceCaps (metafile_dc, LOGPIXELSX);
1754 *dpi_y = (double)GetDeviceCaps (metafile_dc, LOGPIXELSY);
1756 return cairo_win32_surface_create (metafile_dc);
1760 _gtk_print_operation_platform_backend_resize_preview_surface (GtkPrintOperation *op,
1761 GtkPageSetup *page_setup,
1762 cairo_surface_t *surface)
1764 /* TODO: Implement */
1768 gtk_print_run_page_setup_dialog (GtkWindow *parent,
1769 GtkPageSetup *page_setup,
1770 GtkPrintSettings *settings)
1772 LPPAGESETUPDLGW pagesetupdlg = NULL;
1774 gboolean free_settings;
1775 const char *printer;
1776 GtkPaperSize *paper_size;
1777 DWORD measure_system;
1781 pagesetupdlg = (LPPAGESETUPDLGW)GlobalAlloc (GPTR, sizeof (PAGESETUPDLGW));
1785 free_settings = FALSE;
1786 if (settings == NULL)
1788 settings = gtk_print_settings_new ();
1789 free_settings = TRUE;
1792 memset (pagesetupdlg, 0, sizeof (PAGESETUPDLGW));
1794 pagesetupdlg->lStructSize = sizeof(PAGESETUPDLGW);
1797 pagesetupdlg->hwndOwner = get_parent_hwnd (GTK_WIDGET (parent));
1799 pagesetupdlg->hwndOwner = NULL;
1801 pagesetupdlg->Flags = PSD_DEFAULTMINMARGINS;
1802 pagesetupdlg->hDevMode = devmode_from_settings (settings, page_setup);
1803 pagesetupdlg->hDevNames = NULL;
1804 printer = gtk_print_settings_get_printer (settings);
1806 pagesetupdlg->hDevNames = gtk_print_win32_devnames_from_printer_name (printer);
1808 GetLocaleInfoW(LOCALE_USER_DEFAULT, LOCALE_IMEASURE|LOCALE_RETURN_NUMBER,
1809 (LPWSTR)&measure_system, sizeof (DWORD));
1811 if (measure_system == 0)
1813 pagesetupdlg->Flags |= PSD_INHUNDREDTHSOFMILLIMETERS;
1819 pagesetupdlg->Flags |= PSD_INTHOUSANDTHSOFINCHES;
1820 unit = GTK_UNIT_INCH;
1824 /* This is the object we return, we allocate it here so that
1825 * we can use the default page margins */
1827 page_setup = gtk_page_setup_copy (page_setup);
1829 page_setup = gtk_page_setup_new ();
1831 pagesetupdlg->Flags |= PSD_MARGINS;
1832 pagesetupdlg->rtMargin.left =
1833 floor (gtk_page_setup_get_left_margin (page_setup, unit) * scale + 0.5);
1834 pagesetupdlg->rtMargin.right =
1835 floor (gtk_page_setup_get_right_margin (page_setup, unit) * scale + 0.5);
1836 pagesetupdlg->rtMargin.top =
1837 floor (gtk_page_setup_get_top_margin (page_setup, unit) * scale + 0.5);
1838 pagesetupdlg->rtMargin.bottom =
1839 floor (gtk_page_setup_get_bottom_margin (page_setup, unit) * scale + 0.5);
1841 pagesetupdlg->Flags |= PSD_ENABLEPAGESETUPHOOK;
1842 pagesetupdlg->lpfnPageSetupHook = run_mainloop_hook;
1843 got_gdk_events_message = RegisterWindowMessage ("GDK_WIN32_GOT_EVENTS");
1845 res = PageSetupDlgW (pagesetupdlg);
1846 gdk_win32_set_modal_dialog_libgtk_only (NULL);
1850 if (pagesetupdlg->hDevNames != NULL)
1851 devnames_to_settings (settings, pagesetupdlg->hDevNames);
1853 if (pagesetupdlg->hDevMode != NULL)
1854 devmode_to_settings (settings, pagesetupdlg->hDevMode);
1858 g_object_unref (settings);
1862 gtk_page_setup_set_orientation (page_setup,
1863 gtk_print_settings_get_orientation (settings));
1864 paper_size = gtk_print_settings_get_paper_size (settings);
1867 gtk_page_setup_set_paper_size (page_setup, paper_size);
1868 gtk_paper_size_free (paper_size);
1871 if (pagesetupdlg->Flags & PSD_INHUNDREDTHSOFMILLIMETERS)
1878 unit = GTK_UNIT_INCH;
1882 gtk_page_setup_set_left_margin (page_setup,
1883 pagesetupdlg->rtMargin.left / scale,
1885 gtk_page_setup_set_right_margin (page_setup,
1886 pagesetupdlg->rtMargin.right / scale,
1888 gtk_page_setup_set_top_margin (page_setup,
1889 pagesetupdlg->rtMargin.top / scale,
1891 gtk_page_setup_set_bottom_margin (page_setup,
1892 pagesetupdlg->rtMargin.bottom / scale,
1900 gtk_print_run_page_setup_dialog_async (GtkWindow *parent,
1901 GtkPageSetup *page_setup,
1902 GtkPrintSettings *settings,
1903 GtkPageSetupDoneFunc done_cb,
1906 GtkPageSetup *new_page_setup;
1908 new_page_setup = gtk_print_run_page_setup_dialog (parent, page_setup, settings);
1909 done_cb (new_page_setup, data);
1910 g_object_unref (new_page_setup);
1913 #define __GTK_PRINT_OPERATION_WIN32_C__
1914 #include "gtkaliasdef.c"