| OLD | NEW |
| 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "printing/backend/print_backend.h" | 5 #include "printing/backend/print_backend.h" |
| 6 | 6 |
| 7 #include <objidl.h> | 7 #include <objidl.h> |
| 8 #include <winspool.h> | 8 #include <winspool.h> |
| 9 | 9 |
| 10 #include "base/memory/scoped_ptr.h" | 10 #include "base/memory/scoped_ptr.h" |
| 11 #include "base/string_piece.h" | 11 #include "base/string_piece.h" |
| 12 #include "base/utf_string_conversions.h" | 12 #include "base/utf_string_conversions.h" |
| 13 #include "base/win/scoped_bstr.h" | 13 #include "base/win/scoped_bstr.h" |
| 14 #include "base/win/scoped_comptr.h" | 14 #include "base/win/scoped_comptr.h" |
| 15 #include "base/win/scoped_hglobal.h" | 15 #include "base/win/scoped_hglobal.h" |
| 16 #include "printing/backend/print_backend_consts.h" | 16 #include "printing/backend/print_backend_consts.h" |
| 17 #include "printing/backend/printing_info_win.h" |
| 17 #include "printing/backend/win_helper.h" | 18 #include "printing/backend/win_helper.h" |
| 18 | 19 |
| 20 |
| 19 namespace { | 21 namespace { |
| 20 | 22 |
| 21 // This class is designed to work with PRINTER_INFO_X structures | |
| 22 // and calls GetPrinter internally with correctly allocated buffer. | |
| 23 template <typename T> | |
| 24 class PrinterInfo { | |
| 25 public: | |
| 26 bool GetPrinterInfo(HANDLE printer, int level) { | |
| 27 DWORD buf_size = 0; | |
| 28 GetPrinter(printer, level, NULL, 0, &buf_size); | |
| 29 if (buf_size == 0) { | |
| 30 LOG(WARNING) << "Failed to GetPrinter, error = " << GetLastError(); | |
| 31 return false; | |
| 32 } | |
| 33 buffer_.reset(new uint8[buf_size]); | |
| 34 memset(buffer_.get(), 0, buf_size); | |
| 35 return !!GetPrinter(printer, level, buffer_.get(), buf_size, &buf_size); | |
| 36 } | |
| 37 | |
| 38 const T* get() const { | |
| 39 return reinterpret_cast<T*>(buffer_.get()); | |
| 40 } | |
| 41 | |
| 42 private: | |
| 43 scoped_array<uint8> buffer_; | |
| 44 }; | |
| 45 | |
| 46 HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { | 23 HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { |
| 47 DCHECK(stream); | 24 DCHECK(stream); |
| 48 DCHECK(out); | 25 DCHECK(out); |
| 49 HGLOBAL hdata = NULL; | 26 HGLOBAL hdata = NULL; |
| 50 HRESULT hr = GetHGlobalFromStream(stream, &hdata); | 27 HRESULT hr = GetHGlobalFromStream(stream, &hdata); |
| 51 if (SUCCEEDED(hr)) { | 28 if (SUCCEEDED(hr)) { |
| 52 DCHECK(hdata); | 29 DCHECK(hdata); |
| 53 base::win::ScopedHGlobal<char> locked_data(hdata); | 30 base::win::ScopedHGlobal<char> locked_data(hdata); |
| 54 out->assign(locked_data.release(), locked_data.Size()); | 31 out->assign(locked_data.release(), locked_data.Size()); |
| 55 } | 32 } |
| (...skipping 70 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 126 PrinterSemanticCapsAndDefaults* printer_info) { | 103 PrinterSemanticCapsAndDefaults* printer_info) { |
| 127 ScopedPrinterHandle printer_handle; | 104 ScopedPrinterHandle printer_handle; |
| 128 OpenPrinter(const_cast<LPTSTR>(UTF8ToWide(printer_name).c_str()), | 105 OpenPrinter(const_cast<LPTSTR>(UTF8ToWide(printer_name).c_str()), |
| 129 printer_handle.Receive(), NULL); | 106 printer_handle.Receive(), NULL); |
| 130 DCHECK(printer_handle); | 107 DCHECK(printer_handle); |
| 131 if (!printer_handle.IsValid()) { | 108 if (!printer_handle.IsValid()) { |
| 132 LOG(WARNING) << "Failed to open printer, error = " << GetLastError(); | 109 LOG(WARNING) << "Failed to open printer, error = " << GetLastError(); |
| 133 return false; | 110 return false; |
| 134 } | 111 } |
| 135 | 112 |
| 136 PrinterInfo<PRINTER_INFO_5> info_5; | 113 PrinterInfo5 info_5; |
| 137 if (!info_5.GetPrinterInfo(printer_handle, 5)) { | 114 if (!info_5.Init(printer_handle)) { |
| 138 LOG(WARNING) << "Failed to get PRINTER_INFO_5, error = " << GetLastError(); | |
| 139 return false; | 115 return false; |
| 140 } | 116 } |
| 117 DCHECK_EQ(info_5.get()->pPrinterName, UTF8ToUTF16(printer_name)); |
| 118 |
| 119 PrinterSemanticCapsAndDefaults caps; |
| 141 | 120 |
| 142 // Get printer capabilities. For more info see here: | 121 // Get printer capabilities. For more info see here: |
| 143 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).a
spx | 122 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).a
spx |
| 144 bool color_supported = (DeviceCapabilities(info_5.get()->pPrinterName, | 123 caps.color_capable = (::DeviceCapabilities(info_5.get()->pPrinterName, |
| 145 info_5.get()->pPortName, | 124 info_5.get()->pPortName, |
| 146 DC_COLORDEVICE, | 125 DC_COLORDEVICE, |
| 147 NULL, | 126 NULL, |
| 148 NULL) == 1); | 127 NULL) == 1); |
| 149 | 128 |
| 150 bool duplex_supported = (DeviceCapabilities(info_5.get()->pPrinterName, | 129 caps.duplex_capable = (::DeviceCapabilities(info_5.get()->pPrinterName, |
| 151 info_5.get()->pPortName, | 130 info_5.get()->pPortName, |
| 152 DC_DUPLEX, | 131 DC_DUPLEX, |
| 153 NULL, | 132 NULL, |
| 154 NULL) == 1); | 133 NULL) == 1); |
| 155 | 134 |
| 156 DEVMODE* devmode = NULL; | 135 UserDefaultDevMode user_settings; |
| 157 // PRINTER_INFO_9 retrieves current user settings. | |
| 158 PrinterInfo<PRINTER_INFO_9> info_9; | |
| 159 if (info_9.GetPrinterInfo(printer_handle, 9)) { | |
| 160 devmode = info_9.get()->pDevMode; | |
| 161 } else { | |
| 162 LOG(WARNING) << "Failed to get PRINTER_INFO_9, error = " << GetLastError(); | |
| 163 } | |
| 164 | 136 |
| 165 // Sometimes user settings are not available (have not been setted up yet). | 137 if (user_settings.Init(printer_handle)) { |
| 166 // Use printer default settings (PRINTER_INFO_8) in this case. | 138 if ((user_settings.get()->dmFields & DM_COLOR) == DM_COLOR) |
| 167 PrinterInfo<PRINTER_INFO_8> info_8; | 139 caps.color_default = (user_settings.get()->dmColor == DMCOLOR_COLOR); |
| 168 if (!devmode) { | |
| 169 if (info_8.GetPrinterInfo(printer_handle, 8)) { | |
| 170 devmode = info_8.get()->pDevMode; | |
| 171 } else { | |
| 172 LOG(WARNING) << "Failed to get PRINTER_INFO_8, error = " << | |
| 173 GetLastError(); | |
| 174 } | |
| 175 } | |
| 176 if (!devmode) | |
| 177 return false; | |
| 178 | 140 |
| 179 PrinterSemanticCapsAndDefaults caps; | 141 if ((user_settings.get()->dmFields & DM_DUPLEX) == DM_DUPLEX) { |
| 180 caps.color_capable = color_supported; | 142 switch (user_settings.get()->dmDuplex) { |
| 181 if ((devmode->dmFields & DM_COLOR) == DM_COLOR) | |
| 182 caps.color_default = (devmode->dmColor == DMCOLOR_COLOR); | |
| 183 | |
| 184 caps.duplex_capable = duplex_supported; | |
| 185 if ((devmode->dmFields & DM_DUPLEX) == DM_DUPLEX) { | |
| 186 switch (devmode->dmDuplex) { | |
| 187 case DMDUP_SIMPLEX: | 143 case DMDUP_SIMPLEX: |
| 188 caps.duplex_default = SIMPLEX; | 144 caps.duplex_default = SIMPLEX; |
| 189 break; | 145 break; |
| 190 case DMDUP_VERTICAL: | 146 case DMDUP_VERTICAL: |
| 191 caps.duplex_default = LONG_EDGE; | 147 caps.duplex_default = LONG_EDGE; |
| 192 break; | 148 break; |
| 193 case DMDUP_HORIZONTAL: | 149 case DMDUP_HORIZONTAL: |
| 194 caps.duplex_default = SHORT_EDGE; | 150 caps.duplex_default = SHORT_EDGE; |
| 195 break; | 151 break; |
| 196 default: | 152 default: |
| 197 NOTREACHED(); | 153 NOTREACHED(); |
| 154 } |
| 198 } | 155 } |
| 156 } else { |
| 157 LOG(WARNING) << "Fallback to color/simplex mode."; |
| 158 caps.color_default = caps.color_capable; |
| 159 caps.duplex_default = SIMPLEX; |
| 199 } | 160 } |
| 200 | 161 |
| 201 *printer_info = caps; | 162 *printer_info = caps; |
| 202 return true; | 163 return true; |
| 203 } | 164 } |
| 204 | 165 |
| 205 bool PrintBackendWin::GetPrinterCapsAndDefaults( | 166 bool PrintBackendWin::GetPrinterCapsAndDefaults( |
| 206 const std::string& printer_name, | 167 const std::string& printer_name, |
| 207 PrinterCapsAndDefaults* printer_info) { | 168 PrinterCapsAndDefaults* printer_info) { |
| 208 ScopedXPSInitializer xps_initializer; | 169 ScopedXPSInitializer xps_initializer; |
| (...skipping 85 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 294 printer_handle.Receive(), NULL); | 255 printer_handle.Receive(), NULL); |
| 295 return printer_handle.IsValid(); | 256 return printer_handle.IsValid(); |
| 296 } | 257 } |
| 297 | 258 |
| 298 scoped_refptr<PrintBackend> PrintBackend::CreateInstance( | 259 scoped_refptr<PrintBackend> PrintBackend::CreateInstance( |
| 299 const base::DictionaryValue* print_backend_settings) { | 260 const base::DictionaryValue* print_backend_settings) { |
| 300 return new PrintBackendWin; | 261 return new PrintBackendWin; |
| 301 } | 262 } |
| 302 | 263 |
| 303 } // namespace printing | 264 } // namespace printing |
| OLD | NEW |