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

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

Issue 10905006: Get semantic capabilities from Print Backend. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years, 3 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
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/cups_helper.h" 5 #include "printing/backend/cups_helper.h"
6 6
7 #include "base/file_util.h"
7 #include "base/logging.h" 8 #include "base/logging.h"
9 #include "base/string_number_conversions.h"
10 #include "base/string_split.h"
11 #include "base/string_util.h"
12 #include "base/values.h"
8 #include "googleurl/src/gurl.h" 13 #include "googleurl/src/gurl.h"
14 #include "printing/backend/print_backend.h"
15 #include "printing/backend/print_backend_consts.h"
16
17 // This section contains helper code for PPD parsing for semantic capabilities.
18 namespace {
19
20 const char kColorDevice[] = "ColorDevice";
21 const char kColorModel[] = "ColorModel";
22 const char kColorMode[] = "ColorMode";
23 const char kProcessColorModel[] = "ProcessColorModel";
24 const char kPrintoutMode[] = "PrintoutMode";
25 const char kDraftGray[] = "Draft.Gray";
26 const char kHighGray[] = "High.Gray";
27
28 const char kDuplex[] = "Duplex";
29 const char kDuplexNone[] = "None";
30
31 #if !defined(OS_MACOSX)
Albert Bodenhamer 2012/09/04 23:09:36 A large chunk of this file is ifdefed out here. D
gene 2012/09/04 23:19:50 2 functions are ifdef'ed for non-MACOS: parse_lpop
32 void parse_lpoptions(const FilePath& filepath, const std::string& printer_name,
Lei Zhang 2012/09/05 00:32:32 I realized this got copied over, but this should b
gene 2012/09/05 21:04:10 Done.
33 int* num_options, cups_option_t** options) {
34 std::string content;
35 if (!file_util::ReadFileToString(filepath, &content))
36 return;
37
38 const char kDest[] = "dest";
39 const char kDefault[] = "default";
40 size_t kDestLen = sizeof(kDest) - 1;
Lei Zhang 2012/09/05 00:32:32 const here and next line
gene 2012/09/05 21:04:10 Done.
41 size_t kDefaultLen = sizeof(kDefault) - 1;
42 std::vector <std::string> lines;
Lei Zhang 2012/09/05 00:32:32 no space after vector
gene 2012/09/05 21:04:10 Done.
43 base::SplitString(content, '\n', &lines);
44
45 for (size_t i = 0; i < lines.size(); ++i) {
46 std::string line = lines[i];
47 if (line.empty())
48 continue;
49
50 if (base::strncasecmp (line.c_str(), kDefault, kDefaultLen) == 0 &&
51 isspace(line[kDefaultLen])) {
52 line = line.substr(kDefaultLen);
53 } else if (base::strncasecmp (line.c_str(), kDest, kDestLen) == 0 &&
54 isspace(line[kDestLen])) {
55 line = line.substr(kDestLen);
56 } else {
57 continue;
58 }
59
60 TrimWhitespaceASCII(line, TRIM_ALL, &line);
61 if (line.empty())
62 continue;
63
64 size_t space_found = line.find(' ');
65 if (space_found == std::string::npos)
66 continue;
67
68 std::string name = line.substr(0, space_found);
69 if (name.empty())
70 continue;
71
72 if (base::strncasecmp(printer_name.c_str(), name.c_str(),
73 name.length()) != 0) {
74 continue; // This is not the required printer.
75 }
76
77 line = line.substr(space_found + 1);
78 TrimWhitespaceASCII(line, TRIM_ALL, &line); // Remove extra spaces.
79 if (line.empty())
80 continue;
81 // Parse the selected printer custom options.
82 *num_options = cupsParseOptions(line.c_str(), 0, options);
83 }
84 }
85
86 void mark_lpoptions(const std::string& printer_name, ppd_file_t** ppd) {
87 cups_option_t* options = NULL;
88 int num_options = 0;
89 ppdMarkDefaults(*ppd);
90
91 const char kSystemLpOptionPath[] = "/etc/cups/lpoptions";
92 const char kUserLpOptionPath[] = ".cups/lpoptions";
93
94 std::vector<FilePath> file_locations;
95 file_locations.push_back(FilePath(kSystemLpOptionPath));
96 file_locations.push_back(FilePath(
97 file_util::GetHomeDir().Append(kUserLpOptionPath)));
98
99 for (std::vector<FilePath>::const_iterator it = file_locations.begin();
100 it != file_locations.end(); ++it) {
101 num_options = 0;
102 options = NULL;
103 parse_lpoptions(*it, printer_name, &num_options, &options);
104 if (num_options > 0 && options) {
105 cupsMarkOptions(*ppd, num_options, options);
106 cupsFreeOptions(num_options, options);
107 }
108 }
109 }
110 #endif // !defined(OS_MACOSX)
111
112 bool getBasicColorModelSettings(
Lei Zhang 2012/09/05 00:32:32 Ditto, naming and also parameter list formatting.
gene 2012/09/05 21:04:10 Done.
113 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color,
114 bool* color_is_default) {
115 ppd_option_t* color_model = ppdFindOption(ppd, kColorModel);
116 if (!color_model)
117 return false;
118
119 if (ppdFindChoice(color_model, printing::kBlack))
120 *color_model_for_black = printing::BLACK;
121 else if (ppdFindChoice(color_model, printing::kGray))
122 *color_model_for_black = printing::GRAY;
123 else if (ppdFindChoice(color_model, printing::kGrayscale))
124 *color_model_for_black = printing::GRAYSCALE;
125
126 if (ppdFindChoice(color_model, printing::kColor))
127 *color_model_for_color = printing::COLOR;
128 else if (ppdFindChoice(color_model, printing::kCMYK))
129 *color_model_for_color = printing::CMYK;
130 else if (ppdFindChoice(color_model, printing::kRGB))
131 *color_model_for_color = printing::RGB;
132 else if (ppdFindChoice(color_model, printing::kRGBA))
133 *color_model_for_color = printing::RGBA;
134 else if (ppdFindChoice(color_model, printing::kRGB16))
135 *color_model_for_color = printing::RGB16;
136 else if (ppdFindChoice(color_model, printing::kCMY))
137 *color_model_for_color = printing::CMY;
138 else if (ppdFindChoice(color_model, printing::kKCMY))
139 *color_model_for_color = printing::KCMY;
140 else if (ppdFindChoice(color_model, printing::kCMY_K))
141 *color_model_for_color = printing::CMY_K;
142
143 ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorModel);
144 if (!marked_choice)
145 marked_choice = ppdFindChoice(color_model, color_model->defchoice);
146
147 if (marked_choice) {
148 *color_is_default =
149 (base::strcasecmp(marked_choice->choice, printing::kBlack) != 0) &&
150 (base::strcasecmp(marked_choice->choice, printing::kGray) != 0);
151 }
152 return true;
153 }
154
155 bool getPrintOutModeColorSettings(
156 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color,
157 bool* color_is_default) {
158 ppd_option_t* printout_mode = ppdFindOption(ppd, kPrintoutMode);
159 if (!printout_mode)
160 return false;
161
162 *color_model_for_color = printing::PRINTOUTMODE_NORMAL;
163 *color_model_for_black = printing::PRINTOUTMODE_NORMAL;
164
165 // Check to see if NORMAL_GRAY value is supported by PrintoutMode.
166 // If NORMAL_GRAY is not supported, NORMAL value is used to
167 // represent grayscale. If NORMAL_GRAY is supported, NORMAL is used to
168 // represent color.
169 if (ppdFindChoice(printout_mode, printing::kNormalGray))
170 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY;
171
172 // Get the default marked choice to identify the default color setting
173 // value.
174 ppd_choice_t* printout_mode_choice = ppdFindMarkedChoice(ppd, kPrintoutMode);
175 if (!printout_mode_choice) {
176 printout_mode_choice = ppdFindChoice(printout_mode,
177 printout_mode->defchoice);
178 }
179 if (printout_mode_choice) {
180 if ((base::strcasecmp(printout_mode_choice->choice,
181 printing::kNormalGray) == 0) ||
182 (base::strcasecmp(printout_mode_choice->choice, kHighGray) == 0) ||
183 (base::strcasecmp(printout_mode_choice->choice, kDraftGray) == 0)) {
184 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY;
185 *color_is_default = false;
186 }
187 }
188 return true;
189 }
190
191 bool getColorModeSettings(
192 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color,
193 bool* color_is_default) {
194 // Samsung printers use "ColorMode" attribute in their ppds.
195 ppd_option_t* color_mode_option = ppdFindOption(ppd, kColorMode);
196 if (!color_mode_option)
197 return false;
198
199 if (ppdFindChoice(color_mode_option, printing::kColor))
200 *color_model_for_color = printing::COLORMODE_COLOR;
201
202 if (ppdFindChoice(color_mode_option, printing::kMonochrome))
203 *color_model_for_black = printing::COLORMODE_MONOCHROME;
204
205 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode);
206 if (!mode_choice) {
207 mode_choice = ppdFindChoice(color_mode_option,
208 color_mode_option->defchoice);
209 }
210
211 if (mode_choice) {
212 *color_is_default =
213 (base::strcasecmp(mode_choice->choice, printing::kColor) == 0);
214 }
215 return true;
216 }
217
218 bool getHPColorSettings(
219 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color,
220 bool* color_is_default) {
221 // HP printers use "Color/Color Model" attribute in their ppds.
222 ppd_option_t* color_mode_option = ppdFindOption(ppd, printing::kColor);
223 if (!color_mode_option)
224 return false;
225
226 if (ppdFindChoice(color_mode_option, printing::kColor))
227 *color_model_for_color = printing::HP_COLOR_COLOR;
228 if (ppdFindChoice(color_mode_option, printing::kBlack))
229 *color_model_for_black = printing::HP_COLOR_BLACK;
230
231 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode);
232 if (!mode_choice) {
233 mode_choice = ppdFindChoice(color_mode_option,
234 color_mode_option->defchoice);
235 }
236 if (mode_choice) {
237 *color_is_default =
238 (base::strcasecmp(mode_choice->choice, printing::kColor) == 0);
239 }
240 return true;
241 }
242
243 bool getProcessColorModelSettings(
244 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color,
245 bool* color_is_default) {
246 // Canon printers use "ProcessColorModel" attribute in their ppds.
247 ppd_option_t* color_mode_option = ppdFindOption(ppd, kProcessColorModel);
248 if (!color_mode_option)
249 return false;
250
251 if (ppdFindChoice(color_mode_option, printing::kRGB))
252 *color_model_for_color = printing::PROCESSCOLORMODEL_RGB;
253 else if (ppdFindChoice(color_mode_option, printing::kCMYK))
254 *color_model_for_color = printing::PROCESSCOLORMODEL_CMYK;
255
256 if (ppdFindChoice(color_mode_option, printing::kGreyscale))
257 *color_model_for_black = printing::PROCESSCOLORMODEL_GREYSCALE;
258
259 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kProcessColorModel);
260 if (!mode_choice) {
261 mode_choice = ppdFindChoice(color_mode_option,
262 color_mode_option->defchoice);
263 }
264
265 if (mode_choice) {
266 *color_is_default =
267 (base::strcasecmp(mode_choice->choice, printing::kGreyscale) != 0);
268 }
269 return true;
270 }
271
272 bool getColorModelSettings(
273 ppd_file_t* ppd, int* cm_black, int* cm_color, bool* is_color) {
274 bool is_color_device = false;
275 ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, NULL);
276 if (attr && attr->value)
277 is_color_device = ppd->color_device;
278
279 *is_color = is_color_device;
280 if (!((is_color_device &&
Lei Zhang 2012/09/05 00:32:32 Might be slightly better to write this as: return
gene 2012/09/05 21:04:10 Done.
281 getBasicColorModelSettings(ppd, cm_black, cm_color, is_color)) ||
282 getPrintOutModeColorSettings(ppd, cm_black, cm_color, is_color) ||
283 getColorModeSettings(ppd, cm_black, cm_color, is_color) ||
284 getHPColorSettings(ppd, cm_black, cm_color, is_color) ||
285 getProcessColorModelSettings(ppd, cm_black, cm_color, is_color))) {
286 return false;
287 }
288 return true;
289 }
290 } // namespace
Lei Zhang 2012/09/05 00:32:32 add a blank line above this.
gene 2012/09/05 21:04:10 Done.
9 291
10 namespace printing { 292 namespace printing {
11 293
12 // Default port for IPP print servers. 294 // Default port for IPP print servers.
13 static const int kDefaultIPPServerPort = 631; 295 static const int kDefaultIPPServerPort = 631;
14 296
15 // Helper wrapper around http_t structure, with connection and cleanup 297 // Helper wrapper around http_t structure, with connection and cleanup
16 // functionality. 298 // functionality.
17 HttpConnectionCUPS::HttpConnectionCUPS(const GURL& print_server_url, 299 HttpConnectionCUPS::HttpConnectionCUPS(const GURL& print_server_url,
18 http_encryption_t encryption) 300 http_encryption_t encryption)
(...skipping 20 matching lines...) Expand all
39 } 321 }
40 322
41 void HttpConnectionCUPS::SetBlocking(bool blocking) { 323 void HttpConnectionCUPS::SetBlocking(bool blocking) {
42 httpBlocking(http_, blocking ? 1 : 0); 324 httpBlocking(http_, blocking ? 1 : 0);
43 } 325 }
44 326
45 http_t* HttpConnectionCUPS::http() { 327 http_t* HttpConnectionCUPS::http() {
46 return http_; 328 return http_;
47 } 329 }
48 330
331 bool parsePpdCapabilities(
332 const std::string& printer_name,
333 const std::string& printer_capabilities,
334 PrinterSemanticCapsAndDefaults* printer_info) {
335 FilePath ppd_file_path;
336 if (!file_util::CreateTemporaryFile(&ppd_file_path))
337 return false;
338
339 int data_size = printer_capabilities.length();
340 if (data_size != file_util::WriteFile(
341 ppd_file_path,
342 printer_capabilities.data(),
343 data_size)) {
344 file_util::Delete(ppd_file_path, false);
345 return false;
346 }
347
348 ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str());
349 if (!ppd)
350 return false;
351
352 printing::PrinterSemanticCapsAndDefaults caps;
353 #if !defined(OS_MACOSX)
354 mark_lpoptions(printer_name, &ppd);
355 #endif
356 ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex);
357 if (!duplex_choice) {
358 ppd_option_t* option = ppdFindOption(ppd, kDuplex);
359 if (option)
360 duplex_choice = ppdFindChoice(option, option->defchoice);
361 }
362
363 if (duplex_choice) {
364 caps.duplex_capable = true;
365 if (base::strcasecmp(duplex_choice->choice, kDuplexNone) != 0)
366 caps.duplex_default = printing::LONG_EDGE;
367 else
368 caps.duplex_default = printing::SIMPLEX;
369 }
370
371 bool is_color = false;
372 int cm_color = 0, cm_black = 0;
373 if (!getColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) {
374 VLOG(1) << "Unknown printer color model";
375 }
376
377 caps.color_capable = (cm_color && cm_black && (cm_color != cm_black));
378 caps.color_default = is_color;
379
380 ppdClose(ppd);
381 file_util::Delete(ppd_file_path, false);
382
383 *printer_info = caps;
384 return true;
385 }
49 } // namespace printing 386 } // namespace printing
Lei Zhang 2012/09/05 00:32:32 add a blank line above this.
gene 2012/09/05 21:04:10 Done.
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698