Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(862)

Side by Side Diff: printing/backend/print_backend_win.cc

Issue 153373002: Extend PrinterSemanticCapsAndDefaults with Collate, Copies, PaperSize and Dpi capabilities. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Created 6 years, 10 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « printing/backend/print_backend.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
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/strings/string_piece.h" 11 #include "base/strings/string_piece.h"
12 #include "base/strings/utf_string_conversions.h" 12 #include "base/strings/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/printing_info_win.h"
18 #include "printing/backend/win_helper.h" 18 #include "printing/backend/win_helper.h"
19 19
20 namespace printing {
20 21
21 namespace { 22 namespace {
22 23
23 HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) { 24 HRESULT StreamOnHGlobalToString(IStream* stream, std::string* out) {
24 DCHECK(stream); 25 DCHECK(stream);
25 DCHECK(out); 26 DCHECK(out);
26 HGLOBAL hdata = NULL; 27 HGLOBAL hdata = NULL;
27 HRESULT hr = GetHGlobalFromStream(stream, &hdata); 28 HRESULT hr = GetHGlobalFromStream(stream, &hdata);
28 if (SUCCEEDED(hr)) { 29 if (SUCCEEDED(hr)) {
29 DCHECK(hdata); 30 DCHECK(hdata);
30 base::win::ScopedHGlobal<char> locked_data(hdata); 31 base::win::ScopedHGlobal<char> locked_data(hdata);
31 out->assign(locked_data.release(), locked_data.Size()); 32 out->assign(locked_data.release(), locked_data.Size());
32 } 33 }
33 return hr; 34 return hr;
34 } 35 }
35 36
37 template <class T>
38 void GetDeviceCapabilityArray(const wchar_t* printer,
39 const wchar_t* port,
40 WORD id,
41 std::vector<T>* result) {
42 int count = DeviceCapabilities(printer, port, id, NULL, NULL);
43 if (count <= 0)
44 return;
45 result->resize(count);
46 CHECK_EQ(count,
47 DeviceCapabilities(printer, port, id,
Noam Samuel 2014/02/04 18:33:22 Misaligned.
Vitaly Buka (NO REVIEWS) 2014/02/04 18:48:24 Done.
48 reinterpret_cast<LPTSTR>(result->data()), NULL));
49 }
50
51 void LoadPaper(const wchar_t* printer,
52 const wchar_t* port,
53 const DEVMODE* devmode,
54 PrinterSemanticCapsAndDefaults* caps) {
55 static const size_t kToUm = 100;
56 static const size_t kMaxPaperName = 64;
57
58 short default_id = 0;
59 gfx::Size default_size;
60
61 if (devmode) {
62 if ((devmode->dmFields & DM_PAPERSIZE) == DM_PAPERSIZE)
63 default_id = devmode->dmPaperSize;
64 if ((devmode->dmFields & DM_PAPERWIDTH) == DM_PAPERWIDTH)
65 default_size.set_width(devmode->dmPaperWidth * kToUm);
66 if ((devmode->dmFields & DM_PAPERLENGTH) == DM_PAPERLENGTH)
67 default_size.set_height(devmode->dmPaperLength * kToUm);
68 }
69
70 struct PaperName {
71 wchar_t chars[kMaxPaperName];
72 };
73
74 // Paper
75 std::vector<PaperName> names;
76 GetDeviceCapabilityArray(printer, port, DC_PAPERNAMES, &names);
77
78 std::vector<POINT> sizes;
79 GetDeviceCapabilityArray(printer, port, DC_PAPERSIZE, &sizes);
80
81 std::vector<WORD> ids;
82 GetDeviceCapabilityArray(printer, port, DC_PAPERS, &ids);
83
84 DCHECK_EQ(ids.size(), sizes.size());
85 DCHECK_EQ(names.size(), sizes.size());
86
87 if (ids.size() != sizes.size())
88 ids.clear();
89 if (names.size() != sizes.size())
90 names.clear();
91
92 for (size_t i = 0; i < sizes.size(); ++i) {
93 PrinterSemanticCapsAndDefaults::Paper paper;
94 paper.size_um.SetSize(sizes[i].x * kToUm, sizes[i].y * kToUm);
95 if (!names.empty()) {
96 paper.name.assign(&names[i].chars, &names[i].chars + kMaxPaperName);
97 // Trim trailing zeros.
98 paper.name = paper.name.c_str();
99 }
100 if (caps->default_paper < 0) {
101 if (!default_size.IsEmpty()) {
102 if (default_size == paper.size_um)
103 caps->default_paper = i;
104 } else if (default_id && !ids.empty() && ids[i] == default_id) {
105 caps->default_paper = i;
106 }
107 }
108 caps->papers.push_back(paper);
109 }
110
111 if (caps->default_paper < 0) {
112 // Add default paper because DeviceCapabilities it was not found yet.
Noam Samuel 2014/02/04 18:33:22 "Add default paper because DeviceCapabilities hasn
Vitaly Buka (NO REVIEWS) 2014/02/04 18:48:24 Done.
113 if (!default_size.IsEmpty()) {
114 caps->default_paper = caps->papers.size();
115 PrinterSemanticCapsAndDefaults::Paper paper;
116 paper.size_um = default_size;
117 paper.name = "CUSTOM";
118 caps->papers.push_back(paper);
119 }
120 }
121 }
122
123 void LoadDpi(const wchar_t* printer,
124 const wchar_t* port,
125 const DEVMODE* devmode,
126 PrinterSemanticCapsAndDefaults* caps) {
127 gfx::Size default_dpi;
128
129 if (devmode) {
130 if ((devmode->dmFields & DM_PRINTQUALITY) == DM_PRINTQUALITY &&
131 devmode->dmPrintQuality > 0) {
132 default_dpi.SetSize(devmode->dmPrintQuality, devmode->dmPrintQuality);
133 if ((devmode->dmFields & DM_YRESOLUTION) == DM_PRINTQUALITY) {
134 default_dpi.set_height(devmode->dmYResolution);
135 }
136 }
137 }
138
139 std::vector<POINT> dpis;
140 GetDeviceCapabilityArray(printer, port, DC_ENUMRESOLUTIONS, &dpis);
141
142 for (size_t i = 0; i < dpis.size() ; ++i) {
143 gfx::Size dpi(dpis[i].x, dpis[i].y);
144 if (caps->default_dpi < 0 && default_dpi == dpi)
145 caps->default_dpi = i;
146 caps->dpis.push_back(dpi);
147 }
148
149 if (caps->default_dpi < 0) {
150 // Add default dpi because DeviceCapabilities didn't return it.
151 if (!default_dpi.IsEmpty()) {
152 caps->default_dpi = caps->dpis.size();
153 caps->dpis.push_back(default_dpi);
154 }
155 }
156 }
157
36 } // namespace 158 } // namespace
37 159
38 namespace printing {
39
40 class PrintBackendWin : public PrintBackend { 160 class PrintBackendWin : public PrintBackend {
41 public: 161 public:
42 PrintBackendWin() {} 162 PrintBackendWin() {}
43 163
44 // PrintBackend implementation. 164 // PrintBackend implementation.
45 virtual bool EnumeratePrinters(PrinterList* printer_list) OVERRIDE; 165 virtual bool EnumeratePrinters(PrinterList* printer_list) OVERRIDE;
46 virtual std::string GetDefaultPrinterName() OVERRIDE; 166 virtual std::string GetDefaultPrinterName() OVERRIDE;
47 virtual bool GetPrinterSemanticCapsAndDefaults( 167 virtual bool GetPrinterSemanticCapsAndDefaults(
48 const std::string& printer_name, 168 const std::string& printer_name,
49 PrinterSemanticCapsAndDefaults* printer_info) OVERRIDE; 169 PrinterSemanticCapsAndDefaults* printer_info) OVERRIDE;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 bool PrintBackendWin::GetPrinterSemanticCapsAndDefaults( 221 bool PrintBackendWin::GetPrinterSemanticCapsAndDefaults(
102 const std::string& printer_name, 222 const std::string& printer_name,
103 PrinterSemanticCapsAndDefaults* printer_info) { 223 PrinterSemanticCapsAndDefaults* printer_info) {
104 ScopedPrinterHandle printer_handle; 224 ScopedPrinterHandle printer_handle;
105 if (!printer_handle.OpenPrinter(base::UTF8ToWide(printer_name).c_str())) { 225 if (!printer_handle.OpenPrinter(base::UTF8ToWide(printer_name).c_str())) {
106 LOG(WARNING) << "Failed to open printer, error = " << GetLastError(); 226 LOG(WARNING) << "Failed to open printer, error = " << GetLastError();
107 return false; 227 return false;
108 } 228 }
109 229
110 PrinterInfo5 info_5; 230 PrinterInfo5 info_5;
111 if (!info_5.Init(printer_handle)) { 231 if (!info_5.Init(printer_handle))
112 return false; 232 return false;
113 } 233 const wchar_t* name = info_5.get()->pPrinterName;
114 DCHECK_EQ(info_5.get()->pPrinterName, base::UTF8ToUTF16(printer_name)); 234 const wchar_t* port = info_5.get()->pPortName;
235 DCHECK_EQ(name, base::UTF8ToUTF16(printer_name));
115 236
116 PrinterSemanticCapsAndDefaults caps; 237 PrinterSemanticCapsAndDefaults caps;
117
118 // Get printer capabilities. For more info see here:
119 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).a spx
120 caps.color_changeable = (::DeviceCapabilities(info_5.get()->pPrinterName,
121 info_5.get()->pPortName,
122 DC_COLORDEVICE,
123 NULL,
124 NULL) == 1);
125
126 caps.duplex_capable = (::DeviceCapabilities(info_5.get()->pPrinterName,
127 info_5.get()->pPortName,
128 DC_DUPLEX,
129 NULL,
130 NULL) == 1);
131
132 UserDefaultDevMode user_settings; 238 UserDefaultDevMode user_settings;
133
134 if (user_settings.Init(printer_handle)) { 239 if (user_settings.Init(printer_handle)) {
135 if ((user_settings.get()->dmFields & DM_COLOR) == DM_COLOR) 240 if ((user_settings.get()->dmFields & DM_COLOR) == DM_COLOR)
136 caps.color_default = (user_settings.get()->dmColor == DMCOLOR_COLOR); 241 caps.color_default = (user_settings.get()->dmColor == DMCOLOR_COLOR);
137 242
138 if ((user_settings.get()->dmFields & DM_DUPLEX) == DM_DUPLEX) { 243 if ((user_settings.get()->dmFields & DM_DUPLEX) == DM_DUPLEX) {
139 switch (user_settings.get()->dmDuplex) { 244 switch (user_settings.get()->dmDuplex) {
140 case DMDUP_SIMPLEX: 245 case DMDUP_SIMPLEX:
141 caps.duplex_default = SIMPLEX; 246 caps.duplex_default = SIMPLEX;
142 break; 247 break;
143 case DMDUP_VERTICAL: 248 case DMDUP_VERTICAL:
144 caps.duplex_default = LONG_EDGE; 249 caps.duplex_default = LONG_EDGE;
145 break; 250 break;
146 case DMDUP_HORIZONTAL: 251 case DMDUP_HORIZONTAL:
147 caps.duplex_default = SHORT_EDGE; 252 caps.duplex_default = SHORT_EDGE;
148 break; 253 break;
149 default: 254 default:
150 NOTREACHED(); 255 NOTREACHED();
151 } 256 }
152 } 257 }
258
259 if ((user_settings.get()->dmFields & DM_COLLATE) == DM_COLLATE)
260 caps.collate_default = (user_settings.get()->dmCollate == DMCOLLATE_TRUE);
153 } else { 261 } else {
154 LOG(WARNING) << "Fallback to color/simplex mode."; 262 LOG(WARNING) << "Fallback to color/simplex mode.";
155 caps.color_default = caps.color_changeable; 263 caps.color_default = caps.color_changeable;
156 caps.duplex_default = SIMPLEX; 264 caps.duplex_default = SIMPLEX;
157 } 265 }
158 266
267 // Get printer capabilities. For more info see here:
268 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).a spx
269 caps.color_changeable =
270 (DeviceCapabilities(name, port, DC_COLORDEVICE, NULL, NULL) == 1);
271
272 caps.duplex_capable =
273 (DeviceCapabilities(name, port, DC_DUPLEX, NULL, NULL) == 1);
274
275 caps.collate_capable =
276 (DeviceCapabilities(name, port, DC_COLLATE, NULL, NULL) == 1);
277
278 caps.copies_capable =
279 (DeviceCapabilities(name, port, DC_COPIES, NULL, NULL) > 1);
280
281 LoadPaper(name, port, user_settings.get(), &caps);
282 LoadDpi(name, port, user_settings.get(), &caps);
283
159 *printer_info = caps; 284 *printer_info = caps;
160 return true; 285 return true;
161 } 286 }
162 287
163 bool PrintBackendWin::GetPrinterCapsAndDefaults( 288 bool PrintBackendWin::GetPrinterCapsAndDefaults(
164 const std::string& printer_name, 289 const std::string& printer_name,
165 PrinterCapsAndDefaults* printer_info) { 290 PrinterCapsAndDefaults* printer_info) {
166 ScopedXPSInitializer xps_initializer; 291 ScopedXPSInitializer xps_initializer;
167 if (!xps_initializer.initialized()) { 292 if (!xps_initializer.initialized()) {
168 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) 293 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll)
(...skipping 77 matching lines...) Expand 10 before | Expand all | Expand 10 after
246 ScopedPrinterHandle printer_handle; 371 ScopedPrinterHandle printer_handle;
247 return printer_handle.OpenPrinter(base::UTF8ToWide(printer_name).c_str()); 372 return printer_handle.OpenPrinter(base::UTF8ToWide(printer_name).c_str());
248 } 373 }
249 374
250 scoped_refptr<PrintBackend> PrintBackend::CreateInstance( 375 scoped_refptr<PrintBackend> PrintBackend::CreateInstance(
251 const base::DictionaryValue* print_backend_settings) { 376 const base::DictionaryValue* print_backend_settings) {
252 return new PrintBackendWin; 377 return new PrintBackendWin;
253 } 378 }
254 379
255 } // namespace printing 380 } // namespace printing
OLDNEW
« no previous file with comments | « printing/backend/print_backend.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698