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

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: removed unnessesary indirection 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,
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; // Windows uses 0.1mm.
56 static const size_t kMaxPaperName = 64;
57
58 struct PaperName {
59 wchar_t chars[kMaxPaperName];
60 };
61
62 // Paper
63 std::vector<PaperName> names;
64 GetDeviceCapabilityArray(printer, port, DC_PAPERNAMES, &names);
65
66 std::vector<POINT> sizes;
67 GetDeviceCapabilityArray(printer, port, DC_PAPERSIZE, &sizes);
68
69 std::vector<WORD> ids;
70 GetDeviceCapabilityArray(printer, port, DC_PAPERS, &ids);
71
72 DCHECK_EQ(ids.size(), sizes.size());
73 DCHECK_EQ(names.size(), sizes.size());
74
75 if (ids.size() != sizes.size())
76 ids.clear();
77 if (names.size() != sizes.size())
78 names.clear();
79
80 for (size_t i = 0; i < sizes.size(); ++i) {
81 PrinterSemanticCapsAndDefaults::Paper paper;
82 paper.size_um.SetSize(sizes[i].x * kToUm, sizes[i].y * kToUm);
83 if (!names.empty()) {
84 paper.name.assign(&names[i].chars, &names[i].chars + kMaxPaperName);
85 // Trim trailing zeros.
86 paper.name = paper.name.c_str();
87 }
88 caps->papers.push_back(paper);
89 }
90
91 if (devmode) {
92 short default_id = 0;
93 gfx::Size default_size;
94
95 if ((devmode->dmFields & DM_PAPERSIZE) == DM_PAPERSIZE)
96 default_id = devmode->dmPaperSize;
97 if ((devmode->dmFields & DM_PAPERWIDTH) == DM_PAPERWIDTH)
98 default_size.set_width(devmode->dmPaperWidth * kToUm);
99 if ((devmode->dmFields & DM_PAPERLENGTH) == DM_PAPERLENGTH)
100 default_size.set_height(devmode->dmPaperLength * kToUm);
101
102 if (default_size.IsEmpty()) {
103 for (size_t i = 0; i < ids.size(); ++i) {
104 if (ids[i] == default_id) {
105 PrinterSemanticCapsAndDefaults::Paper paper;
106 paper.size_um.SetSize(sizes[i].x * kToUm, sizes[i].y * kToUm);
107 if (!names.empty()) {
108 paper.name.assign(&names[i].chars, &names[i].chars + kMaxPaperName);
109 // Trim trailing zeros.
110 paper.name = paper.name.c_str();
111 }
112 caps->default_paper = paper;
113 break;
114 }
115 }
116 } else {
117 caps->default_paper.size_um = default_size;
118 }
119 }
120 }
121
122 void LoadDpi(const wchar_t* printer,
123 const wchar_t* port,
124 const DEVMODE* devmode,
125 PrinterSemanticCapsAndDefaults* caps) {
126 std::vector<POINT> dpis;
127 GetDeviceCapabilityArray(printer, port, DC_ENUMRESOLUTIONS, &dpis);
128
129 for (size_t i = 0; i < dpis.size() ; ++i)
130 caps->dpis.push_back(gfx::Size(dpis[i].x, dpis[i].y));
131
132 if (devmode) {
133 if ((devmode->dmFields & DM_PRINTQUALITY) == DM_PRINTQUALITY &&
134 devmode->dmPrintQuality > 0) {
135 caps->default_dpi.SetSize(devmode->dmPrintQuality,
136 devmode->dmPrintQuality);
137 if ((devmode->dmFields & DM_YRESOLUTION) == DM_PRINTQUALITY) {
138 caps->default_dpi.set_height(devmode->dmYResolution);
139 }
140 }
141 }
142 }
143
36 } // namespace 144 } // namespace
37 145
38 namespace printing {
39
40 class PrintBackendWin : public PrintBackend { 146 class PrintBackendWin : public PrintBackend {
41 public: 147 public:
42 PrintBackendWin() {} 148 PrintBackendWin() {}
43 149
44 // PrintBackend implementation. 150 // PrintBackend implementation.
45 virtual bool EnumeratePrinters(PrinterList* printer_list) OVERRIDE; 151 virtual bool EnumeratePrinters(PrinterList* printer_list) OVERRIDE;
46 virtual std::string GetDefaultPrinterName() OVERRIDE; 152 virtual std::string GetDefaultPrinterName() OVERRIDE;
47 virtual bool GetPrinterSemanticCapsAndDefaults( 153 virtual bool GetPrinterSemanticCapsAndDefaults(
48 const std::string& printer_name, 154 const std::string& printer_name,
49 PrinterSemanticCapsAndDefaults* printer_info) OVERRIDE; 155 PrinterSemanticCapsAndDefaults* printer_info) OVERRIDE;
(...skipping 51 matching lines...) Expand 10 before | Expand all | Expand 10 after
101 bool PrintBackendWin::GetPrinterSemanticCapsAndDefaults( 207 bool PrintBackendWin::GetPrinterSemanticCapsAndDefaults(
102 const std::string& printer_name, 208 const std::string& printer_name,
103 PrinterSemanticCapsAndDefaults* printer_info) { 209 PrinterSemanticCapsAndDefaults* printer_info) {
104 ScopedPrinterHandle printer_handle; 210 ScopedPrinterHandle printer_handle;
105 if (!printer_handle.OpenPrinter(base::UTF8ToWide(printer_name).c_str())) { 211 if (!printer_handle.OpenPrinter(base::UTF8ToWide(printer_name).c_str())) {
106 LOG(WARNING) << "Failed to open printer, error = " << GetLastError(); 212 LOG(WARNING) << "Failed to open printer, error = " << GetLastError();
107 return false; 213 return false;
108 } 214 }
109 215
110 PrinterInfo5 info_5; 216 PrinterInfo5 info_5;
111 if (!info_5.Init(printer_handle)) { 217 if (!info_5.Init(printer_handle))
112 return false; 218 return false;
113 } 219 const wchar_t* name = info_5.get()->pPrinterName;
114 DCHECK_EQ(info_5.get()->pPrinterName, base::UTF8ToUTF16(printer_name)); 220 const wchar_t* port = info_5.get()->pPortName;
221 DCHECK_EQ(name, base::UTF8ToUTF16(printer_name));
115 222
116 PrinterSemanticCapsAndDefaults caps; 223 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; 224 UserDefaultDevMode user_settings;
133
134 if (user_settings.Init(printer_handle)) { 225 if (user_settings.Init(printer_handle)) {
135 if ((user_settings.get()->dmFields & DM_COLOR) == DM_COLOR) 226 if ((user_settings.get()->dmFields & DM_COLOR) == DM_COLOR)
136 caps.color_default = (user_settings.get()->dmColor == DMCOLOR_COLOR); 227 caps.color_default = (user_settings.get()->dmColor == DMCOLOR_COLOR);
137 228
138 if ((user_settings.get()->dmFields & DM_DUPLEX) == DM_DUPLEX) { 229 if ((user_settings.get()->dmFields & DM_DUPLEX) == DM_DUPLEX) {
139 switch (user_settings.get()->dmDuplex) { 230 switch (user_settings.get()->dmDuplex) {
140 case DMDUP_SIMPLEX: 231 case DMDUP_SIMPLEX:
141 caps.duplex_default = SIMPLEX; 232 caps.duplex_default = SIMPLEX;
142 break; 233 break;
143 case DMDUP_VERTICAL: 234 case DMDUP_VERTICAL:
144 caps.duplex_default = LONG_EDGE; 235 caps.duplex_default = LONG_EDGE;
145 break; 236 break;
146 case DMDUP_HORIZONTAL: 237 case DMDUP_HORIZONTAL:
147 caps.duplex_default = SHORT_EDGE; 238 caps.duplex_default = SHORT_EDGE;
148 break; 239 break;
149 default: 240 default:
150 NOTREACHED(); 241 NOTREACHED();
151 } 242 }
152 } 243 }
244
245 if ((user_settings.get()->dmFields & DM_COLLATE) == DM_COLLATE)
246 caps.collate_default = (user_settings.get()->dmCollate == DMCOLLATE_TRUE);
153 } else { 247 } else {
154 LOG(WARNING) << "Fallback to color/simplex mode."; 248 LOG(WARNING) << "Fallback to color/simplex mode.";
155 caps.color_default = caps.color_changeable; 249 caps.color_default = caps.color_changeable;
156 caps.duplex_default = SIMPLEX; 250 caps.duplex_default = SIMPLEX;
157 } 251 }
158 252
253 // Get printer capabilities. For more info see here:
254 // http://msdn.microsoft.com/en-us/library/windows/desktop/dd183552(v=vs.85).a spx
255 caps.color_changeable =
256 (DeviceCapabilities(name, port, DC_COLORDEVICE, NULL, NULL) == 1);
257
258 caps.duplex_capable =
259 (DeviceCapabilities(name, port, DC_DUPLEX, NULL, NULL) == 1);
260
261 caps.collate_capable =
262 (DeviceCapabilities(name, port, DC_COLLATE, NULL, NULL) == 1);
263
264 caps.copies_capable =
265 (DeviceCapabilities(name, port, DC_COPIES, NULL, NULL) > 1);
266
267 LoadPaper(name, port, user_settings.get(), &caps);
268 LoadDpi(name, port, user_settings.get(), &caps);
269
159 *printer_info = caps; 270 *printer_info = caps;
160 return true; 271 return true;
161 } 272 }
162 273
163 bool PrintBackendWin::GetPrinterCapsAndDefaults( 274 bool PrintBackendWin::GetPrinterCapsAndDefaults(
164 const std::string& printer_name, 275 const std::string& printer_name,
165 PrinterCapsAndDefaults* printer_info) { 276 PrinterCapsAndDefaults* printer_info) {
166 ScopedXPSInitializer xps_initializer; 277 ScopedXPSInitializer xps_initializer;
167 if (!xps_initializer.initialized()) { 278 if (!xps_initializer.initialized()) {
168 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) 279 // 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; 357 ScopedPrinterHandle printer_handle;
247 return printer_handle.OpenPrinter(base::UTF8ToWide(printer_name).c_str()); 358 return printer_handle.OpenPrinter(base::UTF8ToWide(printer_name).c_str());
248 } 359 }
249 360
250 scoped_refptr<PrintBackend> PrintBackend::CreateInstance( 361 scoped_refptr<PrintBackend> PrintBackend::CreateInstance(
251 const base::DictionaryValue* print_backend_settings) { 362 const base::DictionaryValue* print_backend_settings) {
252 return new PrintBackendWin; 363 return new PrintBackendWin;
253 } 364 }
254 365
255 } // namespace printing 366 } // 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