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/win_helper.h" | 5 #include "printing/backend/win_helper.h" |
6 | 6 |
7 #include <stddef.h> | 7 #include <stddef.h> |
8 | 8 |
9 #include <algorithm> | 9 #include <algorithm> |
10 | 10 |
(...skipping 377 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
388 return driver_info; | 388 return driver_info; |
389 } | 389 } |
390 | 390 |
391 scoped_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode( | 391 scoped_ptr<DEVMODE, base::FreeDeleter> XpsTicketToDevMode( |
392 const base::string16& printer_name, | 392 const base::string16& printer_name, |
393 const std::string& print_ticket) { | 393 const std::string& print_ticket) { |
394 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode; | 394 scoped_ptr<DEVMODE, base::FreeDeleter> dev_mode; |
395 printing::ScopedXPSInitializer xps_initializer; | 395 printing::ScopedXPSInitializer xps_initializer; |
396 if (!xps_initializer.initialized()) { | 396 if (!xps_initializer.initialized()) { |
397 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) | 397 // TODO(sanjeevr): Handle legacy proxy case (with no prntvpt.dll) |
398 return dev_mode.Pass(); | 398 return dev_mode; |
399 } | 399 } |
400 | 400 |
401 printing::ScopedPrinterHandle printer; | 401 printing::ScopedPrinterHandle printer; |
402 if (!printer.OpenPrinter(printer_name.c_str())) | 402 if (!printer.OpenPrinter(printer_name.c_str())) |
403 return dev_mode.Pass(); | 403 return dev_mode; |
404 | 404 |
405 base::win::ScopedComPtr<IStream> pt_stream; | 405 base::win::ScopedComPtr<IStream> pt_stream; |
406 HRESULT hr = StreamFromPrintTicket(print_ticket, pt_stream.Receive()); | 406 HRESULT hr = StreamFromPrintTicket(print_ticket, pt_stream.Receive()); |
407 if (FAILED(hr)) | 407 if (FAILED(hr)) |
408 return dev_mode.Pass(); | 408 return dev_mode; |
409 | 409 |
410 HPTPROVIDER provider = NULL; | 410 HPTPROVIDER provider = NULL; |
411 hr = printing::XPSModule::OpenProvider(printer_name, 1, &provider); | 411 hr = printing::XPSModule::OpenProvider(printer_name, 1, &provider); |
412 if (SUCCEEDED(hr)) { | 412 if (SUCCEEDED(hr)) { |
413 ULONG size = 0; | 413 ULONG size = 0; |
414 DEVMODE* dm = NULL; | 414 DEVMODE* dm = NULL; |
415 // Use kPTJobScope, because kPTDocumentScope breaks duplex. | 415 // Use kPTJobScope, because kPTDocumentScope breaks duplex. |
416 hr = printing::XPSModule::ConvertPrintTicketToDevMode( | 416 hr = printing::XPSModule::ConvertPrintTicketToDevMode( |
417 provider, pt_stream.get(), kUserDefaultDevmode, kPTJobScope, &size, &dm, | 417 provider, pt_stream.get(), kUserDefaultDevmode, kPTJobScope, &size, &dm, |
418 NULL); | 418 NULL); |
419 if (SUCCEEDED(hr)) { | 419 if (SUCCEEDED(hr)) { |
420 // Correct DEVMODE using DocumentProperties. See documentation for | 420 // Correct DEVMODE using DocumentProperties. See documentation for |
421 // PTConvertPrintTicketToDevMode. | 421 // PTConvertPrintTicketToDevMode. |
422 dev_mode = CreateDevMode(printer.Get(), dm); | 422 dev_mode = CreateDevMode(printer.Get(), dm); |
423 printing::XPSModule::ReleaseMemory(dm); | 423 printing::XPSModule::ReleaseMemory(dm); |
424 } | 424 } |
425 printing::XPSModule::CloseProvider(provider); | 425 printing::XPSModule::CloseProvider(provider); |
426 } | 426 } |
427 return dev_mode.Pass(); | 427 return dev_mode; |
428 } | 428 } |
429 | 429 |
430 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor( | 430 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevModeWithColor( |
431 HANDLE printer, | 431 HANDLE printer, |
432 const base::string16& printer_name, | 432 const base::string16& printer_name, |
433 bool color) { | 433 bool color) { |
434 scoped_ptr<DEVMODE, base::FreeDeleter> default_ticket = | 434 scoped_ptr<DEVMODE, base::FreeDeleter> default_ticket = |
435 CreateDevMode(printer, NULL); | 435 CreateDevMode(printer, NULL); |
436 if (!default_ticket) | 436 if (!default_ticket) |
437 return default_ticket.Pass(); | 437 return default_ticket; |
438 | 438 |
439 if ((default_ticket->dmFields & DM_COLOR) && | 439 if ((default_ticket->dmFields & DM_COLOR) && |
440 ((default_ticket->dmColor == DMCOLOR_COLOR) == color)) { | 440 ((default_ticket->dmColor == DMCOLOR_COLOR) == color)) { |
441 return default_ticket.Pass(); | 441 return default_ticket; |
442 } | 442 } |
443 | 443 |
444 default_ticket->dmFields |= DM_COLOR; | 444 default_ticket->dmFields |= DM_COLOR; |
445 default_ticket->dmColor = color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; | 445 default_ticket->dmColor = color ? DMCOLOR_COLOR : DMCOLOR_MONOCHROME; |
446 | 446 |
447 DriverInfo6 info_6; | 447 DriverInfo6 info_6; |
448 if (!info_6.Init(printer)) | 448 if (!info_6.Init(printer)) |
449 return default_ticket.Pass(); | 449 return default_ticket; |
450 | 450 |
451 const DRIVER_INFO_6* p = info_6.get(); | 451 const DRIVER_INFO_6* p = info_6.get(); |
452 | 452 |
453 // Only HP known to have issues. | 453 // Only HP known to have issues. |
454 if (!p->pszMfgName || wcscmp(p->pszMfgName, L"HP") != 0) | 454 if (!p->pszMfgName || wcscmp(p->pszMfgName, L"HP") != 0) |
455 return default_ticket.Pass(); | 455 return default_ticket; |
456 | 456 |
457 // Need XPS for this workaround. | 457 // Need XPS for this workaround. |
458 printing::ScopedXPSInitializer xps_initializer; | 458 printing::ScopedXPSInitializer xps_initializer; |
459 if (!xps_initializer.initialized()) | 459 if (!xps_initializer.initialized()) |
460 return default_ticket.Pass(); | 460 return default_ticket; |
461 | 461 |
462 const char* xps_color = color ? kXpsTicketColor : kXpsTicketMonochrome; | 462 const char* xps_color = color ? kXpsTicketColor : kXpsTicketMonochrome; |
463 std::string xps_ticket = base::StringPrintf(kXpsTicketTemplate, xps_color); | 463 std::string xps_ticket = base::StringPrintf(kXpsTicketTemplate, xps_color); |
464 scoped_ptr<DEVMODE, base::FreeDeleter> ticket = | 464 scoped_ptr<DEVMODE, base::FreeDeleter> ticket = |
465 printing::XpsTicketToDevMode(printer_name, xps_ticket); | 465 printing::XpsTicketToDevMode(printer_name, xps_ticket); |
466 if (!ticket) | 466 if (!ticket) |
467 return default_ticket.Pass(); | 467 return default_ticket; |
468 | 468 |
469 return ticket.Pass(); | 469 return ticket; |
470 } | 470 } |
471 | 471 |
472 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, | 472 scoped_ptr<DEVMODE, base::FreeDeleter> CreateDevMode(HANDLE printer, |
473 DEVMODE* in) { | 473 DEVMODE* in) { |
474 LONG buffer_size = DocumentProperties( | 474 LONG buffer_size = DocumentProperties( |
475 NULL, printer, const_cast<wchar_t*>(L""), NULL, NULL, 0); | 475 NULL, printer, const_cast<wchar_t*>(L""), NULL, NULL, 0); |
476 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) | 476 if (buffer_size < static_cast<int>(sizeof(DEVMODE))) |
477 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 477 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
478 | 478 |
479 // Some drivers request buffers with size smaller than dmSize + dmDriverExtra. | 479 // Some drivers request buffers with size smaller than dmSize + dmDriverExtra. |
480 // crbug.com/421402 | 480 // crbug.com/421402 |
481 buffer_size *= 2; | 481 buffer_size *= 2; |
482 | 482 |
483 scoped_ptr<DEVMODE, base::FreeDeleter> out( | 483 scoped_ptr<DEVMODE, base::FreeDeleter> out( |
484 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); | 484 reinterpret_cast<DEVMODE*>(calloc(buffer_size, 1))); |
485 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; | 485 DWORD flags = (in ? (DM_IN_BUFFER) : 0) | DM_OUT_BUFFER; |
486 if (DocumentProperties( | 486 if (DocumentProperties( |
487 NULL, printer, const_cast<wchar_t*>(L""), out.get(), in, flags) != | 487 NULL, printer, const_cast<wchar_t*>(L""), out.get(), in, flags) != |
488 IDOK) { | 488 IDOK) { |
489 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 489 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
490 } | 490 } |
491 int size = out->dmSize; | 491 int size = out->dmSize; |
492 int extra_size = out->dmDriverExtra; | 492 int extra_size = out->dmDriverExtra; |
493 CHECK_GE(buffer_size, size + extra_size); | 493 CHECK_GE(buffer_size, size + extra_size); |
494 return out.Pass(); | 494 return out; |
495 } | 495 } |
496 | 496 |
497 scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( | 497 scoped_ptr<DEVMODE, base::FreeDeleter> PromptDevMode( |
498 HANDLE printer, | 498 HANDLE printer, |
499 const base::string16& printer_name, | 499 const base::string16& printer_name, |
500 DEVMODE* in, | 500 DEVMODE* in, |
501 HWND window, | 501 HWND window, |
502 bool* canceled) { | 502 bool* canceled) { |
503 LONG buffer_size = | 503 LONG buffer_size = |
504 DocumentProperties(window, | 504 DocumentProperties(window, |
(...skipping 18 matching lines...) Expand all Loading... |
523 out.get(), | 523 out.get(), |
524 in, | 524 in, |
525 flags); | 525 flags); |
526 if (canceled) | 526 if (canceled) |
527 *canceled = (result == IDCANCEL); | 527 *canceled = (result == IDCANCEL); |
528 if (result != IDOK) | 528 if (result != IDOK) |
529 return scoped_ptr<DEVMODE, base::FreeDeleter>(); | 529 return scoped_ptr<DEVMODE, base::FreeDeleter>(); |
530 int size = out->dmSize; | 530 int size = out->dmSize; |
531 int extra_size = out->dmDriverExtra; | 531 int extra_size = out->dmDriverExtra; |
532 CHECK_GE(buffer_size, size + extra_size); | 532 CHECK_GE(buffer_size, size + extra_size); |
533 return out.Pass(); | 533 return out; |
534 } | 534 } |
535 | 535 |
536 } // namespace printing | 536 } // namespace printing |
OLD | NEW |