summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--chrome/app/chrome_command_ids.h1
-rw-r--r--chrome/browser/printing/print_job_manager.cc6
-rw-r--r--chrome/browser/printing/print_job_manager.h9
-rw-r--r--chrome/browser/printing/print_job_worker.cc23
-rw-r--r--chrome/browser/printing/print_job_worker.h10
-rw-r--r--chrome/browser/printing/print_view_manager.cc10
-rw-r--r--chrome/browser/printing/print_view_manager.h5
-rw-r--r--chrome/browser/printing/printer_query.cc7
-rw-r--r--chrome/browser/printing/printer_query.h8
-rw-r--r--chrome/browser/printing/printing_message_filter.cc10
-rw-r--r--chrome/browser/ui/browser_command_controller.cc19
-rw-r--r--chrome/browser/ui/browser_commands.cc4
-rw-r--r--chrome/browser/ui/browser_commands.h1
-rw-r--r--printing/print_destination_interface.h33
-rw-r--r--printing/print_destination_none.cc13
-rw-r--r--printing/print_destination_win.cc52
-rw-r--r--printing/printing.gyp6
17 files changed, 208 insertions, 9 deletions
diff --git a/chrome/app/chrome_command_ids.h b/chrome/app/chrome_command_ids.h
index da1a0fb..d7aec0e 100644
--- a/chrome/app/chrome_command_ids.h
+++ b/chrome/app/chrome_command_ids.h
@@ -77,6 +77,7 @@
#define IDC_EMAIL_PAGE_LOCATION 35006
#define IDC_ADVANCED_PRINT 35007
#define IDC_CHROME_TO_MOBILE_PAGE 35008
+#define IDC_PRINT_TO_DESTINATION 35009
// When adding a new encoding to this list, be sure to append it to the
// EncodingMenuController::kValidEncodingIds array in
diff --git a/chrome/browser/printing/print_job_manager.cc b/chrome/browser/printing/print_job_manager.cc
index e83238c..e3abfd1 100644
--- a/chrome/browser/printing/print_job_manager.cc
+++ b/chrome/browser/printing/print_job_manager.cc
@@ -59,6 +59,11 @@ void PrintJobManager::StopJobs(bool wait_for_finish) {
current_jobs_.clear();
}
+void PrintJobManager::SetPrintDestination(
+ PrintDestinationInterface* destination) {
+ destination_ = destination;
+}
+
void PrintJobManager::QueuePrinterQuery(PrinterQuery* job) {
base::AutoLock lock(lock_);
DCHECK(job);
@@ -125,6 +130,7 @@ void PrintJobManager::OnPrintJobEvent(
DCHECK(current_jobs_.end() == std::find(current_jobs_.begin(),
current_jobs_.end(),
print_job));
+ destination_ = NULL;
break;
}
case JobEventDetails::FAILED: {
diff --git a/chrome/browser/printing/print_job_manager.h b/chrome/browser/printing/print_job_manager.h
index 4fc34d4..3ea70a63 100644
--- a/chrome/browser/printing/print_job_manager.h
+++ b/chrome/browser/printing/print_job_manager.h
@@ -13,6 +13,7 @@
#include "chrome/browser/prefs/pref_member.h"
#include "content/public/browser/notification_observer.h"
#include "content/public/browser/notification_registrar.h"
+#include "printing/print_destination_interface.h"
class PrefService;
@@ -38,6 +39,9 @@ class PrintJobManager : public content::NotificationObserver {
// a chance to complete before stopping them.
void StopJobs(bool wait_for_finish);
+ // Sets the print destination to be set on the next print job.
+ void SetPrintDestination(PrintDestinationInterface* destination);
+
// Queues a semi-initialized worker thread. Can be called from any thread.
// Current use case is queuing from the I/O thread.
// TODO(maruel): Have them vanish after a timeout (~5 minutes?)
@@ -58,6 +62,9 @@ class PrintJobManager : public content::NotificationObserver {
// prefs::kPrintingEnabled via g_browser_process->local_state() directly.
bool printing_enabled() const;
+ // May return NULL when no destination was set.
+ PrintDestinationInterface* destination() const { return destination_.get(); }
+
private:
typedef std::vector<scoped_refptr<PrintJob> > PrintJobs;
typedef std::vector<scoped_refptr<PrinterQuery> > PrinterQueries;
@@ -83,6 +90,8 @@ class PrintJobManager : public content::NotificationObserver {
PrinterQueries queued_queries_;
+ scoped_refptr<PrintDestinationInterface> destination_;
+
// Current print jobs that are active.
PrintJobs current_jobs_;
diff --git a/chrome/browser/printing/print_job_worker.cc b/chrome/browser/printing/print_job_worker.cc
index 1162cc5..54082cf 100644
--- a/chrome/browser/printing/print_job_worker.cc
+++ b/chrome/browser/printing/print_job_worker.cc
@@ -69,6 +69,11 @@ void PrintJobWorker::SetNewOwner(PrintJobWorkerOwner* new_owner) {
owner_ = new_owner;
}
+void PrintJobWorker::SetPrintDestination(
+ PrintDestinationInterface* destination) {
+ destination_ = destination;
+}
+
void PrintJobWorker::GetSettings(bool ask_user_for_settings,
gfx::NativeView parent_view,
int document_page_count,
@@ -85,7 +90,9 @@ void PrintJobWorker::GetSettings(bool ask_user_for_settings,
// MessageLoop::current()->SetNestableTasksAllowed(true);
printing_context_->set_margin_type(margin_type);
- if (ask_user_for_settings) {
+ // When we delegate to a destination, we don't ask the user for settings.
+ // TODO(mad): Ask the destination for settings.
+ if (ask_user_for_settings && destination_.get() == NULL) {
BrowserThread::PostTask(
BrowserThread::UI, FROM_HERE,
base::Bind(&HoldRefCallback, make_scoped_refptr(owner_),
@@ -241,6 +248,8 @@ void PrintJobWorker::OnNewPage() {
}
// We have enough information to initialize page_number_.
page_number_.Init(document_->settings(), page_count);
+ if (destination_.get() != NULL)
+ destination_->SetPageCount(page_count);
}
DCHECK_NE(page_number_, PageNumber::npos());
@@ -308,6 +317,18 @@ void PrintJobWorker::SpoolPage(PrintedPage* page) {
return;
}
+ if (destination_.get() != NULL) {
+ std::vector<uint8> metabytes(page->metafile()->GetDataSize());
+ bool success = page->metafile()->GetData(
+ reinterpret_cast<void*>(&metabytes[0]), metabytes.size());
+ DCHECK(success) << "Failed to get metafile data.";
+ destination_->SetPageContent(
+ page->page_number(),
+ reinterpret_cast<void*>(&metabytes[0]),
+ metabytes.size());
+ return;
+ }
+
// Actual printing.
#if defined(OS_WIN) || defined(OS_MACOSX)
document_->RenderPrintedPage(*page, printing_context_->context());
diff --git a/chrome/browser/printing/print_job_worker.h b/chrome/browser/printing/print_job_worker.h
index fee682d..41b9171 100644
--- a/chrome/browser/printing/print_job_worker.h
+++ b/chrome/browser/printing/print_job_worker.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -11,6 +11,7 @@
#include "base/memory/weak_ptr.h"
#include "base/threading/thread.h"
#include "printing/page_number.h"
+#include "printing/print_destination_interface.h"
#include "printing/printing_context.h"
#include "printing/print_job_constants.h"
#include "ui/gfx/native_widget_types.h"
@@ -39,6 +40,10 @@ class PrintJobWorker : public base::Thread {
void SetNewOwner(PrintJobWorkerOwner* new_owner);
+ // Set a destination for print.
+ // This supercedes the document's rendering destination.
+ void SetPrintDestination(PrintDestinationInterface* destination);
+
// Initializes the print settings. If |ask_user_for_settings| is true, a
// Print... dialog box will be shown to ask the user his preference.
void GetSettings(bool ask_user_for_settings,
@@ -118,6 +123,9 @@ class PrintJobWorker : public base::Thread {
// The printed document. Only has read-only access.
scoped_refptr<PrintedDocument> document_;
+ // The print destination, may be NULL.
+ scoped_refptr<PrintDestinationInterface> destination_;
+
// The print job owning this worker thread. It is guaranteed to outlive this
// object.
PrintJobWorkerOwner* owner_;
diff --git a/chrome/browser/printing/print_view_manager.cc b/chrome/browser/printing/print_view_manager.cc
index 477336e..6f8a334 100644
--- a/chrome/browser/printing/print_view_manager.cc
+++ b/chrome/browser/printing/print_view_manager.cc
@@ -31,6 +31,7 @@
#include "grit/generated_resources.h"
#include "printing/metafile.h"
#include "printing/metafile_impl.h"
+#include "printing/print_destination_interface.h"
#include "printing/printed_document.h"
#include "ui/base/l10n/l10n_util.h"
@@ -101,6 +102,13 @@ bool PrintViewManager::AdvancedPrintNow() {
}
}
+bool PrintViewManager::PrintToDestination() {
+ // TODO(mad): Use a passed in destination interface instead.
+ g_browser_process->print_job_manager()->SetPrintDestination(
+ printing::CreatePrintDestination());
+ return PrintNowInternal(new PrintMsg_PrintPages(routing_id()));
+}
+
bool PrintViewManager::PrintPreviewNow() {
if (print_preview_state_ != NOT_PREVIEWING) {
NOTREACHED();
@@ -613,6 +621,8 @@ void PrintViewManager::ReleasePrinterQuery() {
int cookie = cookie_;
cookie_ = 0;
+ g_browser_process->print_job_manager()->SetPrintDestination(NULL);
+
printing::PrintJobManager* print_job_manager =
g_browser_process->print_job_manager();
diff --git a/chrome/browser/printing/print_view_manager.h b/chrome/browser/printing/print_view_manager.h
index da74578..02ef195 100644
--- a/chrome/browser/printing/print_view_manager.h
+++ b/chrome/browser/printing/print_view_manager.h
@@ -51,6 +51,11 @@ class PrintViewManager : public content::NotificationObserver,
// preview tab.
bool AdvancedPrintNow();
+ // Same as PrintNow(), but for the case where we want to send the result to
+ // another destination.
+ // TODO(mad) Add an argument so we can pass the destination interface.
+ bool PrintToDestination();
+
// Initiate print preview of the current document by first notifying the
// renderer. Since this happens asynchronous, the print preview tab creation
// will not be completed on the return of this function. Returns false if
diff --git a/chrome/browser/printing/printer_query.cc b/chrome/browser/printing/printer_query.cc
index 0536b24..7c07fe2 100644
--- a/chrome/browser/printing/printer_query.cc
+++ b/chrome/browser/printing/printer_query.cc
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -100,6 +100,11 @@ void PrinterQuery::SetSettings(const DictionaryValue& new_settings,
new_settings.DeepCopy()));
}
+void PrinterQuery::SetWorkerDestination(
+ PrintDestinationInterface* destination) {
+ worker_->SetPrintDestination(destination);
+}
+
void PrinterQuery::StartWorker(const base::Closure& callback) {
DCHECK(callback_.is_null());
DCHECK(worker_.get());
diff --git a/chrome/browser/printing/printer_query.h b/chrome/browser/printing/printer_query.h
index dcb2f6a..a2b9bb9 100644
--- a/chrome/browser/printing/printer_query.h
+++ b/chrome/browser/printing/printer_query.h
@@ -1,4 +1,4 @@
-// Copyright (c) 2011 The Chromium Authors. All rights reserved.
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style license that can be
// found in the LICENSE file.
@@ -21,7 +21,8 @@ class DictionaryValue;
namespace printing {
-class PrintJobWorker;
+ class PrintDestinationInterface;
+ class PrintJobWorker;
// Query the printer for settings.
class PrinterQuery : public PrintJobWorkerOwner {
@@ -57,6 +58,9 @@ class PrinterQuery : public PrintJobWorkerOwner {
void SetSettings(const base::DictionaryValue& new_settings,
const base::Closure& callback);
+ // Set a destination for the worker.
+ void SetWorkerDestination(PrintDestinationInterface* destination);
+
// Stops the worker thread since the client is done with this object.
void StopWorker();
diff --git a/chrome/browser/printing/printing_message_filter.cc b/chrome/browser/printing/printing_message_filter.cc
index 812a7a0..2ba8a02 100644
--- a/chrome/browser/printing/printing_message_filter.cc
+++ b/chrome/browser/printing/printing_message_filter.cc
@@ -232,8 +232,10 @@ void PrintingMessageFilter::OnGetDefaultPrintSettings(IPC::Message* reply_msg) {
return;
}
print_job_manager_->PopPrinterQuery(0, &printer_query);
- if (!printer_query.get())
+ if (!printer_query.get()) {
printer_query = new printing::PrinterQuery;
+ printer_query->SetWorkerDestination(print_job_manager_->destination());
+ }
// Loads default settings. This is asynchronous, only the IPC message sender
// will hang until the settings are retrieved.
@@ -282,6 +284,7 @@ void PrintingMessageFilter::OnScriptedPrint(
print_job_manager_->PopPrinterQuery(params.cookie, &printer_query);
if (!printer_query.get()) {
printer_query = new printing::PrinterQuery;
+ printer_query->SetWorkerDestination(print_job_manager_->destination());
}
GetPrintSettingsForRenderViewParams settings_params;
settings_params.ask_user_for_settings = printing::PrinterQuery::ASK_USER;
@@ -331,9 +334,10 @@ void PrintingMessageFilter::OnUpdatePrintSettings(
}
print_job_manager_->PopPrinterQuery(document_cookie, &printer_query);
- if (!printer_query.get())
+ if (!printer_query.get()) {
printer_query = new printing::PrinterQuery;
-
+ printer_query->SetWorkerDestination(print_job_manager_->destination());
+ }
printer_query->SetSettings(
job_settings,
base::Bind(&PrintingMessageFilter::OnUpdatePrintSettingsReply, this,
diff --git a/chrome/browser/ui/browser_command_controller.cc b/chrome/browser/ui/browser_command_controller.cc
index fd43df0..158e74d 100644
--- a/chrome/browser/ui/browser_command_controller.cc
+++ b/chrome/browser/ui/browser_command_controller.cc
@@ -371,6 +371,9 @@ void BrowserCommandController::ExecuteCommandWithDisposition(
case IDC_ADVANCED_PRINT:
AdvancedPrint(browser_);
break;
+ case IDC_PRINT_TO_DESTINATION:
+ PrintToDestination(browser_);
+ break;
case IDC_CHROME_TO_MOBILE_PAGE:
ShowChromeToMobileBubble(browser_);
break;
@@ -1013,9 +1016,23 @@ void BrowserCommandController::UpdateCommandsForMultipleProfiles() {
}
void BrowserCommandController::UpdatePrintingState() {
- command_updater_.UpdateCommandEnabled(IDC_PRINT, CanPrint(browser_));
+ bool print_enabled = CanPrint(browser_);
+ command_updater_.UpdateCommandEnabled(IDC_PRINT, print_enabled);
command_updater_.UpdateCommandEnabled(IDC_ADVANCED_PRINT,
CanAdvancedPrint(browser_));
+ command_updater_.UpdateCommandEnabled(IDC_PRINT_TO_DESTINATION,
+ print_enabled);
+#if defined(OS_WIN)
+ HMODULE metro_module = base::win::GetMetroModule();
+ if (metro_module != NULL) {
+ typedef void (*MetroEnablePrinting)(BOOL);
+ MetroEnablePrinting metro_enable_printing =
+ reinterpret_cast<MetroEnablePrinting>(
+ ::GetProcAddress(metro_module, "MetroEnablePrinting"));
+ if (metro_enable_printing)
+ metro_enable_printing(print_enabled);
+ }
+#endif
}
void BrowserCommandController::UpdateSaveAsState() {
diff --git a/chrome/browser/ui/browser_commands.cc b/chrome/browser/ui/browser_commands.cc
index 248b866..1b74ce1 100644
--- a/chrome/browser/ui/browser_commands.cc
+++ b/chrome/browser/ui/browser_commands.cc
@@ -633,6 +633,10 @@ bool CanAdvancedPrint(const Browser* browser) {
return PrintPreviewShowing(browser) || CanPrint(browser);
}
+void PrintToDestination(Browser* browser) {
+ browser->GetActiveTabContents()->print_view_manager()->PrintToDestination();
+}
+
void EmailPageLocation(Browser* browser) {
content::RecordAction(UserMetricsAction("EmailPageLocation"));
WebContents* wc = browser->GetActiveWebContents();
diff --git a/chrome/browser/ui/browser_commands.h b/chrome/browser/ui/browser_commands.h
index bdb7d36..20eba2d 100644
--- a/chrome/browser/ui/browser_commands.h
+++ b/chrome/browser/ui/browser_commands.h
@@ -104,6 +104,7 @@ void Print(Browser* browser);
bool CanPrint(const Browser* browser);
void AdvancedPrint(Browser* browser);
bool CanAdvancedPrint(const Browser* browser);
+void PrintToDestination(Browser* browser);
void EmailPageLocation(Browser* browser);
bool CanEmailPageLocation(const Browser* browser);
void Cut(Browser* browser);
diff --git a/printing/print_destination_interface.h b/printing/print_destination_interface.h
new file mode 100644
index 0000000..13e8c95
--- /dev/null
+++ b/printing/print_destination_interface.h
@@ -0,0 +1,33 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#ifndef PRINTING_PRINT_DESTINATION_INTERFACE_H_
+#define PRINTING_PRINT_DESTINATION_INTERFACE_H_
+#pragma once
+
+#include "base/memory/ref_counted.h"
+#include "printing/printing_export.h"
+
+namespace printing {
+
+class PrintDestinationInterface
+ : public base::RefCountedThreadSafe<PrintDestinationInterface> {
+ public:
+ // Sets the number of pages to print as soon as it is known.
+ virtual void SetPageCount(int page_count) = 0;
+
+ // Sets the metafile bits for a given page as soon as it is ready.
+ virtual void SetPageContent(int page_number,
+ void* content,
+ size_t content_size) = 0;
+ protected:
+ friend class base::RefCountedThreadSafe<PrintDestinationInterface>;
+ virtual ~PrintDestinationInterface() {}
+};
+
+PRINTING_EXPORT PrintDestinationInterface* CreatePrintDestination();
+
+} // namespace printing
+
+#endif // PRINTING_PRINT_DESTINATION_INTERFACE_H_
diff --git a/printing/print_destination_none.cc b/printing/print_destination_none.cc
new file mode 100644
index 0000000..66b838e
--- /dev/null
+++ b/printing/print_destination_none.cc
@@ -0,0 +1,13 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "printing/print_destination_interface.h"
+
+namespace printing {
+
+PrintDestinationInterface* CreatePrintDestination() {
+ return NULL;
+}
+
+} // namespace printing
diff --git a/printing/print_destination_win.cc b/printing/print_destination_win.cc
new file mode 100644
index 0000000..dc99469
--- /dev/null
+++ b/printing/print_destination_win.cc
@@ -0,0 +1,52 @@
+// Copyright (c) 2012 The Chromium Authors. All rights reserved.
+// Use of this source code is governed by a BSD-style license that can be
+// found in the LICENSE file.
+
+#include "printing/print_destination_interface.h"
+
+#include "base/win/metro.h"
+
+namespace printing {
+
+class PrintDestinationWin : public PrintDestinationInterface {
+ public:
+ PrintDestinationWin()
+ : metro_set_print_page_count_(NULL),
+ metro_set_print_page_content_(NULL) {
+ HMODULE metro_module = base::win::GetMetroModule();
+ if (metro_module != NULL) {
+ metro_set_print_page_count_ =
+ reinterpret_cast<MetroSetPrintPageCount>(
+ ::GetProcAddress(metro_module, "MetroSetPrintPageCount"));
+ metro_set_print_page_content_ =
+ reinterpret_cast<MetroSetPrintPageContent>(
+ ::GetProcAddress(metro_module, "MetroSetPrintPageContent"));
+ }
+ }
+ virtual void SetPageCount(int page_count) {
+ if (metro_set_print_page_count_)
+ metro_set_print_page_count_(page_count);
+ }
+
+ virtual void SetPageContent(int page_number,
+ void* content,
+ size_t content_size) {
+ if (metro_set_print_page_content_)
+ metro_set_print_page_content_(page_number - 1, content, content_size);
+ }
+ private:
+ typedef void (*MetroSetPrintPageCount)(INT);
+ typedef void (*MetroSetPrintPageContent)(INT, VOID*, UINT32);
+ MetroSetPrintPageCount metro_set_print_page_count_;
+ MetroSetPrintPageContent metro_set_print_page_content_;
+};
+
+PrintDestinationInterface* CreatePrintDestination() {
+ // We currently only support the Metro print destination.
+ if (base::win::IsMetroProcess())
+ return new PrintDestinationWin;
+ else
+ return NULL;
+}
+
+} // namespace printing
diff --git a/printing/printing.gyp b/printing/printing.gyp
index 19fa1b2..6af7b88 100644
--- a/printing/printing.gyp
+++ b/printing/printing.gyp
@@ -55,6 +55,9 @@
'pdf_metafile_cg_mac.h',
'pdf_metafile_skia.h',
'pdf_metafile_skia.cc',
+ 'print_destination_interface.h',
+ 'print_destination_none.cc',
+ 'print_destination_win.cc',
'printed_document_gtk.cc',
'printed_document.cc',
'printed_document.h',
@@ -146,6 +149,9 @@
'backend/win_helper.h',
'backend/print_backend_win.cc',
],
+ 'sources!': [
+ 'print_destination_none.cc',
+ ],
}],
['chromeos==1 or use_aura==1',{
'sources': [