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 DevMode devmode; |
gene
2012/12/11 18:03:31
call variable user_settings ?
Vitaly Buka (NO REVIEWS)
2012/12/11 19:26:28
Done.
| |
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 (devmode.Init(printer_handle)) { |
166 // Use printer default settings (PRINTER_INFO_8) in this case. | 138 if ((devmode.get()->dmFields & DM_COLOR) == DM_COLOR) |
167 PrinterInfo<PRINTER_INFO_8> info_8; | 139 caps.color_default = (devmode.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 ((devmode.get()->dmFields & DM_DUPLEX) == DM_DUPLEX) { |
180 caps.color_capable = color_supported; | 142 switch (devmode.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 |