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

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