| 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/cups_helper.h" | 5 #include "printing/backend/cups_helper.h" |
| 6 | 6 |
| 7 #include <cups/ppd.h> | 7 #include <cups/ppd.h> |
| 8 | 8 |
| 9 #include "base/base_paths.h" | 9 #include "base/base_paths.h" |
| 10 #include "base/files/file_util.h" | 10 #include "base/files/file_util.h" |
| (...skipping 31 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 42 const std::string& printer_name, | 42 const std::string& printer_name, |
| 43 int* num_options, cups_option_t** options) { | 43 int* num_options, cups_option_t** options) { |
| 44 std::string content; | 44 std::string content; |
| 45 if (!base::ReadFileToString(filepath, &content)) | 45 if (!base::ReadFileToString(filepath, &content)) |
| 46 return; | 46 return; |
| 47 | 47 |
| 48 const char kDest[] = "dest"; | 48 const char kDest[] = "dest"; |
| 49 const char kDefault[] = "default"; | 49 const char kDefault[] = "default"; |
| 50 const size_t kDestLen = sizeof(kDest) - 1; | 50 const size_t kDestLen = sizeof(kDest) - 1; |
| 51 const size_t kDefaultLen = sizeof(kDefault) - 1; | 51 const size_t kDefaultLen = sizeof(kDefault) - 1; |
| 52 std::vector<std::string> lines; | |
| 53 base::SplitString(content, '\n', &lines); | |
| 54 | 52 |
| 55 for (size_t i = 0; i < lines.size(); ++i) { | 53 for (base::StringPiece line : |
| 56 std::string line = lines[i]; | 54 base::SplitStringPiece(content, "\n", base::KEEP_WHITESPACE, |
| 57 if (line.empty()) | 55 base::SPLIT_WANT_NONEMPTY)) { |
| 58 continue; | 56 if (base::StartsWith(line, base::StringPiece(kDefault, kDefaultLen), |
| 59 | 57 base::CompareCase::INSENSITIVE_ASCII) && |
| 60 if (base::strncasecmp (line.c_str(), kDefault, kDefaultLen) == 0 && | |
| 61 isspace(line[kDefaultLen])) { | 58 isspace(line[kDefaultLen])) { |
| 62 line = line.substr(kDefaultLen); | 59 line = line.substr(kDefaultLen); |
| 63 } else if (base::strncasecmp (line.c_str(), kDest, kDestLen) == 0 && | 60 } else if (base::StartsWith(line, base::StringPiece(kDest, kDestLen), |
| 61 base::CompareCase::INSENSITIVE_ASCII) && |
| 64 isspace(line[kDestLen])) { | 62 isspace(line[kDestLen])) { |
| 65 line = line.substr(kDestLen); | 63 line = line.substr(kDestLen); |
| 66 } else { | 64 } else { |
| 67 continue; | 65 continue; |
| 68 } | 66 } |
| 69 | 67 |
| 70 base::TrimWhitespaceASCII(line, base::TRIM_ALL, &line); | 68 line = base::TrimWhitespaceASCII(line, base::TRIM_ALL); |
| 71 if (line.empty()) | 69 if (line.empty()) |
| 72 continue; | 70 continue; |
| 73 | 71 |
| 74 size_t space_found = line.find(' '); | 72 size_t space_found = line.find(' '); |
| 75 if (space_found == std::string::npos) | 73 if (space_found == base::StringPiece::npos) |
| 76 continue; | 74 continue; |
| 77 | 75 |
| 78 std::string name = line.substr(0, space_found); | 76 base::StringPiece name = line.substr(0, space_found); |
| 79 if (name.empty()) | 77 if (name.empty()) |
| 80 continue; | 78 continue; |
| 81 | 79 |
| 82 if (base::strncasecmp(printer_name.c_str(), name.c_str(), | 80 if (!base::EqualsCaseInsensitiveASCII(printer_name, name)) |
| 83 name.length()) != 0) { | |
| 84 continue; // This is not the required printer. | 81 continue; // This is not the required printer. |
| 85 } | |
| 86 | 82 |
| 87 line = line.substr(space_found + 1); | 83 line = line.substr(space_found + 1); |
| 88 // Remove extra spaces. | 84 // Remove extra spaces. |
| 89 base::TrimWhitespaceASCII(line, base::TRIM_ALL, &line); | 85 line = base::TrimWhitespaceASCII(line, base::TRIM_ALL); |
| 90 if (line.empty()) | 86 if (line.empty()) |
| 91 continue; | 87 continue; |
| 92 // Parse the selected printer custom options. | 88 // Parse the selected printer custom options. Need to pass a |
| 93 *num_options = cupsParseOptions(line.c_str(), 0, options); | 89 // null-terminated string. |
| 90 *num_options = cupsParseOptions(line.as_string().c_str(), 0, options); |
| 94 } | 91 } |
| 95 } | 92 } |
| 96 | 93 |
| 97 void MarkLpOptions(const std::string& printer_name, ppd_file_t** ppd) { | 94 void MarkLpOptions(const std::string& printer_name, ppd_file_t** ppd) { |
| 98 cups_option_t* options = NULL; | 95 cups_option_t* options = NULL; |
| 99 int num_options = 0; | 96 int num_options = 0; |
| 100 | 97 |
| 101 const char kSystemLpOptionPath[] = "/etc/cups/lpoptions"; | 98 const char kSystemLpOptionPath[] = "/etc/cups/lpoptions"; |
| 102 const char kUserLpOptionPath[] = ".cups/lpoptions"; | 99 const char kUserLpOptionPath[] = ".cups/lpoptions"; |
| 103 | 100 |
| (...skipping 46 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 150 *color_model_for_color = printing::KCMY; | 147 *color_model_for_color = printing::KCMY; |
| 151 else if (ppdFindChoice(color_model, printing::kCMY_K)) | 148 else if (ppdFindChoice(color_model, printing::kCMY_K)) |
| 152 *color_model_for_color = printing::CMY_K; | 149 *color_model_for_color = printing::CMY_K; |
| 153 | 150 |
| 154 ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorModel); | 151 ppd_choice_t* marked_choice = ppdFindMarkedChoice(ppd, kColorModel); |
| 155 if (!marked_choice) | 152 if (!marked_choice) |
| 156 marked_choice = ppdFindChoice(color_model, color_model->defchoice); | 153 marked_choice = ppdFindChoice(color_model, color_model->defchoice); |
| 157 | 154 |
| 158 if (marked_choice) { | 155 if (marked_choice) { |
| 159 *color_is_default = | 156 *color_is_default = |
| 160 (base::strcasecmp(marked_choice->choice, printing::kBlack) != 0) && | 157 !base::EqualsCaseInsensitiveASCII(marked_choice->choice, |
| 161 (base::strcasecmp(marked_choice->choice, printing::kGray) != 0) && | 158 printing::kBlack) && |
| 162 (base::strcasecmp(marked_choice->choice, printing::kGrayscale) != 0); | 159 !base::EqualsCaseInsensitiveASCII(marked_choice->choice, |
| 160 printing::kGray) && |
| 161 !base::EqualsCaseInsensitiveASCII(marked_choice->choice, |
| 162 printing::kGrayscale); |
| 163 } | 163 } |
| 164 return true; | 164 return true; |
| 165 } | 165 } |
| 166 | 166 |
| 167 bool GetPrintOutModeColorSettings(ppd_file_t* ppd, | 167 bool GetPrintOutModeColorSettings(ppd_file_t* ppd, |
| 168 ColorModel* color_model_for_black, | 168 ColorModel* color_model_for_black, |
| 169 ColorModel* color_model_for_color, | 169 ColorModel* color_model_for_color, |
| 170 bool* color_is_default) { | 170 bool* color_is_default) { |
| 171 ppd_option_t* printout_mode = ppdFindOption(ppd, kPrintoutMode); | 171 ppd_option_t* printout_mode = ppdFindOption(ppd, kPrintoutMode); |
| 172 if (!printout_mode) | 172 if (!printout_mode) |
| (...skipping 10 matching lines...) Expand all Loading... |
| 183 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; | 183 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; |
| 184 | 184 |
| 185 // Get the default marked choice to identify the default color setting | 185 // Get the default marked choice to identify the default color setting |
| 186 // value. | 186 // value. |
| 187 ppd_choice_t* printout_mode_choice = ppdFindMarkedChoice(ppd, kPrintoutMode); | 187 ppd_choice_t* printout_mode_choice = ppdFindMarkedChoice(ppd, kPrintoutMode); |
| 188 if (!printout_mode_choice) { | 188 if (!printout_mode_choice) { |
| 189 printout_mode_choice = ppdFindChoice(printout_mode, | 189 printout_mode_choice = ppdFindChoice(printout_mode, |
| 190 printout_mode->defchoice); | 190 printout_mode->defchoice); |
| 191 } | 191 } |
| 192 if (printout_mode_choice) { | 192 if (printout_mode_choice) { |
| 193 if ((base::strcasecmp(printout_mode_choice->choice, | 193 if (base::EqualsCaseInsensitiveASCII(printout_mode_choice->choice, |
| 194 printing::kNormalGray) == 0) || | 194 printing::kNormalGray) || |
| 195 (base::strcasecmp(printout_mode_choice->choice, kHighGray) == 0) || | 195 base::EqualsCaseInsensitiveASCII(printout_mode_choice->choice, |
| 196 (base::strcasecmp(printout_mode_choice->choice, kDraftGray) == 0)) { | 196 kHighGray) || |
| 197 base::EqualsCaseInsensitiveASCII(printout_mode_choice->choice, |
| 198 kDraftGray)) { |
| 197 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; | 199 *color_model_for_black = printing::PRINTOUTMODE_NORMAL_GRAY; |
| 198 *color_is_default = false; | 200 *color_is_default = false; |
| 199 } | 201 } |
| 200 } | 202 } |
| 201 return true; | 203 return true; |
| 202 } | 204 } |
| 203 | 205 |
| 204 bool GetColorModeSettings(ppd_file_t* ppd, | 206 bool GetColorModeSettings(ppd_file_t* ppd, |
| 205 ColorModel* color_model_for_black, | 207 ColorModel* color_model_for_black, |
| 206 ColorModel* color_model_for_color, | 208 ColorModel* color_model_for_color, |
| 207 bool* color_is_default) { | 209 bool* color_is_default) { |
| 208 // Samsung printers use "ColorMode" attribute in their ppds. | 210 // Samsung printers use "ColorMode" attribute in their ppds. |
| 209 ppd_option_t* color_mode_option = ppdFindOption(ppd, kColorMode); | 211 ppd_option_t* color_mode_option = ppdFindOption(ppd, kColorMode); |
| 210 if (!color_mode_option) | 212 if (!color_mode_option) |
| 211 return false; | 213 return false; |
| 212 | 214 |
| 213 if (ppdFindChoice(color_mode_option, printing::kColor)) | 215 if (ppdFindChoice(color_mode_option, printing::kColor)) |
| 214 *color_model_for_color = printing::COLORMODE_COLOR; | 216 *color_model_for_color = printing::COLORMODE_COLOR; |
| 215 | 217 |
| 216 if (ppdFindChoice(color_mode_option, printing::kMonochrome)) | 218 if (ppdFindChoice(color_mode_option, printing::kMonochrome)) |
| 217 *color_model_for_black = printing::COLORMODE_MONOCHROME; | 219 *color_model_for_black = printing::COLORMODE_MONOCHROME; |
| 218 | 220 |
| 219 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); | 221 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); |
| 220 if (!mode_choice) { | 222 if (!mode_choice) { |
| 221 mode_choice = ppdFindChoice(color_mode_option, | 223 mode_choice = ppdFindChoice(color_mode_option, |
| 222 color_mode_option->defchoice); | 224 color_mode_option->defchoice); |
| 223 } | 225 } |
| 224 | 226 |
| 225 if (mode_choice) { | 227 if (mode_choice) { |
| 226 *color_is_default = | 228 *color_is_default = base::EqualsCaseInsensitiveASCII( |
| 227 (base::strcasecmp(mode_choice->choice, printing::kColor) == 0); | 229 mode_choice->choice, printing::kColor); |
| 228 } | 230 } |
| 229 return true; | 231 return true; |
| 230 } | 232 } |
| 231 | 233 |
| 232 bool GetHPColorSettings(ppd_file_t* ppd, | 234 bool GetHPColorSettings(ppd_file_t* ppd, |
| 233 ColorModel* color_model_for_black, | 235 ColorModel* color_model_for_black, |
| 234 ColorModel* color_model_for_color, | 236 ColorModel* color_model_for_color, |
| 235 bool* color_is_default) { | 237 bool* color_is_default) { |
| 236 // HP printers use "Color/Color Model" attribute in their ppds. | 238 // HP printers use "Color/Color Model" attribute in their ppds. |
| 237 ppd_option_t* color_mode_option = ppdFindOption(ppd, printing::kColor); | 239 ppd_option_t* color_mode_option = ppdFindOption(ppd, printing::kColor); |
| 238 if (!color_mode_option) | 240 if (!color_mode_option) |
| 239 return false; | 241 return false; |
| 240 | 242 |
| 241 if (ppdFindChoice(color_mode_option, printing::kColor)) | 243 if (ppdFindChoice(color_mode_option, printing::kColor)) |
| 242 *color_model_for_color = printing::HP_COLOR_COLOR; | 244 *color_model_for_color = printing::HP_COLOR_COLOR; |
| 243 if (ppdFindChoice(color_mode_option, printing::kBlack)) | 245 if (ppdFindChoice(color_mode_option, printing::kBlack)) |
| 244 *color_model_for_black = printing::HP_COLOR_BLACK; | 246 *color_model_for_black = printing::HP_COLOR_BLACK; |
| 245 | 247 |
| 246 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); | 248 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kColorMode); |
| 247 if (!mode_choice) { | 249 if (!mode_choice) { |
| 248 mode_choice = ppdFindChoice(color_mode_option, | 250 mode_choice = ppdFindChoice(color_mode_option, |
| 249 color_mode_option->defchoice); | 251 color_mode_option->defchoice); |
| 250 } | 252 } |
| 251 if (mode_choice) { | 253 if (mode_choice) { |
| 252 *color_is_default = | 254 *color_is_default = base::EqualsCaseInsensitiveASCII( |
| 253 (base::strcasecmp(mode_choice->choice, printing::kColor) == 0); | 255 mode_choice->choice, printing::kColor); |
| 254 } | 256 } |
| 255 return true; | 257 return true; |
| 256 } | 258 } |
| 257 | 259 |
| 258 bool GetProcessColorModelSettings(ppd_file_t* ppd, | 260 bool GetProcessColorModelSettings(ppd_file_t* ppd, |
| 259 ColorModel* color_model_for_black, | 261 ColorModel* color_model_for_black, |
| 260 ColorModel* color_model_for_color, | 262 ColorModel* color_model_for_color, |
| 261 bool* color_is_default) { | 263 bool* color_is_default) { |
| 262 // Canon printers use "ProcessColorModel" attribute in their ppds. | 264 // Canon printers use "ProcessColorModel" attribute in their ppds. |
| 263 ppd_option_t* color_mode_option = ppdFindOption(ppd, kProcessColorModel); | 265 ppd_option_t* color_mode_option = ppdFindOption(ppd, kProcessColorModel); |
| 264 if (!color_mode_option) | 266 if (!color_mode_option) |
| 265 return false; | 267 return false; |
| 266 | 268 |
| 267 if (ppdFindChoice(color_mode_option, printing::kRGB)) | 269 if (ppdFindChoice(color_mode_option, printing::kRGB)) |
| 268 *color_model_for_color = printing::PROCESSCOLORMODEL_RGB; | 270 *color_model_for_color = printing::PROCESSCOLORMODEL_RGB; |
| 269 else if (ppdFindChoice(color_mode_option, printing::kCMYK)) | 271 else if (ppdFindChoice(color_mode_option, printing::kCMYK)) |
| 270 *color_model_for_color = printing::PROCESSCOLORMODEL_CMYK; | 272 *color_model_for_color = printing::PROCESSCOLORMODEL_CMYK; |
| 271 | 273 |
| 272 if (ppdFindChoice(color_mode_option, printing::kGreyscale)) | 274 if (ppdFindChoice(color_mode_option, printing::kGreyscale)) |
| 273 *color_model_for_black = printing::PROCESSCOLORMODEL_GREYSCALE; | 275 *color_model_for_black = printing::PROCESSCOLORMODEL_GREYSCALE; |
| 274 | 276 |
| 275 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kProcessColorModel); | 277 ppd_choice_t* mode_choice = ppdFindMarkedChoice(ppd, kProcessColorModel); |
| 276 if (!mode_choice) { | 278 if (!mode_choice) { |
| 277 mode_choice = ppdFindChoice(color_mode_option, | 279 mode_choice = ppdFindChoice(color_mode_option, |
| 278 color_mode_option->defchoice); | 280 color_mode_option->defchoice); |
| 279 } | 281 } |
| 280 | 282 |
| 281 if (mode_choice) { | 283 if (mode_choice) { |
| 282 *color_is_default = | 284 *color_is_default = !base::EqualsCaseInsensitiveASCII( |
| 283 (base::strcasecmp(mode_choice->choice, printing::kGreyscale) != 0); | 285 mode_choice->choice, printing::kGreyscale); |
| 284 } | 286 } |
| 285 return true; | 287 return true; |
| 286 } | 288 } |
| 287 | 289 |
| 288 bool GetColorModelSettings(ppd_file_t* ppd, | 290 bool GetColorModelSettings(ppd_file_t* ppd, |
| 289 ColorModel* cm_black, | 291 ColorModel* cm_black, |
| 290 ColorModel* cm_color, | 292 ColorModel* cm_color, |
| 291 bool* is_color) { | 293 bool* is_color) { |
| 292 bool is_color_device = false; | 294 bool is_color_device = false; |
| 293 ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, NULL); | 295 ppd_attr_t* attr = ppdFindAttr(ppd, kColorDevice, NULL); |
| (...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 376 | 378 |
| 377 ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex); | 379 ppd_choice_t* duplex_choice = ppdFindMarkedChoice(ppd, kDuplex); |
| 378 if (!duplex_choice) { | 380 if (!duplex_choice) { |
| 379 ppd_option_t* option = ppdFindOption(ppd, kDuplex); | 381 ppd_option_t* option = ppdFindOption(ppd, kDuplex); |
| 380 if (option) | 382 if (option) |
| 381 duplex_choice = ppdFindChoice(option, option->defchoice); | 383 duplex_choice = ppdFindChoice(option, option->defchoice); |
| 382 } | 384 } |
| 383 | 385 |
| 384 if (duplex_choice) { | 386 if (duplex_choice) { |
| 385 caps.duplex_capable = true; | 387 caps.duplex_capable = true; |
| 386 if (base::strcasecmp(duplex_choice->choice, kDuplexNone) != 0) | 388 if (!base::EqualsCaseInsensitiveASCII(duplex_choice->choice, kDuplexNone)) |
| 387 caps.duplex_default = printing::LONG_EDGE; | 389 caps.duplex_default = printing::LONG_EDGE; |
| 388 else | 390 else |
| 389 caps.duplex_default = printing::SIMPLEX; | 391 caps.duplex_default = printing::SIMPLEX; |
| 390 } | 392 } |
| 391 | 393 |
| 392 bool is_color = false; | 394 bool is_color = false; |
| 393 ColorModel cm_color = UNKNOWN_COLOR_MODEL, cm_black = UNKNOWN_COLOR_MODEL; | 395 ColorModel cm_color = UNKNOWN_COLOR_MODEL, cm_black = UNKNOWN_COLOR_MODEL; |
| 394 if (!GetColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) { | 396 if (!GetColorModelSettings(ppd, &cm_black, &cm_color, &is_color)) { |
| 395 VLOG(1) << "Unknown printer color model"; | 397 VLOG(1) << "Unknown printer color model"; |
| 396 } | 398 } |
| (...skipping 34 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 431 } | 433 } |
| 432 | 434 |
| 433 ppdClose(ppd); | 435 ppdClose(ppd); |
| 434 base::DeleteFile(ppd_file_path, false); | 436 base::DeleteFile(ppd_file_path, false); |
| 435 | 437 |
| 436 *printer_info = caps; | 438 *printer_info = caps; |
| 437 return true; | 439 return true; |
| 438 } | 440 } |
| 439 | 441 |
| 440 } // namespace printing | 442 } // namespace printing |
| OLD | NEW |