summaryrefslogtreecommitdiffstats
path: root/embedding/components/printingui/ipc/nsPrintingProxy.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'embedding/components/printingui/ipc/nsPrintingProxy.cpp')
-rw-r--r--embedding/components/printingui/ipc/nsPrintingProxy.cpp269
1 files changed, 269 insertions, 0 deletions
diff --git a/embedding/components/printingui/ipc/nsPrintingProxy.cpp b/embedding/components/printingui/ipc/nsPrintingProxy.cpp
new file mode 100644
index 000000000..353be04ee
--- /dev/null
+++ b/embedding/components/printingui/ipc/nsPrintingProxy.cpp
@@ -0,0 +1,269 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 4 -*-
+ *
+ * This Source Code Form is subject to the terms of the Mozilla Public
+ * License, v. 2.0. If a copy of the MPL was not distributed with this
+ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
+
+#include "nsPrintingProxy.h"
+
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/TabChild.h"
+#include "mozilla/layout/RemotePrintJobChild.h"
+#include "mozilla/Unused.h"
+#include "nsIDocShell.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIPrintingPromptService.h"
+#include "nsIPrintSession.h"
+#include "nsPIDOMWindow.h"
+#include "nsPrintOptionsImpl.h"
+#include "nsServiceManagerUtils.h"
+#include "PrintDataUtils.h"
+#include "PrintProgressDialogChild.h"
+#include "PrintSettingsDialogChild.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+using namespace mozilla::embedding;
+using namespace mozilla::layout;
+
+static StaticRefPtr<nsPrintingProxy> sPrintingProxyInstance;
+
+NS_IMPL_ISUPPORTS(nsPrintingProxy, nsIPrintingPromptService)
+
+nsPrintingProxy::nsPrintingProxy()
+{
+}
+
+nsPrintingProxy::~nsPrintingProxy()
+{
+}
+
+/* static */
+already_AddRefed<nsPrintingProxy>
+nsPrintingProxy::GetInstance()
+{
+ if (!sPrintingProxyInstance) {
+ sPrintingProxyInstance = new nsPrintingProxy();
+ if (!sPrintingProxyInstance) {
+ return nullptr;
+ }
+ nsresult rv = sPrintingProxyInstance->Init();
+ if (NS_FAILED(rv)) {
+ sPrintingProxyInstance = nullptr;
+ return nullptr;
+ }
+ ClearOnShutdown(&sPrintingProxyInstance);
+ }
+
+ RefPtr<nsPrintingProxy> inst = sPrintingProxyInstance.get();
+ return inst.forget();
+}
+
+nsresult
+nsPrintingProxy::Init()
+{
+ mozilla::Unused << ContentChild::GetSingleton()->SendPPrintingConstructor(this);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingProxy::ShowPrintDialog(mozIDOMWindowProxy *parent,
+ nsIWebBrowserPrint *webBrowserPrint,
+ nsIPrintSettings *printSettings)
+{
+ NS_ENSURE_ARG(webBrowserPrint);
+ NS_ENSURE_ARG(printSettings);
+
+ // If parent is null we are just being called to retrieve the print settings
+ // from the printer in the parent for print preview.
+ TabChild* pBrowser = nullptr;
+ if (parent) {
+ // Get the TabChild for this nsIDOMWindow, which we can then pass up to
+ // the parent.
+ nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(parent);
+ NS_ENSURE_STATE(pwin);
+ nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
+ NS_ENSURE_STATE(docShell);
+
+ nsCOMPtr<nsITabChild> tabchild = docShell->GetTabChild();
+ NS_ENSURE_STATE(tabchild);
+
+ pBrowser = static_cast<TabChild*>(tabchild.get());
+ }
+
+ // Next, serialize the nsIWebBrowserPrint and nsIPrintSettings we were given.
+ nsresult rv = NS_OK;
+ nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
+ do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PrintData inSettings;
+ rv = printSettingsSvc->SerializeToPrintData(printSettings, webBrowserPrint,
+ &inSettings);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ // Now, the waiting game. The parent process should be showing
+ // the printing dialog soon. In the meantime, we need to spin a
+ // nested event loop while we wait for the results of the dialog
+ // to be returned to us.
+
+ RefPtr<PrintSettingsDialogChild> dialog = new PrintSettingsDialogChild();
+ SendPPrintSettingsDialogConstructor(dialog);
+
+ mozilla::Unused << SendShowPrintDialog(dialog, pBrowser, inSettings);
+
+ while(!dialog->returned()) {
+ NS_ProcessNextEvent(nullptr, true);
+ }
+
+ rv = dialog->result();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = printSettingsSvc->DeserializeToPrintSettings(dialog->data(),
+ printSettings);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingProxy::ShowProgress(mozIDOMWindowProxy* parent,
+ nsIWebBrowserPrint* webBrowserPrint, // ok to be null
+ nsIPrintSettings* printSettings, // ok to be null
+ nsIObserver* openDialogObserver, // ok to be null
+ bool isForPrinting,
+ nsIWebProgressListener** webProgressListener,
+ nsIPrintProgressParams** printProgressParams,
+ bool* notifyOnOpen)
+{
+ NS_ENSURE_ARG(parent);
+ NS_ENSURE_ARG(webProgressListener);
+ NS_ENSURE_ARG(printProgressParams);
+ NS_ENSURE_ARG(notifyOnOpen);
+
+ // Get the TabChild for this nsIDOMWindow, which we can then pass up to
+ // the parent.
+ nsCOMPtr<nsPIDOMWindowOuter> pwin = nsPIDOMWindowOuter::From(parent);
+ NS_ENSURE_STATE(pwin);
+ nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
+ NS_ENSURE_STATE(docShell);
+ nsCOMPtr<nsITabChild> tabchild = docShell->GetTabChild();
+ TabChild* pBrowser = static_cast<TabChild*>(tabchild.get());
+
+ RefPtr<PrintProgressDialogChild> dialogChild =
+ new PrintProgressDialogChild(openDialogObserver);
+
+ SendPPrintProgressDialogConstructor(dialogChild);
+
+ // Get the RemotePrintJob if we have one available.
+ RefPtr<mozilla::layout::RemotePrintJobChild> remotePrintJob;
+ if (printSettings) {
+ nsCOMPtr<nsIPrintSession> printSession;
+ nsresult rv = printSettings->GetPrintSession(getter_AddRefs(printSession));
+ if (NS_SUCCEEDED(rv) && printSession) {
+ printSession->GetRemotePrintJob(getter_AddRefs(remotePrintJob));
+ }
+ }
+
+ nsresult rv = NS_OK;
+ mozilla::Unused << SendShowProgress(pBrowser, dialogChild, remotePrintJob,
+ isForPrinting, notifyOnOpen, &rv);
+ if (NS_FAILED(rv)) {
+ return rv;
+ }
+
+ // If we have a RemotePrintJob that will be being used as a more general
+ // forwarder for print progress listeners. Once we always have one we can
+ // remove the interface from PrintProgressDialogChild.
+ if (!remotePrintJob) {
+ NS_ADDREF(*webProgressListener = dialogChild);
+ }
+ NS_ADDREF(*printProgressParams = dialogChild);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingProxy::ShowPageSetup(mozIDOMWindowProxy *parent,
+ nsIPrintSettings *printSettings,
+ nsIObserver *aObs)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsPrintingProxy::ShowPrinterProperties(mozIDOMWindowProxy *parent,
+ const char16_t *printerName,
+ nsIPrintSettings *printSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+nsresult
+nsPrintingProxy::SavePrintSettings(nsIPrintSettings* aPS,
+ bool aUsePrinterNamePrefix,
+ uint32_t aFlags)
+{
+ nsresult rv;
+ nsCOMPtr<nsIPrintSettingsService> printSettingsSvc =
+ do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ PrintData settings;
+ rv = printSettingsSvc->SerializeToPrintData(aPS, nullptr, &settings);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ Unused << SendSavePrintSettings(settings, aUsePrinterNamePrefix, aFlags,
+ &rv);
+ return rv;
+}
+
+PPrintProgressDialogChild*
+nsPrintingProxy::AllocPPrintProgressDialogChild()
+{
+ // The parent process will never initiate the PPrintProgressDialog
+ // protocol connection, so no need to provide an allocator here.
+ NS_NOTREACHED("Allocator for PPrintProgressDialogChild should not be "
+ "called on nsPrintingProxy.");
+ return nullptr;
+}
+
+bool
+nsPrintingProxy::DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor)
+{
+ // The PrintProgressDialogChild implements refcounting, and
+ // will take itself out.
+ return true;
+}
+
+PPrintSettingsDialogChild*
+nsPrintingProxy::AllocPPrintSettingsDialogChild()
+{
+ // The parent process will never initiate the PPrintSettingsDialog
+ // protocol connection, so no need to provide an allocator here.
+ NS_NOTREACHED("Allocator for PPrintSettingsDialogChild should not be "
+ "called on nsPrintingProxy.");
+ return nullptr;
+}
+
+bool
+nsPrintingProxy::DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor)
+{
+ // The PrintSettingsDialogChild implements refcounting, and
+ // will take itself out.
+ return true;
+}
+
+PRemotePrintJobChild*
+nsPrintingProxy::AllocPRemotePrintJobChild()
+{
+ RefPtr<RemotePrintJobChild> remotePrintJob = new RemotePrintJobChild();
+ return remotePrintJob.forget().take();
+}
+
+bool
+nsPrintingProxy::DeallocPRemotePrintJobChild(PRemotePrintJobChild* aDoomed)
+{
+ RemotePrintJobChild* remotePrintJob = static_cast<RemotePrintJobChild*>(aDoomed);
+ NS_RELEASE(remotePrintJob);
+ return true;
+}