OLD | NEW |
1 // Copyright (c) 2009 The Chromium Authors. All rights reserved. | 1 // Copyright (c) 2009 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/printing_context.h" | 5 #include "printing/printing_context.h" |
6 | 6 |
7 #include <winspool.h> | 7 #include <winspool.h> |
8 | 8 |
9 #include "base/file_util.h" | 9 #include "base/file_util.h" |
10 #include "base/i18n/file_util_icu.h" | 10 #include "base/i18n/file_util_icu.h" |
(...skipping 120 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
131 | 131 |
132 private: | 132 private: |
133 PrintingContext& owner_; | 133 PrintingContext& owner_; |
134 HWND owner_hwnd_; | 134 HWND owner_hwnd_; |
135 IPrintDialogServices* services_; | 135 IPrintDialogServices* services_; |
136 | 136 |
137 DISALLOW_EVIL_CONSTRUCTORS(CallbackHandler); | 137 DISALLOW_EVIL_CONSTRUCTORS(CallbackHandler); |
138 }; | 138 }; |
139 | 139 |
140 PrintingContext::PrintingContext() | 140 PrintingContext::PrintingContext() |
141 : hdc_(NULL), | 141 : context_(NULL), |
142 #ifndef NDEBUG | 142 #ifndef NDEBUG |
143 page_number_(-1), | 143 page_number_(-1), |
144 #endif | 144 #endif |
145 dialog_box_(NULL), | 145 dialog_box_(NULL), |
146 dialog_box_dismissed_(false), | 146 dialog_box_dismissed_(false), |
147 in_print_job_(false), | 147 in_print_job_(false), |
148 abort_printing_(false) { | 148 abort_printing_(false) { |
149 } | 149 } |
150 | 150 |
151 PrintingContext::~PrintingContext() { | 151 PrintingContext::~PrintingContext() { |
(...skipping 82 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
234 | 234 |
235 // Close the printer after retrieving the context. | 235 // Close the printer after retrieving the context. |
236 ClosePrinter(printer); | 236 ClosePrinter(printer); |
237 | 237 |
238 if (status != OK) | 238 if (status != OK) |
239 ResetSettings(); | 239 ResetSettings(); |
240 return status; | 240 return status; |
241 } | 241 } |
242 | 242 |
243 void PrintingContext::ResetSettings() { | 243 void PrintingContext::ResetSettings() { |
244 if (hdc_ != NULL) { | 244 if (context_ != NULL) { |
245 DeleteDC(hdc_); | 245 DeleteDC(context_); |
246 hdc_ = NULL; | 246 context_ = NULL; |
247 } | 247 } |
248 settings_.Clear(); | 248 settings_.Clear(); |
249 in_print_job_ = false; | 249 in_print_job_ = false; |
250 | 250 |
251 #ifndef NDEBUG | 251 #ifndef NDEBUG |
252 page_number_ = -1; | 252 page_number_ = -1; |
253 #endif | 253 #endif |
254 } | 254 } |
255 | 255 |
256 PrintingContext::Result PrintingContext::NewDocument( | 256 PrintingContext::Result PrintingContext::NewDocument( |
257 const std::wstring& document_name) { | 257 const std::wstring& document_name) { |
258 DCHECK(!in_print_job_); | 258 DCHECK(!in_print_job_); |
259 if (!hdc_) | 259 if (!context_) |
260 return OnError(); | 260 return OnError(); |
261 | 261 |
262 // Set the flag used by the AbortPrintJob dialog procedure. | 262 // Set the flag used by the AbortPrintJob dialog procedure. |
263 abort_printing_ = false; | 263 abort_printing_ = false; |
264 | 264 |
265 in_print_job_ = true; | 265 in_print_job_ = true; |
266 | 266 |
267 // Register the application's AbortProc function with GDI. | 267 // Register the application's AbortProc function with GDI. |
268 if (SP_ERROR == SetAbortProc(hdc_, &AbortProc)) | 268 if (SP_ERROR == SetAbortProc(context_, &AbortProc)) |
269 return OnError(); | 269 return OnError(); |
270 | 270 |
271 DOCINFO di = { sizeof(DOCINFO) }; | 271 DOCINFO di = { sizeof(DOCINFO) }; |
272 di.lpszDocName = document_name.c_str(); | 272 di.lpszDocName = document_name.c_str(); |
273 | 273 |
274 // Is there a debug dump directory specified? If so, force to print to a file. | 274 // Is there a debug dump directory specified? If so, force to print to a file. |
275 std::wstring debug_dump_path = PrintedDocument::debug_dump_path(); | 275 std::wstring debug_dump_path = PrintedDocument::debug_dump_path(); |
276 if (!debug_dump_path.empty()) { | 276 if (!debug_dump_path.empty()) { |
277 // Create a filename. | 277 // Create a filename. |
278 std::wstring filename; | 278 std::wstring filename; |
(...skipping 10 matching lines...) Expand all Loading... |
289 di.lpszOutput = debug_dump_path.c_str(); | 289 di.lpszOutput = debug_dump_path.c_str(); |
290 } | 290 } |
291 | 291 |
292 // No message loop running in unit tests. | 292 // No message loop running in unit tests. |
293 DCHECK(!MessageLoop::current() ? true : | 293 DCHECK(!MessageLoop::current() ? true : |
294 !MessageLoop::current()->NestableTasksAllowed()); | 294 !MessageLoop::current()->NestableTasksAllowed()); |
295 | 295 |
296 // Begin a print job by calling the StartDoc function. | 296 // Begin a print job by calling the StartDoc function. |
297 // NOTE: StartDoc() starts a message loop. That causes a lot of problems with | 297 // NOTE: StartDoc() starts a message loop. That causes a lot of problems with |
298 // IPC. Make sure recursive task processing is disabled. | 298 // IPC. Make sure recursive task processing is disabled. |
299 if (StartDoc(hdc_, &di) <= 0) | 299 if (StartDoc(context_, &di) <= 0) |
300 return OnError(); | 300 return OnError(); |
301 | 301 |
302 #ifndef NDEBUG | 302 #ifndef NDEBUG |
303 page_number_ = 0; | 303 page_number_ = 0; |
304 #endif | 304 #endif |
305 return OK; | 305 return OK; |
306 } | 306 } |
307 | 307 |
308 PrintingContext::Result PrintingContext::NewPage() { | 308 PrintingContext::Result PrintingContext::NewPage() { |
309 if (abort_printing_) | 309 if (abort_printing_) |
310 return CANCEL; | 310 return CANCEL; |
311 DCHECK(in_print_job_); | 311 DCHECK(in_print_job_); |
312 | 312 |
313 // Inform the driver that the application is about to begin sending data. | 313 // Inform the driver that the application is about to begin sending data. |
314 if (StartPage(hdc_) <= 0) | 314 if (StartPage(context_) <= 0) |
315 return OnError(); | 315 return OnError(); |
316 | 316 |
317 #ifndef NDEBUG | 317 #ifndef NDEBUG |
318 ++page_number_; | 318 ++page_number_; |
319 #endif | 319 #endif |
320 | 320 |
321 return OK; | 321 return OK; |
322 } | 322 } |
323 | 323 |
324 PrintingContext::Result PrintingContext::PageDone() { | 324 PrintingContext::Result PrintingContext::PageDone() { |
325 if (abort_printing_) | 325 if (abort_printing_) |
326 return CANCEL; | 326 return CANCEL; |
327 DCHECK(in_print_job_); | 327 DCHECK(in_print_job_); |
328 | 328 |
329 if (EndPage(hdc_) <= 0) | 329 if (EndPage(context_) <= 0) |
330 return OnError(); | 330 return OnError(); |
331 return OK; | 331 return OK; |
332 } | 332 } |
333 | 333 |
334 PrintingContext::Result PrintingContext::DocumentDone() { | 334 PrintingContext::Result PrintingContext::DocumentDone() { |
335 if (abort_printing_) | 335 if (abort_printing_) |
336 return CANCEL; | 336 return CANCEL; |
337 DCHECK(in_print_job_); | 337 DCHECK(in_print_job_); |
338 | 338 |
339 // Inform the driver that document has ended. | 339 // Inform the driver that document has ended. |
340 if (EndDoc(hdc_) <= 0) | 340 if (EndDoc(context_) <= 0) |
341 return OnError(); | 341 return OnError(); |
342 | 342 |
343 ResetSettings(); | 343 ResetSettings(); |
344 return OK; | 344 return OK; |
345 } | 345 } |
346 | 346 |
347 void PrintingContext::Cancel() { | 347 void PrintingContext::Cancel() { |
348 abort_printing_ = true; | 348 abort_printing_ = true; |
349 in_print_job_ = false; | 349 in_print_job_ = false; |
350 if (hdc_) | 350 if (context_) |
351 CancelDC(hdc_); | 351 CancelDC(context_); |
352 DismissDialog(); | 352 DismissDialog(); |
353 } | 353 } |
354 | 354 |
355 void PrintingContext::DismissDialog() { | 355 void PrintingContext::DismissDialog() { |
356 if (dialog_box_) { | 356 if (dialog_box_) { |
357 DestroyWindow(dialog_box_); | 357 DestroyWindow(dialog_box_); |
358 dialog_box_dismissed_ = true; | 358 dialog_box_dismissed_ = true; |
359 } | 359 } |
360 } | 360 } |
361 | 361 |
362 PrintingContext::Result PrintingContext::OnError() { | 362 PrintingContext::Result PrintingContext::OnError() { |
363 // This will close hdc_ and clear settings_. | 363 // This will close context_ and clear settings_. |
364 ResetSettings(); | 364 ResetSettings(); |
365 return abort_printing_ ? CANCEL : FAILED; | 365 return abort_printing_ ? CANCEL : FAILED; |
366 } | 366 } |
367 | 367 |
368 // static | 368 // static |
369 BOOL PrintingContext::AbortProc(HDC hdc, int nCode) { | 369 BOOL PrintingContext::AbortProc(HDC hdc, int nCode) { |
370 if (nCode) { | 370 if (nCode) { |
371 // TODO(maruel): Need a way to find the right instance to set. Should | 371 // TODO(maruel): Need a way to find the right instance to set. Should |
372 // leverage PrintJobManager here? | 372 // leverage PrintJobManager here? |
373 // abort_printing_ = true; | 373 // abort_printing_ = true; |
374 } | 374 } |
375 return true; | 375 return true; |
376 } | 376 } |
377 | 377 |
378 bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode, | 378 bool PrintingContext::InitializeSettings(const DEVMODE& dev_mode, |
379 const std::wstring& new_device_name, | 379 const std::wstring& new_device_name, |
380 const PRINTPAGERANGE* ranges, | 380 const PRINTPAGERANGE* ranges, |
381 int number_ranges, | 381 int number_ranges, |
382 bool selection_only) { | 382 bool selection_only) { |
383 skia::PlatformDevice::InitializeDC(hdc_); | 383 skia::PlatformDevice::InitializeDC(context_); |
384 DCHECK(GetDeviceCaps(hdc_, CLIPCAPS)); | 384 DCHECK(GetDeviceCaps(context_, CLIPCAPS)); |
385 DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_STRETCHDIB); | 385 DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB); |
386 DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_BITMAP64); | 386 DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64); |
387 // Some printers don't advertise these. | 387 // Some printers don't advertise these. |
388 // DCHECK(GetDeviceCaps(hdc_, RASTERCAPS) & RC_SCALING); | 388 // DCHECK(GetDeviceCaps(context_, RASTERCAPS) & RC_SCALING); |
389 // DCHECK(GetDeviceCaps(hdc_, SHADEBLENDCAPS) & SB_CONST_ALPHA); | 389 // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_CONST_ALPHA); |
390 // DCHECK(GetDeviceCaps(hdc_, SHADEBLENDCAPS) & SB_PIXEL_ALPHA); | 390 // DCHECK(GetDeviceCaps(context_, SHADEBLENDCAPS) & SB_PIXEL_ALPHA); |
391 | 391 |
392 // StretchDIBits() support is needed for printing. | 392 // StretchDIBits() support is needed for printing. |
393 if (!(GetDeviceCaps(hdc_, RASTERCAPS) & RC_STRETCHDIB) || | 393 if (!(GetDeviceCaps(context_, RASTERCAPS) & RC_STRETCHDIB) || |
394 !(GetDeviceCaps(hdc_, RASTERCAPS) & RC_BITMAP64)) { | 394 !(GetDeviceCaps(context_, RASTERCAPS) & RC_BITMAP64)) { |
395 NOTREACHED(); | 395 NOTREACHED(); |
396 ResetSettings(); | 396 ResetSettings(); |
397 return false; | 397 return false; |
398 } | 398 } |
399 | 399 |
400 DCHECK(!in_print_job_); | 400 DCHECK(!in_print_job_); |
401 DCHECK(hdc_); | 401 DCHECK(context_); |
402 PageRanges ranges_vector; | 402 PageRanges ranges_vector; |
403 if (!selection_only) { | 403 if (!selection_only) { |
404 // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector. | 404 // Convert the PRINTPAGERANGE array to a PrintSettings::PageRanges vector. |
405 ranges_vector.reserve(number_ranges); | 405 ranges_vector.reserve(number_ranges); |
406 for (int i = 0; i < number_ranges; ++i) { | 406 for (int i = 0; i < number_ranges; ++i) { |
407 PageRange range; | 407 PageRange range; |
408 // Transfer from 1-based to 0-based. | 408 // Transfer from 1-based to 0-based. |
409 range.from = ranges[i].nFromPage - 1; | 409 range.from = ranges[i].nFromPage - 1; |
410 range.to = ranges[i].nToPage - 1; | 410 range.to = ranges[i].nToPage - 1; |
411 ranges_vector.push_back(range); | 411 ranges_vector.push_back(range); |
412 } | 412 } |
413 } | 413 } |
414 settings_.Init(hdc_, | 414 settings_.Init(context_, |
415 dev_mode, | 415 dev_mode, |
416 ranges_vector, | 416 ranges_vector, |
417 new_device_name, | 417 new_device_name, |
418 selection_only); | 418 selection_only); |
419 return true; | 419 return true; |
420 } | 420 } |
421 | 421 |
422 bool PrintingContext::GetPrinterSettings(HANDLE printer, | 422 bool PrintingContext::GetPrinterSettings(HANDLE printer, |
423 const std::wstring& device_name) { | 423 const std::wstring& device_name) { |
424 DCHECK(!in_print_job_); | 424 DCHECK(!in_print_job_); |
(...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
467 } | 467 } |
468 buffer.reset(); | 468 buffer.reset(); |
469 } | 469 } |
470 // Failed to retrieve the printer settings. | 470 // Failed to retrieve the printer settings. |
471 ResetSettings(); | 471 ResetSettings(); |
472 return false; | 472 return false; |
473 } | 473 } |
474 | 474 |
475 bool PrintingContext::AllocateContext(const std::wstring& printer_name, | 475 bool PrintingContext::AllocateContext(const std::wstring& printer_name, |
476 const DEVMODE* dev_mode) { | 476 const DEVMODE* dev_mode) { |
477 hdc_ = CreateDC(L"WINSPOOL", printer_name.c_str(), NULL, dev_mode); | 477 context_ = CreateDC(L"WINSPOOL", printer_name.c_str(), NULL, dev_mode); |
478 DCHECK(hdc_); | 478 DCHECK(context_); |
479 return hdc_ != NULL; | 479 return context_ != NULL; |
480 } | 480 } |
481 | 481 |
482 PrintingContext::Result PrintingContext::ParseDialogResultEx( | 482 PrintingContext::Result PrintingContext::ParseDialogResultEx( |
483 const PRINTDLGEX& dialog_options) { | 483 const PRINTDLGEX& dialog_options) { |
484 // If the user clicked OK or Apply then Cancel, but not only Cancel. | 484 // If the user clicked OK or Apply then Cancel, but not only Cancel. |
485 if (dialog_options.dwResultAction != PD_RESULT_CANCEL) { | 485 if (dialog_options.dwResultAction != PD_RESULT_CANCEL) { |
486 // Start fresh. | 486 // Start fresh. |
487 ResetSettings(); | 487 ResetSettings(); |
488 | 488 |
489 DEVMODE* dev_mode = NULL; | 489 DEVMODE* dev_mode = NULL; |
(...skipping 12 matching lines...) Expand all Loading... |
502 device_name = | 502 device_name = |
503 reinterpret_cast<const wchar_t*>( | 503 reinterpret_cast<const wchar_t*>( |
504 reinterpret_cast<const wchar_t*>(dev_names) + | 504 reinterpret_cast<const wchar_t*>(dev_names) + |
505 dev_names->wDeviceOffset); | 505 dev_names->wDeviceOffset); |
506 GlobalUnlock(dialog_options.hDevNames); | 506 GlobalUnlock(dialog_options.hDevNames); |
507 } | 507 } |
508 } | 508 } |
509 | 509 |
510 bool success = false; | 510 bool success = false; |
511 if (dev_mode && !device_name.empty()) { | 511 if (dev_mode && !device_name.empty()) { |
512 hdc_ = dialog_options.hDC; | 512 context_ = dialog_options.hDC; |
513 PRINTPAGERANGE* page_ranges = NULL; | 513 PRINTPAGERANGE* page_ranges = NULL; |
514 DWORD num_page_ranges = 0; | 514 DWORD num_page_ranges = 0; |
515 bool print_selection_only = false; | 515 bool print_selection_only = false; |
516 if (dialog_options.Flags & PD_PAGENUMS) { | 516 if (dialog_options.Flags & PD_PAGENUMS) { |
517 page_ranges = dialog_options.lpPageRanges; | 517 page_ranges = dialog_options.lpPageRanges; |
518 num_page_ranges = dialog_options.nPageRanges; | 518 num_page_ranges = dialog_options.nPageRanges; |
519 } | 519 } |
520 if (dialog_options.Flags & PD_SELECTION) { | 520 if (dialog_options.Flags & PD_SELECTION) { |
521 print_selection_only = true; | 521 print_selection_only = true; |
522 } | 522 } |
523 success = InitializeSettings(*dev_mode, | 523 success = InitializeSettings(*dev_mode, |
524 device_name, | 524 device_name, |
525 dialog_options.lpPageRanges, | 525 dialog_options.lpPageRanges, |
526 dialog_options.nPageRanges, | 526 dialog_options.nPageRanges, |
527 print_selection_only); | 527 print_selection_only); |
528 } | 528 } |
529 | 529 |
530 if (!success && dialog_options.hDC) { | 530 if (!success && dialog_options.hDC) { |
531 DeleteDC(dialog_options.hDC); | 531 DeleteDC(dialog_options.hDC); |
532 hdc_ = NULL; | 532 context_ = NULL; |
533 } | 533 } |
534 | 534 |
535 if (dev_mode) { | 535 if (dev_mode) { |
536 GlobalUnlock(dialog_options.hDevMode); | 536 GlobalUnlock(dialog_options.hDevMode); |
537 } | 537 } |
538 } else { | 538 } else { |
539 if (dialog_options.hDC) { | 539 if (dialog_options.hDC) { |
540 DeleteDC(dialog_options.hDC); | 540 DeleteDC(dialog_options.hDC); |
541 } | 541 } |
542 } | 542 } |
543 | 543 |
544 if (dialog_options.hDevMode != NULL) | 544 if (dialog_options.hDevMode != NULL) |
545 GlobalFree(dialog_options.hDevMode); | 545 GlobalFree(dialog_options.hDevMode); |
546 if (dialog_options.hDevNames != NULL) | 546 if (dialog_options.hDevNames != NULL) |
547 GlobalFree(dialog_options.hDevNames); | 547 GlobalFree(dialog_options.hDevNames); |
548 | 548 |
549 switch (dialog_options.dwResultAction) { | 549 switch (dialog_options.dwResultAction) { |
550 case PD_RESULT_PRINT: | 550 case PD_RESULT_PRINT: |
551 return hdc_ ? OK : FAILED; | 551 return context_ ? OK : FAILED; |
552 case PD_RESULT_APPLY: | 552 case PD_RESULT_APPLY: |
553 return hdc_ ? CANCEL : FAILED; | 553 return context_ ? CANCEL : FAILED; |
554 case PD_RESULT_CANCEL: | 554 case PD_RESULT_CANCEL: |
555 return CANCEL; | 555 return CANCEL; |
556 default: | 556 default: |
557 return FAILED; | 557 return FAILED; |
558 } | 558 } |
559 } | 559 } |
560 | 560 |
561 PrintingContext::Result PrintingContext::ParseDialogResult( | 561 PrintingContext::Result PrintingContext::ParseDialogResult( |
562 const PRINTDLG& dialog_options) { | 562 const PRINTDLG& dialog_options) { |
563 // If the user clicked OK or Apply then Cancel, but not only Cancel. | 563 // If the user clicked OK or Apply then Cancel, but not only Cancel. |
(...skipping 16 matching lines...) Expand all Loading... |
580 device_name = | 580 device_name = |
581 reinterpret_cast<const wchar_t*>( | 581 reinterpret_cast<const wchar_t*>( |
582 reinterpret_cast<const wchar_t*>(dev_names) + | 582 reinterpret_cast<const wchar_t*>(dev_names) + |
583 dev_names->wDeviceOffset); | 583 dev_names->wDeviceOffset); |
584 GlobalUnlock(dialog_options.hDevNames); | 584 GlobalUnlock(dialog_options.hDevNames); |
585 } | 585 } |
586 } | 586 } |
587 | 587 |
588 bool success = false; | 588 bool success = false; |
589 if (dev_mode && !device_name.empty()) { | 589 if (dev_mode && !device_name.empty()) { |
590 hdc_ = dialog_options.hDC; | 590 context_ = dialog_options.hDC; |
591 success = InitializeSettings(*dev_mode, device_name, NULL, 0, false); | 591 success = InitializeSettings(*dev_mode, device_name, NULL, 0, false); |
592 } | 592 } |
593 | 593 |
594 if (!success && dialog_options.hDC) { | 594 if (!success && dialog_options.hDC) { |
595 DeleteDC(dialog_options.hDC); | 595 DeleteDC(dialog_options.hDC); |
596 hdc_ = NULL; | 596 context_ = NULL; |
597 } | 597 } |
598 | 598 |
599 if (dev_mode) { | 599 if (dev_mode) { |
600 GlobalUnlock(dialog_options.hDevMode); | 600 GlobalUnlock(dialog_options.hDevMode); |
601 } | 601 } |
602 | 602 |
603 if (dialog_options.hDevMode != NULL) | 603 if (dialog_options.hDevMode != NULL) |
604 GlobalFree(dialog_options.hDevMode); | 604 GlobalFree(dialog_options.hDevMode); |
605 if (dialog_options.hDevNames != NULL) | 605 if (dialog_options.hDevNames != NULL) |
606 GlobalFree(dialog_options.hDevNames); | 606 GlobalFree(dialog_options.hDevNames); |
607 | 607 |
608 return hdc_ ? OK : FAILED; | 608 return context_ ? OK : FAILED; |
609 } | 609 } |
610 | 610 |
611 } // namespace printing | 611 } // namespace printing |
OLD | NEW |