[email protected] | 55e8e9f | 2012-03-02 22:50:54 | [diff] [blame] | 1 | // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
license.bot | bf09a50 | 2008-08-24 00:55:55 | [diff] [blame] | 2 | // Use of this source code is governed by a BSD-style license that can be |
| 3 | // found in the LICENSE file. |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 4 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 5 | #include "printing/printing_context_win.h" |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 6 | |
[email protected] | 19f09a6 | 2011-05-04 23:37:47 | [diff] [blame] | 7 | #include <algorithm> |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 8 | #include <vector> |
[email protected] | 19f09a6 | 2011-05-04 23:37:47 | [diff] [blame] | 9 | |
vitalybuka | 12b8758 | 2014-12-08 18:57:10 | [diff] [blame] | 10 | #include "base/bind.h" |
dcheng | db5935f | 2016-03-26 00:16:27 | [diff] [blame] | 11 | #include "base/memory/free_deleter.h" |
dcheng | c3df9ba | 2016-04-07 23:09:32 | [diff] [blame] | 12 | #include "base/memory/ptr_util.h" |
gab | f64a25e | 2017-05-12 19:42:56 | [diff] [blame^] | 13 | #include "base/message_loop/message_loop.h" |
[email protected] | ad3b0501 | 2014-06-16 23:02:15 | [diff] [blame] | 14 | #include "base/strings/string_number_conversions.h" |
[email protected] | 90626587 | 2013-06-07 22:40:45 | [diff] [blame] | 15 | #include "base/strings/utf_string_conversions.h" |
[email protected] | 09083eb | 2012-09-20 05:58:43 | [diff] [blame] | 16 | #include "printing/backend/print_backend.h" |
[email protected] | 55e8e9f | 2012-03-02 22:50:54 | [diff] [blame] | 17 | #include "printing/backend/win_helper.h" |
Brett Wilson | 65f951c | 2016-11-03 22:06:12 | [diff] [blame] | 18 | #include "printing/features/features.h" |
[email protected] | 4993f34 | 2010-10-26 17:57:52 | [diff] [blame] | 19 | #include "printing/print_settings_initializer_win.h" |
[email protected] | 8ff1d42 | 2009-07-07 21:31:39 | [diff] [blame] | 20 | #include "printing/printed_document.h" |
vitalybuka | f9d0c0c | 2014-09-09 19:53:33 | [diff] [blame] | 21 | #include "printing/printing_context_system_dialog_win.h" |
[email protected] | ec91bfa | 2013-11-09 17:24:27 | [diff] [blame] | 22 | #include "printing/printing_utils.h" |
[email protected] | e5636a5 | 2011-09-28 21:44:42 | [diff] [blame] | 23 | #include "printing/units.h" |
tomhudson | 828dddb | 2015-12-04 14:34:16 | [diff] [blame] | 24 | #include "skia/ext/skia_utils_win.h" |
[email protected] | 6b7bfd2 | 2013-05-28 23:55:15 | [diff] [blame] | 25 | #include "ui/aura/window.h" |
samli | 6d8217f | 2016-01-20 04:12:20 | [diff] [blame] | 26 | #include "ui/aura/window_tree_host.h" |
[email protected] | 6b7bfd2 | 2013-05-28 23:55:15 | [diff] [blame] | 27 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 28 | namespace printing { |
| 29 | |
vitalybuka | 12b8758 | 2014-12-08 18:57:10 | [diff] [blame] | 30 | namespace { |
| 31 | |
thestig | e85e6b6 | 2016-08-25 00:00:06 | [diff] [blame] | 32 | void AssignResult(PrintingContext::Result* out, PrintingContext::Result in) { |
vitalybuka | 12b8758 | 2014-12-08 18:57:10 | [diff] [blame] | 33 | *out = in; |
| 34 | } |
| 35 | |
| 36 | } // namespace |
| 37 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 38 | // static |
dcheng | c3df9ba | 2016-04-07 23:09:32 | [diff] [blame] | 39 | std::unique_ptr<PrintingContext> PrintingContext::Create(Delegate* delegate) { |
Brett Wilson | 65f951c | 2016-11-03 22:06:12 | [diff] [blame] | 40 | #if BUILDFLAG(ENABLE_BASIC_PRINTING) |
thestig | e85e6b6 | 2016-08-25 00:00:06 | [diff] [blame] | 41 | return base::WrapUnique(new PrintingContextSystemDialogWin(delegate)); |
| 42 | #else |
dcheng | c3df9ba | 2016-04-07 23:09:32 | [diff] [blame] | 43 | return base::WrapUnique(new PrintingContextWin(delegate)); |
thestig | e85e6b6 | 2016-08-25 00:00:06 | [diff] [blame] | 44 | #endif |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 45 | } |
| 46 | |
Vitaly Buka | bd7c981 | 2014-08-26 08:57:54 | [diff] [blame] | 47 | PrintingContextWin::PrintingContextWin(Delegate* delegate) |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 48 | : PrintingContext(delegate), context_(nullptr) {} |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 49 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 50 | PrintingContextWin::~PrintingContextWin() { |
| 51 | ReleaseContext(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 52 | } |
| 53 | |
[email protected] | abe4811 | 2011-11-19 01:58:38 | [diff] [blame] | 54 | void PrintingContextWin::AskUserForSettings( |
Vitaly Buka | bd7c981 | 2014-08-26 08:57:54 | [diff] [blame] | 55 | int max_pages, |
| 56 | bool has_selection, |
dgn | 4c172eea | 2014-12-15 21:11:23 | [diff] [blame] | 57 | bool is_scripted, |
[email protected] | abe4811 | 2011-11-19 01:58:38 | [diff] [blame] | 58 | const PrintSettingsCallback& callback) { |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 59 | NOTIMPLEMENTED(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 60 | } |
| 61 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 62 | PrintingContext::Result PrintingContextWin::UseDefaultSettings() { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 63 | DCHECK(!in_print_job_); |
| 64 | |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 65 | scoped_refptr<PrintBackend> backend = PrintBackend::CreateInstance(nullptr); |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 66 | base::string16 default_printer = |
| 67 | base::UTF8ToWide(backend->GetDefaultPrinterName()); |
| 68 | if (!default_printer.empty()) { |
| 69 | ScopedPrinterHandle printer; |
| 70 | if (printer.OpenPrinter(default_printer.c_str())) { |
dcheng | c3df9ba | 2016-04-07 23:09:32 | [diff] [blame] | 71 | std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode = |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 72 | CreateDevMode(printer.Get(), nullptr); |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 73 | if (InitializeSettings(default_printer, dev_mode.get()) == OK) |
| 74 | return OK; |
| 75 | } |
| 76 | } |
| 77 | |
| 78 | ReleaseContext(); |
[email protected] | ff3ccc2 | 2011-04-18 21:35:48 | [diff] [blame] | 79 | |
| 80 | // No default printer configured, do we have any printers at all? |
| 81 | DWORD bytes_needed = 0; |
| 82 | DWORD count_returned = 0; |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 83 | (void)::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, nullptr, |
| 84 | 2, nullptr, 0, &bytes_needed, &count_returned); |
[email protected] | ff3ccc2 | 2011-04-18 21:35:48 | [diff] [blame] | 85 | if (bytes_needed) { |
[email protected] | 1b24888 | 2014-02-25 04:39:14 | [diff] [blame] | 86 | DCHECK_GE(bytes_needed, count_returned * sizeof(PRINTER_INFO_2)); |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 87 | std::vector<BYTE> printer_info_buffer(bytes_needed); |
| 88 | BOOL ret = ::EnumPrinters(PRINTER_ENUM_LOCAL | PRINTER_ENUM_CONNECTIONS, |
| 89 | nullptr, 2, printer_info_buffer.data(), |
| 90 | bytes_needed, &bytes_needed, &count_returned); |
[email protected] | ff3ccc2 | 2011-04-18 21:35:48 | [diff] [blame] | 91 | if (ret && count_returned) { // have printers |
| 92 | // Open the first successfully found printer. |
[email protected] | 1b24888 | 2014-02-25 04:39:14 | [diff] [blame] | 93 | const PRINTER_INFO_2* info_2 = |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 94 | reinterpret_cast<PRINTER_INFO_2*>(printer_info_buffer.data()); |
[email protected] | 1b24888 | 2014-02-25 04:39:14 | [diff] [blame] | 95 | const PRINTER_INFO_2* info_2_end = info_2 + count_returned; |
| 96 | for (; info_2 < info_2_end; ++info_2) { |
| 97 | ScopedPrinterHandle printer; |
| 98 | if (!printer.OpenPrinter(info_2->pPrinterName)) |
[email protected] | ff3ccc2 | 2011-04-18 21:35:48 | [diff] [blame] | 99 | continue; |
dcheng | c3df9ba | 2016-04-07 23:09:32 | [diff] [blame] | 100 | std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode = |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 101 | CreateDevMode(printer.Get(), nullptr); |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 102 | if (InitializeSettings(info_2->pPrinterName, dev_mode.get()) == OK) |
[email protected] | 1b24888 | 2014-02-25 04:39:14 | [diff] [blame] | 103 | return OK; |
[email protected] | ff3ccc2 | 2011-04-18 21:35:48 | [diff] [blame] | 104 | } |
| 105 | if (context_) |
| 106 | return OK; |
| 107 | } |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 108 | } |
[email protected] | ff3ccc2 | 2011-04-18 21:35:48 | [diff] [blame] | 109 | |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 110 | return OnError(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 111 | } |
| 112 | |
[email protected] | 4c9054b | 2013-11-04 18:34:29 | [diff] [blame] | 113 | gfx::Size PrintingContextWin::GetPdfPaperSizeDeviceUnits() { |
| 114 | // Default fallback to Letter size. |
| 115 | gfx::SizeF paper_size(kLetterWidthInch, kLetterHeightInch); |
| 116 | |
| 117 | // Get settings from locale. Paper type buffer length is at most 4. |
| 118 | const int paper_type_buffer_len = 4; |
| 119 | wchar_t paper_type_buffer[paper_type_buffer_len] = {0}; |
| 120 | GetLocaleInfo(LOCALE_USER_DEFAULT, LOCALE_IPAPERSIZE, paper_type_buffer, |
| 121 | paper_type_buffer_len); |
| 122 | if (wcslen(paper_type_buffer)) { // The call succeeded. |
| 123 | int paper_code = _wtoi(paper_type_buffer); |
| 124 | switch (paper_code) { |
| 125 | case DMPAPER_LEGAL: |
| 126 | paper_size.SetSize(kLegalWidthInch, kLegalHeightInch); |
| 127 | break; |
| 128 | case DMPAPER_A4: |
| 129 | paper_size.SetSize(kA4WidthInch, kA4HeightInch); |
| 130 | break; |
| 131 | case DMPAPER_A3: |
| 132 | paper_size.SetSize(kA3WidthInch, kA3HeightInch); |
| 133 | break; |
| 134 | default: // DMPAPER_LETTER is used for default fallback. |
| 135 | break; |
| 136 | } |
| 137 | } |
| 138 | return gfx::Size( |
| 139 | paper_size.width() * settings_.device_units_per_inch(), |
| 140 | paper_size.height() * settings_.device_units_per_inch()); |
| 141 | } |
| 142 | |
[email protected] | 55b23a0 | 2011-08-17 23:09:36 | [diff] [blame] | 143 | PrintingContext::Result PrintingContextWin::UpdatePrinterSettings( |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 144 | bool external_preview, |
vitalybuka | 95fa3c9 | 2015-05-05 03:03:32 | [diff] [blame] | 145 | bool show_system_dialog, |
| 146 | int page_count) { |
[email protected] | 7868ecab | 2011-03-05 00:12:53 | [diff] [blame] | 147 | DCHECK(!in_print_job_); |
[email protected] | e5324b5 | 2013-10-29 03:16:37 | [diff] [blame] | 148 | DCHECK(!external_preview) << "Not implemented"; |
[email protected] | 7868ecab | 2011-03-05 00:12:53 | [diff] [blame] | 149 | |
[email protected] | 55e8e9f | 2012-03-02 22:50:54 | [diff] [blame] | 150 | ScopedPrinterHandle printer; |
[email protected] | 1b24888 | 2014-02-25 04:39:14 | [diff] [blame] | 151 | if (!printer.OpenPrinter(settings_.device_name().c_str())) |
[email protected] | bd5baaf | 2011-04-21 20:48:33 | [diff] [blame] | 152 | return OnError(); |
[email protected] | afbdbf11 | 2011-03-28 22:09:37 | [diff] [blame] | 153 | |
[email protected] | 30aaa81a | 2011-05-03 21:08:39 | [diff] [blame] | 154 | // Make printer changes local to Chrome. |
| 155 | // See MSDN documentation regarding DocumentProperties. |
dcheng | c3df9ba | 2016-04-07 23:09:32 | [diff] [blame] | 156 | std::unique_ptr<DEVMODE, base::FreeDeleter> scoped_dev_mode = |
rvargas | 9b7c6b0f | 2014-09-25 19:22:48 | [diff] [blame] | 157 | CreateDevModeWithColor(printer.Get(), settings_.device_name(), |
[email protected] | b3b6b6f | 2014-02-14 20:19:54 | [diff] [blame] | 158 | settings_.color() != GRAY); |
| 159 | if (!scoped_dev_mode) |
[email protected] | bd5baaf | 2011-04-21 20:48:33 | [diff] [blame] | 160 | return OnError(); |
[email protected] | 7868ecab | 2011-03-05 00:12:53 | [diff] [blame] | 161 | |
[email protected] | b3b6b6f | 2014-02-14 20:19:54 | [diff] [blame] | 162 | { |
| 163 | DEVMODE* dev_mode = scoped_dev_mode.get(); |
| 164 | dev_mode->dmCopies = std::max(settings_.copies(), 1); |
[email protected] | 299e3d00 | 2014-06-03 08:46:49 | [diff] [blame] | 165 | if (dev_mode->dmCopies > 1) { // do not change unless multiple copies |
[email protected] | b3b6b6f | 2014-02-14 20:19:54 | [diff] [blame] | 166 | dev_mode->dmFields |= DM_COPIES; |
| 167 | dev_mode->dmCollate = settings_.collate() ? DMCOLLATE_TRUE : |
| 168 | DMCOLLATE_FALSE; |
| 169 | } |
[email protected] | f3256b0d8 | 2011-09-04 23:36:29 | [diff] [blame] | 170 | |
[email protected] | b3b6b6f | 2014-02-14 20:19:54 | [diff] [blame] | 171 | switch (settings_.duplex_mode()) { |
| 172 | case LONG_EDGE: |
| 173 | dev_mode->dmFields |= DM_DUPLEX; |
| 174 | dev_mode->dmDuplex = DMDUP_VERTICAL; |
| 175 | break; |
| 176 | case SHORT_EDGE: |
| 177 | dev_mode->dmFields |= DM_DUPLEX; |
| 178 | dev_mode->dmDuplex = DMDUP_HORIZONTAL; |
| 179 | break; |
| 180 | case SIMPLEX: |
| 181 | dev_mode->dmFields |= DM_DUPLEX; |
| 182 | dev_mode->dmDuplex = DMDUP_SIMPLEX; |
| 183 | break; |
| 184 | default: // UNKNOWN_DUPLEX_MODE |
| 185 | break; |
| 186 | } |
| 187 | |
| 188 | dev_mode->dmFields |= DM_ORIENTATION; |
| 189 | dev_mode->dmOrientation = settings_.landscape() ? DMORIENT_LANDSCAPE : |
| 190 | DMORIENT_PORTRAIT; |
[email protected] | ad3b0501 | 2014-06-16 23:02:15 | [diff] [blame] | 191 | |
rbpotter | 116c2e1 | 2017-04-04 19:21:28 | [diff] [blame] | 192 | if (settings_.dpi_horizontal() > 0) { |
| 193 | dev_mode->dmPrintQuality = settings_.dpi_horizontal(); |
| 194 | dev_mode->dmFields |= DM_PRINTQUALITY; |
| 195 | } |
| 196 | if (settings_.dpi_vertical() > 0) { |
| 197 | dev_mode->dmYResolution = settings_.dpi_vertical(); |
| 198 | dev_mode->dmFields |= DM_YRESOLUTION; |
| 199 | } |
| 200 | |
[email protected] | ad3b0501 | 2014-06-16 23:02:15 | [diff] [blame] | 201 | const PrintSettings::RequestedMedia& requested_media = |
| 202 | settings_.requested_media(); |
| 203 | static const int kFromUm = 100; // Windows uses 0.1mm. |
| 204 | int width = requested_media.size_microns.width() / kFromUm; |
| 205 | int height = requested_media.size_microns.height() / kFromUm; |
| 206 | unsigned id = 0; |
| 207 | if (base::StringToUint(requested_media.vendor_id, &id) && id) { |
| 208 | dev_mode->dmFields |= DM_PAPERSIZE; |
| 209 | dev_mode->dmPaperSize = static_cast<short>(id); |
| 210 | } else if (width > 0 && height > 0) { |
| 211 | dev_mode->dmFields |= DM_PAPERWIDTH; |
| 212 | dev_mode->dmPaperWidth = width; |
| 213 | dev_mode->dmFields |= DM_PAPERLENGTH; |
| 214 | dev_mode->dmPaperLength = height; |
| 215 | } |
[email protected] | e5324b5 | 2013-10-29 03:16:37 | [diff] [blame] | 216 | } |
[email protected] | bd5baaf | 2011-04-21 20:48:33 | [diff] [blame] | 217 | |
[email protected] | 30aaa81a | 2011-05-03 21:08:39 | [diff] [blame] | 218 | // Update data using DocumentProperties. |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 219 | if (show_system_dialog) { |
vitalybuka | 12b8758 | 2014-12-08 18:57:10 | [diff] [blame] | 220 | PrintingContext::Result result = PrintingContext::FAILED; |
vitalybuka | 95fa3c9 | 2015-05-05 03:03:32 | [diff] [blame] | 221 | AskUserForSettings(page_count, false, false, |
thestig | e85e6b6 | 2016-08-25 00:00:06 | [diff] [blame] | 222 | base::Bind(&AssignResult, &result)); |
vitalybuka | 12b8758 | 2014-12-08 18:57:10 | [diff] [blame] | 223 | return result; |
[email protected] | bd5baaf | 2011-04-21 20:48:33 | [diff] [blame] | 224 | } |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 225 | // Set printer then refresh printer settings. |
thestig | e85e6b6 | 2016-08-25 00:00:06 | [diff] [blame] | 226 | scoped_dev_mode = CreateDevMode(printer.Get(), scoped_dev_mode.get()); |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 227 | return InitializeSettings(settings_.device_name(), scoped_dev_mode.get()); |
[email protected] | 7868ecab | 2011-03-05 00:12:53 | [diff] [blame] | 228 | } |
| 229 | |
thestig | 5f68391 | 2016-09-30 22:42:16 | [diff] [blame] | 230 | PrintingContext::Result PrintingContextWin::InitWithSettingsForTest( |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 231 | const PrintSettings& settings) { |
| 232 | DCHECK(!in_print_job_); |
[email protected] | 4993f34 | 2010-10-26 17:57:52 | [diff] [blame] | 233 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 234 | settings_ = settings; |
[email protected] | 4993f34 | 2010-10-26 17:57:52 | [diff] [blame] | 235 | |
| 236 | // TODO(maruel): settings_.ToDEVMODE() |
[email protected] | 55e8e9f | 2012-03-02 22:50:54 | [diff] [blame] | 237 | ScopedPrinterHandle printer; |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 238 | if (!printer.OpenPrinter(settings_.device_name().c_str())) |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 239 | return FAILED; |
| 240 | |
dcheng | c3df9ba | 2016-04-07 23:09:32 | [diff] [blame] | 241 | std::unique_ptr<DEVMODE, base::FreeDeleter> dev_mode = |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 242 | CreateDevMode(printer.Get(), nullptr); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 243 | |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 244 | return InitializeSettings(settings_.device_name(), dev_mode.get()); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 245 | } |
| 246 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 247 | PrintingContext::Result PrintingContextWin::NewDocument( |
[email protected] | b5fa4ee | 2013-10-01 07:19:07 | [diff] [blame] | 248 | const base::string16& document_name) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 249 | DCHECK(!in_print_job_); |
[email protected] | b75dca8 | 2009-10-13 18:46:21 | [diff] [blame] | 250 | if (!context_) |
[email protected] | c8ad40c | 2009-06-08 17:05:21 | [diff] [blame] | 251 | return OnError(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 252 | |
| 253 | // Set the flag used by the AbortPrintJob dialog procedure. |
| 254 | abort_printing_ = false; |
| 255 | |
| 256 | in_print_job_ = true; |
| 257 | |
| 258 | // Register the application's AbortProc function with GDI. |
[email protected] | b75dca8 | 2009-10-13 18:46:21 | [diff] [blame] | 259 | if (SP_ERROR == SetAbortProc(context_, &AbortProc)) |
[email protected] | c8ad40c | 2009-06-08 17:05:21 | [diff] [blame] | 260 | return OnError(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 261 | |
[email protected] | ec91bfa | 2013-11-09 17:24:27 | [diff] [blame] | 262 | DCHECK(SimplifyDocumentTitle(document_name) == document_name); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 263 | DOCINFO di = { sizeof(DOCINFO) }; |
[email protected] | 299e3d00 | 2014-06-03 08:46:49 | [diff] [blame] | 264 | di.lpszDocName = document_name.c_str(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 265 | |
| 266 | // Is there a debug dump directory specified? If so, force to print to a file. |
[email protected] | c95198b | 2014-06-12 16:56:55 | [diff] [blame] | 267 | base::string16 debug_dump_path = |
| 268 | PrintedDocument::CreateDebugDumpPath(document_name, |
| 269 | FILE_PATH_LITERAL(".prn")).value(); |
| 270 | if (!debug_dump_path.empty()) |
| 271 | di.lpszOutput = debug_dump_path.c_str(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 272 | |
[email protected] | daee497 | 2009-07-09 14:28:24 | [diff] [blame] | 273 | // No message loop running in unit tests. |
[email protected] | f58ef2b | 2013-05-06 22:43:57 | [diff] [blame] | 274 | DCHECK(!base::MessageLoop::current() || |
| 275 | !base::MessageLoop::current()->NestableTasksAllowed()); |
[email protected] | daee497 | 2009-07-09 14:28:24 | [diff] [blame] | 276 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 277 | // Begin a print job by calling the StartDoc function. |
| 278 | // NOTE: StartDoc() starts a message loop. That causes a lot of problems with |
| 279 | // IPC. Make sure recursive task processing is disabled. |
[email protected] | b75dca8 | 2009-10-13 18:46:21 | [diff] [blame] | 280 | if (StartDoc(context_, &di) <= 0) |
[email protected] | c8ad40c | 2009-06-08 17:05:21 | [diff] [blame] | 281 | return OnError(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 282 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 283 | return OK; |
| 284 | } |
| 285 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 286 | PrintingContext::Result PrintingContextWin::NewPage() { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 287 | if (abort_printing_) |
| 288 | return CANCEL; |
[email protected] | 3b52c98 | 2010-09-27 20:40:36 | [diff] [blame] | 289 | DCHECK(context_); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 290 | DCHECK(in_print_job_); |
| 291 | |
vitalybuka | fdd3212ca | 2014-08-29 03:11:56 | [diff] [blame] | 292 | // Intentional No-op. PdfMetafileSkia::SafePlayback takes care of calling |
[email protected] | b10c54d | 2011-03-16 18:22:35 | [diff] [blame] | 293 | // ::StartPage(). |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 294 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 295 | return OK; |
| 296 | } |
| 297 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 298 | PrintingContext::Result PrintingContextWin::PageDone() { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 299 | if (abort_printing_) |
| 300 | return CANCEL; |
| 301 | DCHECK(in_print_job_); |
| 302 | |
vitalybuka | fdd3212ca | 2014-08-29 03:11:56 | [diff] [blame] | 303 | // Intentional No-op. PdfMetafileSkia::SafePlayback takes care of calling |
[email protected] | b10c54d | 2011-03-16 18:22:35 | [diff] [blame] | 304 | // ::EndPage(). |
| 305 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 306 | return OK; |
| 307 | } |
| 308 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 309 | PrintingContext::Result PrintingContextWin::DocumentDone() { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 310 | if (abort_printing_) |
| 311 | return CANCEL; |
| 312 | DCHECK(in_print_job_); |
[email protected] | 6074541 | 2010-09-27 23:46:07 | [diff] [blame] | 313 | DCHECK(context_); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 314 | |
| 315 | // Inform the driver that document has ended. |
[email protected] | b75dca8 | 2009-10-13 18:46:21 | [diff] [blame] | 316 | if (EndDoc(context_) <= 0) |
[email protected] | c8ad40c | 2009-06-08 17:05:21 | [diff] [blame] | 317 | return OnError(); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 318 | |
| 319 | ResetSettings(); |
| 320 | return OK; |
| 321 | } |
| 322 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 323 | void PrintingContextWin::Cancel() { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 324 | abort_printing_ = true; |
| 325 | in_print_job_ = false; |
[email protected] | b75dca8 | 2009-10-13 18:46:21 | [diff] [blame] | 326 | if (context_) |
| 327 | CancelDC(context_); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 328 | } |
| 329 | |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 330 | void PrintingContextWin::ReleaseContext() { |
| 331 | if (context_) { |
| 332 | DeleteDC(context_); |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 333 | context_ = nullptr; |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 334 | } |
| 335 | } |
| 336 | |
tfarina | 876d1e0 | 2016-10-11 23:12:53 | [diff] [blame] | 337 | skia::NativeDrawingContext PrintingContextWin::context() const { |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 338 | return context_; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 339 | } |
| 340 | |
| 341 | // static |
[email protected] | 51e8d935 | 2010-10-06 22:21:17 | [diff] [blame] | 342 | BOOL PrintingContextWin::AbortProc(HDC hdc, int nCode) { |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 343 | if (nCode) { |
| 344 | // TODO(maruel): Need a way to find the right instance to set. Should |
| 345 | // leverage PrintJobManager here? |
| 346 | // abort_printing_ = true; |
| 347 | } |
| 348 | return true; |
| 349 | } |
| 350 | |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 351 | PrintingContext::Result PrintingContextWin::InitializeSettings( |
| 352 | const std::wstring& device_name, |
| 353 | DEVMODE* dev_mode) { |
| 354 | if (!dev_mode) |
| 355 | return OnError(); |
| 356 | |
| 357 | ReleaseContext(); |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 358 | context_ = CreateDC(L"WINSPOOL", device_name.c_str(), nullptr, dev_mode); |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 359 | if (!context_) |
| 360 | return OnError(); |
| 361 | |
[email protected] | 62f2e80 | 2011-05-26 14:28:35 | [diff] [blame] | 362 | skia::InitializeDC(context_); |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 363 | |
| 364 | DCHECK(!in_print_job_); |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 365 | settings_.set_device_name(device_name); |
| 366 | PrintSettingsInitializerWin::InitPrintSettings( |
| 367 | context_, *dev_mode, &settings_); |
[email protected] | 4993f34 | 2010-10-26 17:57:52 | [diff] [blame] | 368 | |
vitalybuka | 92ab8ce | 2014-08-26 23:41:45 | [diff] [blame] | 369 | return OK; |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 370 | } |
| 371 | |
vitalybuka | f9d0c0c | 2014-09-09 19:53:33 | [diff] [blame] | 372 | HWND PrintingContextWin::GetRootWindow(gfx::NativeView view) { |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 373 | HWND window = nullptr; |
vitalybuka | a58ec6a | 2015-02-23 18:30:49 | [diff] [blame] | 374 | if (view && view->GetHost()) |
vitalybuka | f9d0c0c | 2014-09-09 19:53:33 | [diff] [blame] | 375 | window = view->GetHost()->GetAcceleratedWidget(); |
vitalybuka | f9d0c0c | 2014-09-09 19:53:33 | [diff] [blame] | 376 | if (!window) { |
thestig | b50a0c33 | 2016-09-30 04:22:45 | [diff] [blame] | 377 | // TODO(maruel): b/1214347 Get the right browser window instead. |
vitalybuka | f9d0c0c | 2014-09-09 19:53:33 | [diff] [blame] | 378 | return GetDesktopWindow(); |
| 379 | } |
| 380 | return window; |
| 381 | } |
| 382 | |
initial.commit | 09911bf | 2008-07-26 23:55:29 | [diff] [blame] | 383 | } // namespace printing |