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

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
« no previous file with comments | « printing/backend/cups_helper.h ('k') | printing/backend/cups_helper_unittest.cc » ('j') | 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/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)
32 void ParseLpOptions(const FilePath& filepath, const std::string& printer_name,
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 const size_t kDestLen = sizeof(kDest) - 1;
41 const size_t kDefaultLen = sizeof(kDefault) - 1;
42 std::vector<std::string> lines;
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 MarkLpOptions(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 ParseLpOptions(*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(ppd_file_t* ppd,
113 int* color_model_for_black,
114 int* color_model_for_color,
115 bool* color_is_default) {
116 ppd_option_t* color_model = ppdFindOption(ppd, kColorModel);
117 if (!color_model)
118 return false;
119
120 if (ppdFindChoice(color_model, printing::kBlack))
121 *color_model_for_black = printing::BLACK;
122 else if (ppdFindChoice(color_model, printing::kGray))
123 *color_model_for_black = printing::GRAY;
124 else if (ppdFindChoice(color_model, printing::kGrayscale))
125 *color_model_for_black = printing::GRAYSCALE;
126
127 if (ppdFindChoice(color_model, printing::kColor))
128 *color_model_for_color = printing::COLOR;
129 else if (ppdFindChoice(color_model, printing::kCMYK))
130 *color_model_for_color = printing::CMYK;
131 else if (ppdFindChoice(color_model, printing::kRGB))
132 *color_model_for_color = printing::RGB;
133 else if (ppdFindChoice(color_model, printing::kRGBA))
134 *color_model_for_color = printing::RGBA;
135 else if (ppdFindChoice(color_model, printing::kRGB16))
136 *color_model_for_color = printing::RGB16;
137 else if (ppdFindChoice(color_model, printing::kCMY))
138 *color_model_for_color = printing::CMY;
139 else if (ppdFindChoice(color_model, printing::kKCMY))
140 *color_model_for_color = printing::KCMY;
141 else if (ppdFindChoice(color_model, printing::kCMY_K))
142 *color_model_for_color = printing::CMY_K;
143
144 ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorModel);
145 if (!marked_choice)
146 marked_choice = ppdFindChoice(color_model, color_model->defchoice);
147
148 if (marked_choice) {
149 *color_is_default =
150 (base::strcasecmp(marked_choice->choice, printing::kBlack) != 0) &&
151 (base::strcasecmp(marked_choice->choice, printing::kGray) != 0);
152 }
153 return true;
154 }
155
156 bool GetPrintOutModeColorSettings(ppd_file_t* ppd,
157 int* color_model_for_black,
158 int* color_model_for_color,
159 bool* color_is_default) {
160 ppd_option_t* printout_mode = ppdFindOption(ppd, kPrintoutMode);
161 if (!printout_mode)
162 return false;
163
164 *color_model_for_color = printing::PRINTOUTMODE_NORMAL;
165 *color_model_for_black = printing::PRINTOUTMODE_NORMAL;
166
167 // Check to see if NORMAL_GRAY value is supported by PrintoutMode.
168 // If NORMAL_GRAY is not supported, NORMAL value is used to
169 // represent grayscale. If NORMAL_GRAY is supported, NORMAL is used to
170 // represent color.
171 if (ppdFindChoice(printout_mode, printing::kNormalGray))
172 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY;
173
174 // Get the default marked choice to identify the default color setting
175 // value.
176 ppd_choice_t* printout_mode_choice = ppdFindMarkedChoice(ppd, kPrintoutMode);
177 if (!printout_mode_choice) {
178 printout_mode_choice = ppdFindChoice(printout_mode,
179 printout_mode->defchoice);
180 }
181 if (printout_mode_choice) {
182 if ((base::strcasecmp(printout_mode_choice->choice,
183 printing::kNormalGray) == 0) ||
184 (base::strcasecmp(printout_mode_choice->choice, kHighGray) == 0) ||
185 (base::strcasecmp(printout_mode_choice->choice, kDraftGray) == 0)) {
186 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY;
187 *color_is_default = false;
188 }
189 }
190 return true;
191 }
192
193 bool GetColorModeSettings(ppd_file_t* ppd,
194 int* color_model_for_black,
195 int* color_model_for_color,
196 bool* color_is_default) {
197 // Samsung printers use "ColorMode" attribute in their ppds.
198 ppd_option_t* color_mode_option = ppdFindOption(ppd, kColorMode);
199 if (!color_mode_option)
200 return false;
201
202 if (ppdFindChoice(color_mode_option, printing::kColor))
203 *color_model_for_color = printing::COLORMODE_COLOR;
204
205 if (ppdFindChoice(color_mode_option, printing::kMonochrome))
206 *color_model_for_black = printing::COLORMODE_MONOCHROME;
207
208 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode);
209 if (!mode_choice) {
210 mode_choice = ppdFindChoice(color_mode_option,
211 color_mode_option->defchoice);
212 }
213
214 if (mode_choice) {
215 *color_is_default =
216 (base::strcasecmp(mode_choice->choice, printing::kColor) == 0);
217 }
218 return true;
219 }
220
221 bool GetHPColorSettings(ppd_file_t* ppd,
222 int* color_model_for_black,
223 int* color_model_for_color,
224 bool* color_is_default) {
225 // HP printers use "Color/Color Model" attribute in their ppds.
226 ppd_option_t* color_mode_option = ppdFindOption(ppd, printing::kColor);
227 if (!color_mode_option)
228 return false;
229
230 if (ppdFindChoice(color_mode_option, printing::kColor))
231 *color_model_for_color = printing::HP_COLOR_COLOR;
232 if (ppdFindChoice(color_mode_option, printing::kBlack))
233 *color_model_for_black = printing::HP_COLOR_BLACK;
234
235 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode);
236 if (!mode_choice) {
237 mode_choice = ppdFindChoice(color_mode_option,
238 color_mode_option->defchoice);
239 }
240 if (mode_choice) {
241 *color_is_default =
242 (base::strcasecmp(mode_choice->choice, printing::kColor) == 0);
243 }
244 return true;
245 }
246
247 bool GetProcessColorModelSettings(ppd_file_t* ppd,
248 int* color_model_for_black,
249 int* color_model_for_color,
250 bool* color_is_default) {
251 // Canon printers use "ProcessColorModel" attribute in their ppds.
252 ppd_option_t* color_mode_option = ppdFindOption(ppd, kProcessColorModel);
253 if (!color_mode_option)
254 return false;
255
256 if (ppdFindChoice(color_mode_option, printing::kRGB))
257 *color_model_for_color = printing::PROCESSCOLORMODEL_RGB;
258 else if (ppdFindChoice(color_mode_option, printing::kCMYK))
259 *color_model_for_color = printing::PROCESSCOLORMODEL_CMYK;
260
261 if (ppdFindChoice(color_mode_option, printing::kGreyscale))
262 *color_model_for_black = printing::PROCESSCOLORMODEL_GREYSCALE;
263
264 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kProcessColorModel);
265 if (!mode_choice) {
266 mode_choice = ppdFindChoice(color_mode_option,
267 color_mode_option->defchoice);
268 }
269
270 if (mode_choice) {
271 *color_is_default =
272 (base::strcasecmp(mode_choice->choice, printing::kGreyscale) != 0);
273 }
274 return true;
275 }
276
277 bool GetColorModelSettings(ppd_file_t* ppd,
278 int* cm_black,
279 int* cm_color,
280 bool* is_color) {
281 bool is_color_device = false;
282 ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, NULL);
283 if (attr && attr->value)
284 is_color_device = ppd->color_device;
285
286 *is_color = is_color_device;
287 return (!((is_color_device &&
Lei Zhang 2012/09/05 21:10:16 I think you need to get rid of the ! if (!(eval_t
gene 2012/09/05 21:15:10 You are absolutely correct. Fixed. Thanks for catc
288 GetBasicColorModelSettings(ppd, cm_black, cm_color, is_color)) ||
289 GetPrintOutModeColorSettings(ppd, cm_black, cm_color, is_color) ||
290 GetColorModeSettings(ppd, cm_black, cm_color, is_color) ||
291 GetHPColorSettings(ppd, cm_black, cm_color, is_color) ||
292 GetProcessColorModelSettings(ppd, cm_black, cm_color, is_color)));
293 }
294
295 } // namespace
9 296
10 namespace printing { 297 namespace printing {
11 298
12 // Default port for IPP print servers. 299 // Default port for IPP print servers.
13 static const int kDefaultIPPServerPort = 631; 300 static const int kDefaultIPPServerPort = 631;
14 301
15 // Helper wrapper around http_t structure, with connection and cleanup 302 // Helper wrapper around http_t structure, with connection and cleanup
16 // functionality. 303 // functionality.
17 HttpConnectionCUPS::HttpConnectionCUPS(const GURL& print_server_url, 304 HttpConnectionCUPS::HttpConnectionCUPS(const GURL& print_server_url,
18 http_encryption_t encryption) 305 http_encryption_t encryption)
(...skipping 20 matching lines...) Expand all
39 } 326 }
40 327
41 void HttpConnectionCUPS::SetBlocking(bool blocking) { 328 void HttpConnectionCUPS::SetBlocking(bool blocking) {
42 httpBlocking(http_, blocking ? 1 : 0); 329 httpBlocking(http_, blocking ? 1 : 0);
43 } 330 }
44 331
45 http_t* HttpConnectionCUPS::http() { 332 http_t* HttpConnectionCUPS::http() {
46 return http_; 333 return http_;
47 } 334 }
48 335
336 bool parsePpdCapabilities(
337 const std::string& printer_name,
338 const std::string& printer_capabilities,
339 PrinterSemanticCapsAndDefaults* printer_info) {
340 FilePath ppd_file_path;
341 if (!file_util::CreateTemporaryFile(&ppd_file_path))
342 return false;
343
344 int data_size = printer_capabilities.length();
345 if (data_size != file_util::WriteFile(
346 ppd_file_path,
347 printer_capabilities.data(),
348 data_size)) {
349 file_util::Delete(ppd_file_path, false);
350 return false;
351 }
352
353 ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str());
354 if (!ppd)
355 return false;
356
357 printing::PrinterSemanticCapsAndDefaults caps;
358 #if !defined(OS_MACOSX)
359 MarkLpOptions(printer_name, &ppd);
360 #endif
361 ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex);
362 if (!duplex_choice) {
363 ppd_option_t* option = ppdFindOption(ppd, kDuplex);
364 if (option)
365 duplex_choice = ppdFindChoice(option, option->defchoice);
366 }
367
368 if (duplex_choice) {
369 caps.duplex_capable = true;
370 if (base::strcasecmp(duplex_choice->choice, kDuplexNone) != 0)
371 caps.duplex_default = printing::LONG_EDGE;
372 else
373 caps.duplex_default = printing::SIMPLEX;
374 }
375
376 bool is_color = false;
377 int cm_color = 0, cm_black = 0;
378 if (!GetColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) {
379 VLOG(1) << "Unknown printer color model";
380 }
381
382 caps.color_capable = (cm_color && cm_black && (cm_color != cm_black));
383 caps.color_default = is_color;
384
385 ppdClose(ppd);
386 file_util::Delete(ppd_file_path, false);
387
388 *printer_info = caps;
389 return true;
390 }
391
49 } // namespace printing 392 } // namespace printing
OLDNEW
« no previous file with comments | « printing/backend/cups_helper.h ('k') | printing/backend/cups_helper_unittest.cc » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698