OLD | NEW |
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 "build/build_config.h" | 7 #include "build/build_config.h" |
8 | 8 |
9 #include <dlfcn.h> | 9 #include <dlfcn.h> |
10 #include <errno.h> | 10 #include <errno.h> |
(...skipping 75 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
86 LOG(ERROR) << "Cannot find libgnutls"; | 86 LOG(ERROR) << "Cannot find libgnutls"; |
87 } | 87 } |
88 }; | 88 }; |
89 | 89 |
90 base::LazyInstance<GcryptInitializer> g_gcrypt_initializer = | 90 base::LazyInstance<GcryptInitializer> g_gcrypt_initializer = |
91 LAZY_INSTANCE_INITIALIZER; | 91 LAZY_INSTANCE_INITIALIZER; |
92 | 92 |
93 } // namespace | 93 } // namespace |
94 #endif // !defined(OS_MACOSX) | 94 #endif // !defined(OS_MACOSX) |
95 | 95 |
| 96 namespace { |
| 97 |
| 98 // This section contains helper code for PPD parsing for semantic capabilities. |
| 99 |
| 100 const char kColorDevice[] = "ColorDevice"; |
| 101 const char kColorModel[] = "ColorModel"; |
| 102 const char kColorMode[] = "ColorMode"; |
| 103 const char kProcessColorModel[] = "ProcessColorModel"; |
| 104 const char kPrintoutMode[] = "PrintoutMode"; |
| 105 const char kDraftGray[] = "Draft.Gray"; |
| 106 const char kHighGray[] = "High.Gray"; |
| 107 |
| 108 const char kDuplex[] = "Duplex"; |
| 109 const char kDuplexNone[] = "None"; |
| 110 |
| 111 bool getBasicColorModelSettings( |
| 112 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
| 113 bool* color_is_default) { |
| 114 ppd_option_t* color_model = ppdFindOption(ppd, kColorModel); |
| 115 if (!color_model) |
| 116 return false; |
| 117 |
| 118 if (ppdFindChoice(color_model, printing::kBlack)) |
| 119 *color_model_for_black = printing::BLACK; |
| 120 else if (ppdFindChoice(color_model, printing::kGray)) |
| 121 *color_model_for_black = printing::GRAY; |
| 122 else if (ppdFindChoice(color_model, printing::kGrayscale)) |
| 123 *color_model_for_black = printing::GRAYSCALE; |
| 124 |
| 125 if (ppdFindChoice(color_model, printing::kColor)) |
| 126 *color_model_for_color = printing::COLOR; |
| 127 else if (ppdFindChoice(color_model, printing::kCMYK)) |
| 128 *color_model_for_color = printing::CMYK; |
| 129 else if (ppdFindChoice(color_model, printing::kRGB)) |
| 130 *color_model_for_color = printing::RGB; |
| 131 else if (ppdFindChoice(color_model, printing::kRGBA)) |
| 132 *color_model_for_color = printing::RGBA; |
| 133 else if (ppdFindChoice(color_model, printing::kRGB16)) |
| 134 *color_model_for_color = printing::RGB16; |
| 135 else if (ppdFindChoice(color_model, printing::kCMY)) |
| 136 *color_model_for_color = printing::CMY; |
| 137 else if (ppdFindChoice(color_model, printing::kKCMY)) |
| 138 *color_model_for_color = printing::KCMY; |
| 139 else if (ppdFindChoice(color_model, printing::kCMY_K)) |
| 140 *color_model_for_color = printing::CMY_K; |
| 141 |
| 142 ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorModel); |
| 143 if (!marked_choice) |
| 144 marked_choice = ppdFindChoice(color_model, color_model->defchoice); |
| 145 |
| 146 if (marked_choice) { |
| 147 *color_is_default = |
| 148 (base::strcasecmp(marked_choice->choice, printing::kBlack) != 0) && |
| 149 (base::strcasecmp(marked_choice->choice, printing::kGray) != 0); |
| 150 } |
| 151 return true; |
| 152 } |
| 153 |
| 154 bool getPrintOutModeColorSettings( |
| 155 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
| 156 bool* color_is_default) { |
| 157 ppd_option_t* printout_mode = ppdFindOption(ppd, kPrintoutMode); |
| 158 if (!printout_mode) |
| 159 return false; |
| 160 |
| 161 *color_model_for_color = printing::PRINTOUTMODE_NORMAL; |
| 162 *color_model_for_black = printing::PRINTOUTMODE_NORMAL; |
| 163 |
| 164 // Check to see if NORMAL_GRAY value is supported by PrintoutMode. |
| 165 // If NORMAL_GRAY is not supported, NORMAL value is used to |
| 166 // represent grayscale. If NORMAL_GRAY is supported, NORMAL is used to |
| 167 // represent color. |
| 168 if (ppdFindChoice(printout_mode, printing::kNormalGray)) |
| 169 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; |
| 170 |
| 171 // Get the default marked choice to identify the default color setting |
| 172 // value. |
| 173 ppd_choice_t* printout_mode_choice = ppdFindMarkedChoice(ppd, kPrintoutMode); |
| 174 if (!printout_mode_choice) { |
| 175 printout_mode_choice = ppdFindChoice(printout_mode, |
| 176 printout_mode->defchoice); |
| 177 } |
| 178 if (printout_mode_choice) { |
| 179 if ((base::strcasecmp(printout_mode_choice->choice, |
| 180 printing::kNormalGray) == 0) || |
| 181 (base::strcasecmp(printout_mode_choice->choice, kHighGray) == 0) || |
| 182 (base::strcasecmp(printout_mode_choice->choice, kDraftGray) == 0)) { |
| 183 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; |
| 184 *color_is_default = false; |
| 185 } |
| 186 } |
| 187 return true; |
| 188 } |
| 189 |
| 190 bool getColorModeSettings( |
| 191 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
| 192 bool* color_is_default) { |
| 193 // Samsung printers use "ColorMode" attribute in their ppds. |
| 194 ppd_option_t* color_mode_option = ppdFindOption(ppd, kColorMode); |
| 195 if (!color_mode_option) |
| 196 return false; |
| 197 |
| 198 if (ppdFindChoice(color_mode_option, printing::kColor)) |
| 199 *color_model_for_color = printing::COLORMODE_COLOR; |
| 200 |
| 201 if (ppdFindChoice(color_mode_option, printing::kMonochrome)) |
| 202 *color_model_for_black = printing::COLORMODE_MONOCHROME; |
| 203 |
| 204 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); |
| 205 if (!mode_choice) { |
| 206 mode_choice = ppdFindChoice(color_mode_option, |
| 207 color_mode_option->defchoice); |
| 208 } |
| 209 |
| 210 if (mode_choice) { |
| 211 *color_is_default = |
| 212 (base::strcasecmp(mode_choice->choice, printing::kColor) == 0); |
| 213 } |
| 214 return true; |
| 215 } |
| 216 |
| 217 bool getHPColorSettings( |
| 218 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
| 219 bool* color_is_default) { |
| 220 // HP printers use "Color/Color Model" attribute in their ppds. |
| 221 ppd_option_t* color_mode_option = ppdFindOption(ppd, printing::kColor); |
| 222 if (!color_mode_option) |
| 223 return false; |
| 224 |
| 225 if (ppdFindChoice(color_mode_option, printing::kColor)) |
| 226 *color_model_for_color = printing::HP_COLOR_COLOR; |
| 227 if (ppdFindChoice(color_mode_option, printing::kBlack)) |
| 228 *color_model_for_black = printing::HP_COLOR_BLACK; |
| 229 |
| 230 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); |
| 231 if (!mode_choice) { |
| 232 mode_choice = ppdFindChoice(color_mode_option, |
| 233 color_mode_option->defchoice); |
| 234 } |
| 235 if (mode_choice) { |
| 236 *color_is_default = |
| 237 (base::strcasecmp(mode_choice->choice, printing::kColor) == 0); |
| 238 } |
| 239 return true; |
| 240 } |
| 241 |
| 242 bool getProcessColorModelSettings( |
| 243 ppd_file_t* ppd, int* color_model_for_black, int* color_model_for_color, |
| 244 bool* color_is_default) { |
| 245 // Canon printers use "ProcessColorModel" attribute in their ppds. |
| 246 ppd_option_t* color_mode_option = ppdFindOption(ppd, kProcessColorModel); |
| 247 if (!color_mode_option) |
| 248 return false; |
| 249 |
| 250 if (ppdFindChoice(color_mode_option, printing::kRGB)) |
| 251 *color_model_for_color = printing::PROCESSCOLORMODEL_RGB; |
| 252 else if (ppdFindChoice(color_mode_option, printing::kCMYK)) |
| 253 *color_model_for_color = printing::PROCESSCOLORMODEL_CMYK; |
| 254 |
| 255 if (ppdFindChoice(color_mode_option, printing::kGreyscale)) |
| 256 *color_model_for_black = printing::PROCESSCOLORMODEL_GREYSCALE; |
| 257 |
| 258 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kProcessColorModel); |
| 259 if (!mode_choice) { |
| 260 mode_choice = ppdFindChoice(color_mode_option, |
| 261 color_mode_option->defchoice); |
| 262 } |
| 263 |
| 264 if (mode_choice) { |
| 265 *color_is_default = |
| 266 (base::strcasecmp(mode_choice->choice, printing::kGreyscale) != 0); |
| 267 } |
| 268 return true; |
| 269 } |
| 270 |
| 271 bool getColorModelSettings( |
| 272 ppd_file_t* ppd, int* cm_black, int* cm_color, bool* is_color) { |
| 273 bool is_color_device = false; |
| 274 ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, NULL); |
| 275 if (attr && attr->value) |
| 276 is_color_device = ppd->color_device; |
| 277 |
| 278 *is_color = is_color_device; |
| 279 if (!((is_color_device && |
| 280 getBasicColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) || |
| 281 getPrintOutModeColorSettings(ppd, &cm_black, &cm_color, &is_color) || |
| 282 getColorModeSettings(ppd, &cm_black, &cm_color, &is_color) || |
| 283 getHPColorSettings(ppd, &cm_black, &cm_color, &is_color) || |
| 284 getProcessColorModelSettings(ppd, &cm_black, &cm_color, &is_color))) { |
| 285 return false; |
| 286 } |
| 287 return true; |
| 288 } |
| 289 |
| 290 bool parsePpdPrinterCapabilities( |
| 291 const std::string& printer_capabilities, |
| 292 printing_internal::PrinterSemanticCapsAndDefaults* printer_info) { |
| 293 FilePath ppd_file_path; |
| 294 if (!file_util::CreateTemporaryFile(&ppd_file_path)) |
| 295 return false; |
| 296 |
| 297 int data_size = printer_capabilities.length(); |
| 298 if (data_size != file_util::WriteFile( |
| 299 ppd_file_path, |
| 300 printer_capabilities.data(), |
| 301 data_size)) { |
| 302 file_util::Delete(ppd_file_path, false); |
| 303 return false; |
| 304 } |
| 305 |
| 306 ppd_file_t* ppd = ppdOpenFile(ppd_file_path.value().c_str()); |
| 307 if (!ppd) |
| 308 return false; |
| 309 |
| 310 PrinterSemanticCapsAndDefaults caps; |
| 311 #if !defined(OS_MACOSX) |
| 312 printing_internal::mark_lpoptions(printer_name, &ppd); |
| 313 #endif |
| 314 ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex); |
| 315 if (!duplex_choice) { |
| 316 ppd_option_t* option = ppdFindOption(ppd, kDuplex); |
| 317 if (option) |
| 318 duplex_choice = ppdFindChoice(option, option->defchoice); |
| 319 } |
| 320 |
| 321 if (duplex_choice) { |
| 322 caps.duplex_capable = true; |
| 323 if (base::strcasecmp(duplex_choice->choice, kDuplexNone) != 0) |
| 324 caps.duplex_default = printing::LONG_EDGE; |
| 325 else |
| 326 caps.duplex_default = printing::SIMPLEX; |
| 327 } |
| 328 |
| 329 bool is_color = false; |
| 330 int cm_color = 0, cm_black = 0; |
| 331 if (!getColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) { |
| 332 VLOG(1) << "Unknown printer color model"; |
| 333 } |
| 334 |
| 335 caps.color_capable = (cm_color && cm_black && (cm_color != cm_black)); |
| 336 caps.color_default = is_color; |
| 337 |
| 338 ppdClose(ppd); |
| 339 file_util::Delete(ppd_file_path, false); |
| 340 |
| 341 *printer_info = caps; |
| 342 return true; |
| 343 } |
| 344 } // namespace |
| 345 |
96 namespace printing { | 346 namespace printing { |
97 | 347 |
98 static const char kCUPSPrinterInfoOpt[] = "printer-info"; | 348 static const char kCUPSPrinterInfoOpt[] = "printer-info"; |
99 static const char kCUPSPrinterStateOpt[] = "printer-state"; | 349 static const char kCUPSPrinterStateOpt[] = "printer-state"; |
100 static const char kCUPSPrinterTypeOpt[] = "printer-type"; | 350 static const char kCUPSPrinterTypeOpt[] = "printer-type"; |
101 static const char kCUPSPrinterMakeModelOpt[] = "printer-make-and-model"; | 351 static const char kCUPSPrinterMakeModelOpt[] = "printer-make-and-model"; |
102 | 352 |
103 class PrintBackendCUPS : public PrintBackend { | 353 class PrintBackendCUPS : public PrintBackend { |
104 public: | 354 public: |
105 PrintBackendCUPS(const GURL& print_server_url, | 355 PrintBackendCUPS(const GURL& print_server_url, |
106 http_encryption_t encryption, bool blocking); | 356 http_encryption_t encryption, bool blocking); |
107 | 357 |
108 // PrintBackend implementation. | 358 // PrintBackend implementation. |
109 virtual bool EnumeratePrinters(PrinterList* printer_list) OVERRIDE; | 359 virtual bool EnumeratePrinters(PrinterList* printer_list) OVERRIDE; |
110 virtual std::string GetDefaultPrinterName() OVERRIDE; | 360 virtual std::string GetDefaultPrinterName() OVERRIDE; |
| 361 virtual bool GetPrinterSemanticCapsAndDefaults( |
| 362 const std::string& printer_name, |
| 363 PrinterSemanticCapsAndDefaults* printer_info) OVERRIDE; |
111 virtual bool GetPrinterCapsAndDefaults( | 364 virtual bool GetPrinterCapsAndDefaults( |
112 const std::string& printer_name, | 365 const std::string& printer_name, |
113 PrinterCapsAndDefaults* printer_info) OVERRIDE; | 366 PrinterCapsAndDefaults* printer_info) OVERRIDE; |
114 virtual std::string GetPrinterDriverInfo( | 367 virtual std::string GetPrinterDriverInfo( |
115 const std::string& printer_name) OVERRIDE; | 368 const std::string& printer_name) OVERRIDE; |
116 virtual bool IsValidPrinter(const std::string& printer_name) OVERRIDE; | 369 virtual bool IsValidPrinter(const std::string& printer_name) OVERRIDE; |
117 | 370 |
118 protected: | 371 protected: |
119 virtual ~PrintBackendCUPS() {} | 372 virtual ~PrintBackendCUPS() {} |
120 | 373 |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
203 } | 456 } |
204 | 457 |
205 std::string PrintBackendCUPS::GetDefaultPrinterName() { | 458 std::string PrintBackendCUPS::GetDefaultPrinterName() { |
206 // Not using cupsGetDefault() because it lies about the default printer. | 459 // Not using cupsGetDefault() because it lies about the default printer. |
207 cups_dest_t* dests; | 460 cups_dest_t* dests; |
208 int num_dests = GetDests(&dests); | 461 int num_dests = GetDests(&dests); |
209 cups_dest_t* dest = cupsGetDest(NULL, NULL, num_dests, dests); | 462 cups_dest_t* dest = cupsGetDest(NULL, NULL, num_dests, dests); |
210 return dest ? std::string(dest->name) : std::string(); | 463 return dest ? std::string(dest->name) : std::string(); |
211 } | 464 } |
212 | 465 |
| 466 bool PrintBackendCUPS::GetPrinterSemanticCapsAndDefaults( |
| 467 const std::string& printer_name, |
| 468 PrinterSemanticCapsAndDefaults* printer_info) { |
| 469 PrinterCapsAndDefaults info; |
| 470 if (!GetPrinterCapsAndDefaults(printer_name, &info) ) |
| 471 return false; |
| 472 |
| 473 return parsePpdPrinterCapabilities(info.printer_capabilities, printer_info); |
| 474 } |
| 475 |
213 bool PrintBackendCUPS::GetPrinterCapsAndDefaults( | 476 bool PrintBackendCUPS::GetPrinterCapsAndDefaults( |
214 const std::string& printer_name, | 477 const std::string& printer_name, |
215 PrinterCapsAndDefaults* printer_info) { | 478 PrinterCapsAndDefaults* printer_info) { |
216 DCHECK(printer_info); | 479 DCHECK(printer_info); |
217 | 480 |
218 VLOG(1) << "CUPS: Getting caps and defaults" | 481 VLOG(1) << "CUPS: Getting caps and defaults" |
219 << ", printer name: " << printer_name; | 482 << ", printer name: " << printer_name; |
220 | 483 |
221 FilePath ppd_path(GetPPD(printer_name.c_str())); | 484 FilePath ppd_path(GetPPD(printer_name.c_str())); |
222 // In some cases CUPS failed to get ppd file. | 485 // In some cases CUPS failed to get ppd file. |
(...skipping 130 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
353 << ", HTTP error: " << http_error; | 616 << ", HTTP error: " << http_error; |
354 file_util::Delete(ppd_path, false); | 617 file_util::Delete(ppd_path, false); |
355 ppd_path.clear(); | 618 ppd_path.clear(); |
356 } | 619 } |
357 } | 620 } |
358 } | 621 } |
359 return ppd_path; | 622 return ppd_path; |
360 } | 623 } |
361 | 624 |
362 } // namespace printing | 625 } // namespace printing |
OLD | NEW |