| 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 |