summaryrefslogtreecommitdiffstats
path: root/toolkit/components/printingui
diff options
context:
space:
mode:
authorDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
committerDaniel Baumann <daniel.baumann@progress-linux.org>2024-04-28 14:29:10 +0000
commit2aa4a82499d4becd2284cdb482213d541b8804dd (patch)
treeb80bf8bf13c3766139fbacc530efd0dd9d54394c /toolkit/components/printingui
parentInitial commit. (diff)
downloadfirefox-upstream.tar.xz
firefox-upstream.zip
Adding upstream version 86.0.1.upstream/86.0.1upstream
Signed-off-by: Daniel Baumann <daniel.baumann@progress-linux.org>
Diffstat (limited to 'toolkit/components/printingui')
-rw-r--r--toolkit/components/printingui/ipc/PPrintProgressDialog.ipdl36
-rw-r--r--toolkit/components/printingui/ipc/PPrintSettingsDialog.ipdl29
-rw-r--r--toolkit/components/printingui/ipc/PPrinting.ipdl46
-rw-r--r--toolkit/components/printingui/ipc/PPrintingTypes.ipdlh94
-rw-r--r--toolkit/components/printingui/ipc/PrintProgressDialogChild.cpp128
-rw-r--r--toolkit/components/printingui/ipc/PrintProgressDialogChild.h43
-rw-r--r--toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp111
-rw-r--r--toolkit/components/printingui/ipc/PrintProgressDialogParent.h57
-rw-r--r--toolkit/components/printingui/ipc/PrintSettingsDialogChild.cpp34
-rw-r--r--toolkit/components/printingui/ipc/PrintSettingsDialogChild.h35
-rw-r--r--toolkit/components/printingui/ipc/PrintSettingsDialogParent.cpp22
-rw-r--r--toolkit/components/printingui/ipc/PrintSettingsDialogParent.h27
-rw-r--r--toolkit/components/printingui/ipc/PrintingParent.cpp307
-rw-r--r--toolkit/components/printingui/ipc/PrintingParent.h87
-rw-r--r--toolkit/components/printingui/ipc/moz.build34
-rw-r--r--toolkit/components/printingui/ipc/nsPrintingProxy.cpp232
-rw-r--r--toolkit/components/printingui/ipc/nsPrintingProxy.h59
-rw-r--r--toolkit/components/printingui/moz.build22
-rw-r--r--toolkit/components/printingui/nsPrintProgress.cpp265
-rw-r--r--toolkit/components/printingui/nsPrintProgress.h44
-rw-r--r--toolkit/components/printingui/nsPrintProgressParams.cpp37
-rw-r--r--toolkit/components/printingui/nsPrintProgressParams.h27
-rw-r--r--toolkit/components/printingui/nsPrintingPromptService.cpp225
-rw-r--r--toolkit/components/printingui/nsPrintingPromptService.h54
24 files changed, 2055 insertions, 0 deletions
diff --git a/toolkit/components/printingui/ipc/PPrintProgressDialog.ipdl b/toolkit/components/printingui/ipc/PPrintProgressDialog.ipdl
new file mode 100644
index 0000000000..433c062158
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PPrintProgressDialog.ipdl
@@ -0,0 +1,36 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* 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 protocol PPrinting;
+
+namespace mozilla {
+namespace embedding {
+
+protocol PPrintProgressDialog
+{
+ manager PPrinting;
+
+parent:
+ async StateChange(long stateFlags,
+ nsresult status);
+
+ async ProgressChange(long curSelfProgress,
+ long maxSelfProgress,
+ long curTotalProgress,
+ long maxTotalProgress);
+
+ async DocTitleChange(nsString newTitle);
+
+ async DocURLChange(nsString newURL);
+
+ async __delete__();
+
+child:
+ async DialogOpened();
+ async CancelledCurrentJob();
+};
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PPrintSettingsDialog.ipdl b/toolkit/components/printingui/ipc/PPrintSettingsDialog.ipdl
new file mode 100644
index 0000000000..3e436892ed
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PPrintSettingsDialog.ipdl
@@ -0,0 +1,29 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* 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 PPrintingTypes;
+include protocol PPrinting;
+include protocol PRemotePrintJob;
+
+namespace mozilla {
+namespace embedding {
+
+// A PrintData for success, a failure nsresult for failure.
+union PrintDataOrNSResult
+{
+ PrintData;
+ nsresult;
+};
+
+protocol PPrintSettingsDialog
+{
+ manager PPrinting;
+
+child:
+ async __delete__(PrintDataOrNSResult result);
+};
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PPrinting.ipdl b/toolkit/components/printingui/ipc/PPrinting.ipdl
new file mode 100644
index 0000000000..5adf0e930b
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PPrinting.ipdl
@@ -0,0 +1,46 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* 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 PPrintingTypes;
+include protocol PContent;
+include protocol PBrowser;
+include protocol PPrintProgressDialog;
+include protocol PPrintSettingsDialog;
+include protocol PRemotePrintJob;
+
+namespace mozilla {
+namespace embedding {
+
+sync protocol PPrinting
+{
+ manager PContent;
+ manages PPrintProgressDialog;
+ manages PPrintSettingsDialog;
+ manages PRemotePrintJob;
+
+parent:
+ async ShowProgress(PBrowser browser,
+ PPrintProgressDialog printProgressDialog,
+ nullable PRemotePrintJob remotePrintJob,
+ bool isForPrinting);
+
+ async ShowPrintDialog(PPrintSettingsDialog dialog,
+ nullable PBrowser browser,
+ PrintData settings);
+
+ async PPrintProgressDialog();
+ async PPrintSettingsDialog();
+
+ sync SavePrintSettings(PrintData settings, bool usePrinterNamePrefix,
+ uint32_t flags)
+ returns(nsresult rv);
+
+child:
+ async PRemotePrintJob();
+ async __delete__();
+};
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PPrintingTypes.ipdlh b/toolkit/components/printingui/ipc/PPrintingTypes.ipdlh
new file mode 100644
index 0000000000..2e33907206
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PPrintingTypes.ipdlh
@@ -0,0 +1,94 @@
+/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 8 -*- */
+/* 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 protocol PRemotePrintJob;
+
+namespace mozilla {
+namespace embedding {
+
+struct CStringKeyValue {
+ nsCString key;
+ nsCString value;
+};
+
+struct PrintData {
+ nullable PRemotePrintJob remotePrintJob;
+ double edgeTop;
+ double edgeLeft;
+ double edgeBottom;
+ double edgeRight;
+ double marginTop;
+ double marginLeft;
+ double marginBottom;
+ double marginRight;
+ double unwriteableMarginTop;
+ double unwriteableMarginLeft;
+ double unwriteableMarginBottom;
+ double unwriteableMarginRight;
+ double scaling;
+ bool printBGColors;
+ bool printBGImages;
+ bool honorPageRuleMargins;
+ bool showMarginGuides;
+ bool isPrintSelectionRBEnabled;
+ bool printSelectionOnly;
+ int32_t[] pageRanges;
+ nsString title;
+ nsString docURL;
+ nsString headerStrLeft;
+ nsString headerStrCenter;
+ nsString headerStrRight;
+ nsString footerStrLeft;
+ nsString footerStrCenter;
+ nsString footerStrRight;
+
+ bool isCancelled;
+ bool printSilent;
+ bool shrinkToFit;
+ bool showPrintProgress;
+
+ nsString paperId;
+ double paperWidth;
+ double paperHeight;
+ short paperSizeUnit;
+ bool printReversed;
+ bool printInColor;
+ int32_t orientation;
+ int32_t numCopies;
+ int32_t numPagesPerSheet;
+ nsString printerName;
+ bool printToFile;
+ nsString toFileName;
+ short outputFormat;
+ int32_t printPageDelay;
+ int32_t resolution;
+ int32_t duplex;
+ bool isInitializedFromPrinter;
+ bool isInitializedFromPrefs;
+
+ /* Windows-specific things */
+ nsString driverName;
+ nsString deviceName;
+ uint8_t[] devModeData;
+
+ /**
+ * GTK-specific things. Some of these might look like dupes of the
+ * information we're already passing, but the generalized settings that
+ * we hold in nsIPrintSettings don't map perfectly to GTK's GtkPrintSettings,
+ * so there are some nuances. GtkPrintSettings, for example, stores both an
+ * internal name for paper size, as well as the display name.
+ */
+ CStringKeyValue[] GTKPrintSettings;
+
+ /*
+ * macOS-specific things:
+ * What the Cocoa print system is supposed to do with the job.
+ */
+ nsString disposition;
+ uint16_t destination;
+};
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PrintProgressDialogChild.cpp b/toolkit/components/printingui/ipc/PrintProgressDialogChild.cpp
new file mode 100644
index 0000000000..c3b5adfb22
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintProgressDialogChild.cpp
@@ -0,0 +1,128 @@
+/* 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 "mozilla/Unused.h"
+#include "nsIObserver.h"
+#include "nsIPrintProgressParams.h"
+#include "PrintProgressDialogChild.h"
+
+class nsIWebProgress;
+class nsIRequest;
+
+using mozilla::Unused;
+
+namespace mozilla {
+namespace embedding {
+
+NS_IMPL_ISUPPORTS(PrintProgressDialogChild, nsIWebProgressListener,
+ nsIPrintProgressParams)
+
+PrintProgressDialogChild::PrintProgressDialogChild(
+ nsIObserver* aOpenObserver, nsIPrintSettings* aPrintSettings)
+ : mOpenObserver(aOpenObserver), mPrintSettings(aPrintSettings) {}
+
+PrintProgressDialogChild::~PrintProgressDialogChild() {
+ // When the printing engine stops supplying information about printing
+ // progress, it'll drop references to us and destroy us. We need to signal
+ // the parent to decrement its refcount, as well as prevent it from attempting
+ // to contact us further.
+ Unused << Send__delete__(this);
+}
+
+mozilla::ipc::IPCResult PrintProgressDialogChild::RecvDialogOpened() {
+ // nsPrintJob's observer, which we're reporting to here, doesn't care
+ // what gets passed as the subject, topic or data, so we'll just send
+ // nullptrs.
+ mOpenObserver->Observe(nullptr, nullptr, nullptr);
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult PrintProgressDialogChild::RecvCancelledCurrentJob() {
+ if (mPrintSettings) {
+ mPrintSettings->SetIsCancelled(true);
+ }
+ return IPC_OK();
+}
+
+// nsIWebProgressListener
+
+NS_IMETHODIMP
+PrintProgressDialogChild::OnStateChange(nsIWebProgress* aProgress,
+ nsIRequest* aRequest,
+ uint32_t aStateFlags,
+ nsresult aStatus) {
+ Unused << SendStateChange(aStateFlags, aStatus);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PrintProgressDialogChild::OnProgressChange(nsIWebProgress* aProgress,
+ nsIRequest* aRequest,
+ int32_t aCurSelfProgress,
+ int32_t aMaxSelfProgress,
+ int32_t aCurTotalProgress,
+ int32_t aMaxTotalProgress) {
+ Unused << SendProgressChange(aCurSelfProgress, aMaxSelfProgress,
+ aCurTotalProgress, aMaxTotalProgress);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PrintProgressDialogChild::OnLocationChange(nsIWebProgress* aProgress,
+ nsIRequest* aRequest, nsIURI* aURI,
+ uint32_t aFlags) {
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PrintProgressDialogChild::OnStatusChange(nsIWebProgress* aProgress,
+ nsIRequest* aRequest, nsresult aStatus,
+ const char16_t* aMessage) {
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PrintProgressDialogChild::OnSecurityChange(nsIWebProgress* aProgress,
+ nsIRequest* aRequest,
+ uint32_t aState) {
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PrintProgressDialogChild::OnContentBlockingEvent(nsIWebProgress* aProgress,
+ nsIRequest* aRequest,
+ uint32_t aEvent) {
+ return NS_OK;
+}
+
+// nsIPrintProgressParams
+
+NS_IMETHODIMP
+PrintProgressDialogChild::GetDocTitle(nsAString& aDocTitle) {
+ aDocTitle = mDocTitle;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PrintProgressDialogChild::SetDocTitle(const nsAString& aDocTitle) {
+ mDocTitle = aDocTitle;
+ Unused << SendDocTitleChange(PromiseFlatString(aDocTitle));
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PrintProgressDialogChild::GetDocURL(nsAString& aDocURL) {
+ aDocURL = mDocURL;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+PrintProgressDialogChild::SetDocURL(const nsAString& aDocURL) {
+ mDocURL = aDocURL;
+ Unused << SendDocURLChange(PromiseFlatString(aDocURL));
+ return NS_OK;
+}
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PrintProgressDialogChild.h b/toolkit/components/printingui/ipc/PrintProgressDialogChild.h
new file mode 100644
index 0000000000..74899c07f9
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintProgressDialogChild.h
@@ -0,0 +1,43 @@
+/* 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/. */
+
+#ifndef mozilla_embedding_PrintProgressDialogChild_h
+#define mozilla_embedding_PrintProgressDialogChild_h
+
+#include "mozilla/embedding/PPrintProgressDialogChild.h"
+#include "nsIPrintSettings.h"
+#include "nsIWebProgressListener.h"
+
+class nsIObserver;
+
+namespace mozilla {
+namespace embedding {
+
+class PrintProgressDialogChild final : public PPrintProgressDialogChild,
+ public nsIWebProgressListener,
+ public nsIPrintProgressParams {
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEBPROGRESSLISTENER
+ NS_DECL_NSIPRINTPROGRESSPARAMS
+
+ public:
+ MOZ_IMPLICIT PrintProgressDialogChild(nsIObserver* aOpenObserver,
+ nsIPrintSettings* aPrintSettings);
+
+ virtual mozilla::ipc::IPCResult RecvDialogOpened() override;
+
+ virtual mozilla::ipc::IPCResult RecvCancelledCurrentJob() override;
+
+ private:
+ virtual ~PrintProgressDialogChild();
+ nsCOMPtr<nsIObserver> mOpenObserver;
+ nsString mDocTitle;
+ nsString mDocURL;
+ nsCOMPtr<nsIPrintSettings> mPrintSettings;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp b/toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp
new file mode 100644
index 0000000000..fcc463808b
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintProgressDialogParent.cpp
@@ -0,0 +1,111 @@
+/* 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 "mozilla/Unused.h"
+#include "nsIWebProgressListener.h"
+#include "PrintProgressDialogParent.h"
+
+using mozilla::Unused;
+
+namespace mozilla {
+namespace embedding {
+
+NS_IMPL_ISUPPORTS(PrintProgressDialogParent, nsIObserver)
+
+PrintProgressDialogParent::PrintProgressDialogParent() : mActive(true) {}
+
+PrintProgressDialogParent::~PrintProgressDialogParent() = default;
+
+void PrintProgressDialogParent::SetWebProgressListener(
+ nsIWebProgressListener* aListener) {
+ mWebProgressListener = aListener;
+}
+
+void PrintProgressDialogParent::SetPrintProgressParams(
+ nsIPrintProgressParams* aParams) {
+ mPrintProgressParams = aParams;
+}
+
+mozilla::ipc::IPCResult PrintProgressDialogParent::RecvStateChange(
+ const long& stateFlags, const nsresult& status) {
+ if (mWebProgressListener) {
+ mWebProgressListener->OnStateChange(nullptr, nullptr, stateFlags, status);
+ }
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult PrintProgressDialogParent::RecvProgressChange(
+ const long& curSelfProgress, const long& maxSelfProgress,
+ const long& curTotalProgress, const long& maxTotalProgress) {
+ if (mWebProgressListener) {
+ mWebProgressListener->OnProgressChange(nullptr, nullptr, curSelfProgress,
+ maxSelfProgress, curTotalProgress,
+ maxTotalProgress);
+ }
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult PrintProgressDialogParent::RecvDocTitleChange(
+ const nsString& newTitle) {
+ if (mPrintProgressParams) {
+ mPrintProgressParams->SetDocTitle(newTitle);
+ }
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult PrintProgressDialogParent::RecvDocURLChange(
+ const nsString& newURL) {
+ if (mPrintProgressParams) {
+ mPrintProgressParams->SetDocURL(newURL);
+ }
+ return IPC_OK();
+}
+
+void PrintProgressDialogParent::ActorDestroy(ActorDestroyReason aWhy) {
+ // If IPC actor is destroyed, we can't send to child via IPC.
+ mActive = false;
+}
+
+mozilla::ipc::IPCResult PrintProgressDialogParent::Recv__delete__() {
+ // The child has requested that we tear down the connection, so we set a
+ // member to make sure we don't try to contact it after the fact.
+ mActive = false;
+ return IPC_OK();
+}
+
+// nsIObserver
+NS_IMETHODIMP
+PrintProgressDialogParent::Observe(nsISupports* aSubject, const char* aTopic,
+ const char16_t* aData) {
+ if (mActive) {
+ if (aTopic) {
+ if (!strcmp(aTopic, "cancelled")) {
+ Unused << SendCancelledCurrentJob();
+ if (!mDialogOpenedSent) {
+ // We haven't already called SendDialogOpened, so call it now or it
+ // might never get sent and block the child from new printing
+ // requests. Also set mActive to false because we don't want to send
+ // it twice and our PrintProgressDialogChild will get deleted anyway.
+ Unused << SendDialogOpened();
+ mActive = false;
+ }
+ } else if (!strcmp(aTopic, "completed")) {
+ // Once printing is complete don't send any messages to the child.
+ mActive = false;
+ }
+ } else {
+ Unused << SendDialogOpened();
+ mDialogOpenedSent = true;
+ }
+ } else {
+ NS_WARNING(
+ "The print progress dialog finished opening, but communications "
+ "with the child have been closed.");
+ }
+
+ return NS_OK;
+}
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PrintProgressDialogParent.h b/toolkit/components/printingui/ipc/PrintProgressDialogParent.h
new file mode 100644
index 0000000000..5995446aaf
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintProgressDialogParent.h
@@ -0,0 +1,57 @@
+/* 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/. */
+
+#ifndef mozilla_embedding_PrintProgressDialogParent_h
+#define mozilla_embedding_PrintProgressDialogParent_h
+
+#include "mozilla/embedding/PPrintProgressDialogParent.h"
+#include "nsIObserver.h"
+
+class nsIPrintProgressParams;
+class nsIWebProgressListener;
+
+namespace mozilla {
+namespace embedding {
+class PrintProgressDialogParent final : public PPrintProgressDialogParent,
+ public nsIObserver {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIOBSERVER
+
+ MOZ_IMPLICIT PrintProgressDialogParent();
+
+ void SetWebProgressListener(nsIWebProgressListener* aListener);
+
+ void SetPrintProgressParams(nsIPrintProgressParams* aParams);
+
+ virtual mozilla::ipc::IPCResult RecvStateChange(
+ const long& stateFlags, const nsresult& status) override;
+
+ virtual mozilla::ipc::IPCResult RecvProgressChange(
+ const long& curSelfProgress, const long& maxSelfProgress,
+ const long& curTotalProgress, const long& maxTotalProgress) override;
+
+ virtual mozilla::ipc::IPCResult RecvDocTitleChange(
+ const nsString& newTitle) override;
+
+ virtual mozilla::ipc::IPCResult RecvDocURLChange(
+ const nsString& newURL) override;
+
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ virtual mozilla::ipc::IPCResult Recv__delete__() override;
+
+ private:
+ virtual ~PrintProgressDialogParent();
+
+ nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
+ nsCOMPtr<nsIPrintProgressParams> mPrintProgressParams;
+ bool mActive;
+ bool mDialogOpenedSent = false;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/toolkit/components/printingui/ipc/PrintSettingsDialogChild.cpp b/toolkit/components/printingui/ipc/PrintSettingsDialogChild.cpp
new file mode 100644
index 0000000000..b6b1578950
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintSettingsDialogChild.cpp
@@ -0,0 +1,34 @@
+/* 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 "PrintSettingsDialogChild.h"
+
+using mozilla::Unused;
+
+namespace mozilla {
+namespace embedding {
+
+PrintSettingsDialogChild::PrintSettingsDialogChild() : mReturned(false) {
+ MOZ_COUNT_CTOR(PrintSettingsDialogChild);
+}
+
+PrintSettingsDialogChild::~PrintSettingsDialogChild() {
+ MOZ_COUNT_DTOR(PrintSettingsDialogChild);
+}
+
+mozilla::ipc::IPCResult PrintSettingsDialogChild::Recv__delete__(
+ const PrintDataOrNSResult& aData) {
+ if (aData.type() == PrintDataOrNSResult::Tnsresult) {
+ mResult = aData.get_nsresult();
+ MOZ_ASSERT(NS_FAILED(mResult), "expected a failure result");
+ } else {
+ mResult = NS_OK;
+ mData = aData.get_PrintData();
+ }
+ mReturned = true;
+ return IPC_OK();
+}
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PrintSettingsDialogChild.h b/toolkit/components/printingui/ipc/PrintSettingsDialogChild.h
new file mode 100644
index 0000000000..9666117eb1
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintSettingsDialogChild.h
@@ -0,0 +1,35 @@
+/* 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/. */
+
+#ifndef mozilla_embedding_PrintSettingsDialogChild_h
+#define mozilla_embedding_PrintSettingsDialogChild_h
+
+#include "mozilla/embedding/PPrintSettingsDialogChild.h"
+namespace mozilla {
+namespace embedding {
+
+class PrintSettingsDialogChild final : public PPrintSettingsDialogChild {
+ NS_INLINE_DECL_REFCOUNTING(PrintSettingsDialogChild)
+
+ public:
+ MOZ_IMPLICIT PrintSettingsDialogChild();
+
+ virtual mozilla::ipc::IPCResult Recv__delete__(
+ const PrintDataOrNSResult& aData) override;
+
+ bool returned() { return mReturned; };
+ nsresult result() { return mResult; };
+ PrintData data() { return mData; };
+
+ private:
+ virtual ~PrintSettingsDialogChild();
+ bool mReturned;
+ nsresult mResult;
+ PrintData mData;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/toolkit/components/printingui/ipc/PrintSettingsDialogParent.cpp b/toolkit/components/printingui/ipc/PrintSettingsDialogParent.cpp
new file mode 100644
index 0000000000..ae784fef12
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintSettingsDialogParent.cpp
@@ -0,0 +1,22 @@
+/* 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 "PrintSettingsDialogParent.h"
+
+// C++ file contents
+namespace mozilla {
+namespace embedding {
+
+PrintSettingsDialogParent::PrintSettingsDialogParent() {
+ MOZ_COUNT_CTOR(PrintSettingsDialogParent);
+}
+
+PrintSettingsDialogParent::~PrintSettingsDialogParent() {
+ MOZ_COUNT_DTOR(PrintSettingsDialogParent);
+}
+
+void PrintSettingsDialogParent::ActorDestroy(ActorDestroyReason aWhy) {}
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PrintSettingsDialogParent.h b/toolkit/components/printingui/ipc/PrintSettingsDialogParent.h
new file mode 100644
index 0000000000..8d4fa87067
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintSettingsDialogParent.h
@@ -0,0 +1,27 @@
+/* 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/. */
+
+#ifndef mozilla_embedding_PrintSettingsDialogParent_h
+#define mozilla_embedding_PrintSettingsDialogParent_h
+
+#include "mozilla/embedding/PPrintSettingsDialogParent.h"
+
+// Header file contents
+namespace mozilla {
+namespace embedding {
+
+class PrintSettingsDialogParent final : public PPrintSettingsDialogParent {
+ public:
+ virtual void ActorDestroy(ActorDestroyReason aWhy) override;
+
+ MOZ_IMPLICIT PrintSettingsDialogParent();
+
+ private:
+ virtual ~PrintSettingsDialogParent();
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/toolkit/components/printingui/ipc/PrintingParent.cpp b/toolkit/components/printingui/ipc/PrintingParent.cpp
new file mode 100644
index 0000000000..69a7e4006f
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintingParent.cpp
@@ -0,0 +1,307 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set ts=8 sts=2 et sw=2 tw=80: */
+/* 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 "mozilla/dom/Element.h"
+#include "mozilla/dom/BrowserParent.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Unused.h"
+#include "nsIContent.h"
+#include "mozilla/dom/Document.h"
+#include "nsIPrintingPromptService.h"
+#include "nsIPrintSettingsService.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIWebProgressListener.h"
+#include "PrintingParent.h"
+#include "PrintProgressDialogParent.h"
+#include "PrintSettingsDialogParent.h"
+#include "mozilla/layout/RemotePrintJobParent.h"
+#include "mozilla/StaticPrefs_print.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+using namespace mozilla::layout;
+
+namespace mozilla {
+namespace embedding {
+mozilla::ipc::IPCResult PrintingParent::RecvShowProgress(
+ PBrowserParent* parent, PPrintProgressDialogParent* printProgressDialog,
+ PRemotePrintJobParent* remotePrintJob, const bool& isForPrinting) {
+ bool notifyOnOpen = false;
+
+ nsCOMPtr<nsPIDOMWindowOuter> parentWin = DOMWindowFromBrowserParent(parent);
+ nsCOMPtr<nsIPrintingPromptService> pps(
+ do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
+
+ PrintProgressDialogParent* dialogParent =
+ static_cast<PrintProgressDialogParent*>(printProgressDialog);
+ nsCOMPtr<nsIObserver> observer = dialogParent;
+
+ nsCOMPtr<nsIWebProgressListener> printProgressListener;
+ nsCOMPtr<nsIPrintProgressParams> printProgressParams;
+
+ nsresult rv = NS_ERROR_INVALID_ARG;
+ if (parentWin && pps) {
+ rv = pps->ShowPrintProgressDialog(
+ parentWin, nullptr, observer, isForPrinting,
+ getter_AddRefs(printProgressListener),
+ getter_AddRefs(printProgressParams), &notifyOnOpen);
+ }
+
+ if (NS_SUCCEEDED(rv)) {
+ if (remotePrintJob) {
+ // If we have a RemotePrintJob use that as a more general forwarder for
+ // print progress listeners.
+ static_cast<RemotePrintJobParent*>(remotePrintJob)
+ ->RegisterListener(printProgressListener);
+ } else {
+ dialogParent->SetWebProgressListener(printProgressListener);
+ }
+
+ dialogParent->SetPrintProgressParams(printProgressParams);
+ }
+
+ // NOTE: If we aren't going to observe an event on our observer, we need to
+ // fake one. This takes the form of sending the SendDialogOpened message. This
+ // is safe because the child process proxy will always return `true` for
+ // notifyOnOpen, as the request will always be async when performed across
+ // process boundaries.
+ //
+ // We can pass nullptr for all of the arguments, as all consumers of this
+ // observer don't care about the subject, topic, or data.
+ //
+ // If notifyOnOpen is true, then the ShowProgress call will handle notifying
+ // our observer for us.
+ if (!notifyOnOpen) {
+ observer->Observe(nullptr, nullptr, nullptr);
+ }
+ return IPC_OK();
+}
+
+nsresult PrintingParent::ShowPrintDialog(PBrowserParent* aParent,
+ const PrintData& aData,
+ PrintData* aResult) {
+ // If aParent is null this call is just being used to get print settings from
+ // the printer for print preview.
+ bool isPrintPreview = !aParent;
+ nsCOMPtr<nsPIDOMWindowOuter> parentWin;
+ if (aParent) {
+ parentWin = DOMWindowFromBrowserParent(aParent);
+ if (!parentWin) {
+ return NS_ERROR_FAILURE;
+ }
+ }
+
+ nsCOMPtr<nsIPrintingPromptService> pps(
+ do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
+ if (!pps) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Use the existing RemotePrintJob and its settings, if we have one, to make
+ // sure they stay current.
+ RemotePrintJobParent* remotePrintJob =
+ static_cast<RemotePrintJobParent*>(aData.remotePrintJobParent());
+ nsCOMPtr<nsIPrintSettings> settings;
+ nsresult rv;
+ if (remotePrintJob) {
+ settings = remotePrintJob->GetPrintSettings();
+ } else {
+ rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ // We only want to use the print silently setting from the parent.
+ bool printSilently;
+ rv = settings->GetPrintSilent(&printSilently);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = settings->SetPrintSilent(printSilently);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsString printerName;
+ settings->GetPrinterName(printerName);
+#ifdef MOZ_X11
+ // Requesting the last-used printer name on Linux has been removed in the
+ // child, because it was causing a sandbox violation (see Bug 1329216). If no
+ // printer name is set at this point, use the print settings service to get
+ // the last-used printer name, unless we're printing to file.
+ bool printToFile = false;
+ MOZ_ALWAYS_SUCCEEDS(settings->GetPrintToFile(&printToFile));
+ if (!printToFile && printerName.IsEmpty()) {
+ mPrintSettingsSvc->GetLastUsedPrinterName(printerName);
+ settings->SetPrinterName(printerName);
+ }
+ mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings);
+#endif
+
+ // If this is for print preview or we are printing silently then we just need
+ // to initialize the print settings with anything specific from the printer.
+ if (isPrintPreview || printSilently ||
+ StaticPrefs::print_always_print_silent()) {
+ settings->SetIsInitializedFromPrinter(false);
+ mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings);
+ } else {
+ rv = pps->ShowPrintDialog(parentWin, settings);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ if (isPrintPreview) {
+ // For print preview we don't want a RemotePrintJob just the settings.
+ rv = mPrintSettingsSvc->SerializeToPrintData(settings, aResult);
+ } else {
+ rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob,
+ aResult);
+ }
+
+ return rv;
+}
+
+mozilla::ipc::IPCResult PrintingParent::RecvShowPrintDialog(
+ PPrintSettingsDialogParent* aDialog, PBrowserParent* aParent,
+ const PrintData& aData) {
+ PrintData resultData;
+ nsresult rv = ShowPrintDialog(aParent, aData, &resultData);
+
+ // The child has been spinning an event loop while waiting
+ // to hear about the print settings. We return the results
+ // with an async message which frees the child process from
+ // its nested event loop.
+ if (NS_FAILED(rv)) {
+ mozilla::Unused
+ << PPrintingParent::PPrintSettingsDialogParent::Send__delete__(aDialog,
+ rv);
+ } else {
+ mozilla::Unused
+ << PPrintingParent::PPrintSettingsDialogParent::Send__delete__(
+ aDialog, resultData);
+ }
+ return IPC_OK();
+}
+
+mozilla::ipc::IPCResult PrintingParent::RecvSavePrintSettings(
+ const PrintData& aData, const bool& aUsePrinterNamePrefix,
+ const uint32_t& aFlags, nsresult* aResult) {
+ nsCOMPtr<nsIPrintSettings> settings;
+ *aResult = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(settings));
+ NS_ENSURE_SUCCESS(*aResult, IPC_OK());
+
+ *aResult = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
+ NS_ENSURE_SUCCESS(*aResult, IPC_OK());
+
+ *aResult = mPrintSettingsSvc->SavePrintSettingsToPrefs(
+ settings, aUsePrinterNamePrefix, aFlags);
+
+ return IPC_OK();
+}
+
+PPrintProgressDialogParent* PrintingParent::AllocPPrintProgressDialogParent() {
+ PrintProgressDialogParent* actor = new PrintProgressDialogParent();
+ NS_ADDREF(actor); // De-ref'd in the __delete__ handler for
+ // PrintProgressDialogParent.
+ return actor;
+}
+
+bool PrintingParent::DeallocPPrintProgressDialogParent(
+ PPrintProgressDialogParent* doomed) {
+ // We can't just delete the PrintProgressDialogParent since somebody might
+ // still be holding a reference to it as nsIObserver, so just decrement the
+ // refcount instead.
+ PrintProgressDialogParent* actor =
+ static_cast<PrintProgressDialogParent*>(doomed);
+ NS_RELEASE(actor);
+ return true;
+}
+
+PPrintSettingsDialogParent* PrintingParent::AllocPPrintSettingsDialogParent() {
+ return new PrintSettingsDialogParent();
+}
+
+bool PrintingParent::DeallocPPrintSettingsDialogParent(
+ PPrintSettingsDialogParent* aDoomed) {
+ delete aDoomed;
+ return true;
+}
+
+void PrintingParent::ActorDestroy(ActorDestroyReason aWhy) {}
+
+nsPIDOMWindowOuter* PrintingParent::DOMWindowFromBrowserParent(
+ PBrowserParent* parent) {
+ if (!parent) {
+ return nullptr;
+ }
+
+ BrowserParent* browserParent = BrowserParent::GetFrom(parent);
+ if (!browserParent) {
+ return nullptr;
+ }
+
+ nsCOMPtr<Element> frameElement = browserParent->GetOwnerElement();
+ if (!frameElement) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsIContent> frame(frameElement);
+ if (!frame) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsPIDOMWindowOuter> parentWin = frame->OwnerDoc()->GetWindow();
+ if (!parentWin) {
+ return nullptr;
+ }
+
+ return parentWin;
+}
+
+nsresult PrintingParent::SerializeAndEnsureRemotePrintJob(
+ nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aListener,
+ layout::RemotePrintJobParent* aRemotePrintJob, PrintData* aPrintData) {
+ MOZ_ASSERT(aPrintData);
+
+ nsresult rv;
+ nsCOMPtr<nsIPrintSettings> printSettings;
+ if (aPrintSettings) {
+ printSettings = aPrintSettings;
+ } else {
+ rv = mPrintSettingsSvc->GetNewPrintSettings(getter_AddRefs(printSettings));
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+ }
+
+ rv = mPrintSettingsSvc->SerializeToPrintData(printSettings, aPrintData);
+ if (NS_WARN_IF(NS_FAILED(rv))) {
+ return rv;
+ }
+
+ RemotePrintJobParent* remotePrintJob;
+ if (aRemotePrintJob) {
+ remotePrintJob = aRemotePrintJob;
+ aPrintData->remotePrintJobParent() = remotePrintJob;
+ } else {
+ remotePrintJob = new RemotePrintJobParent(aPrintSettings);
+ aPrintData->remotePrintJobParent() =
+ SendPRemotePrintJobConstructor(remotePrintJob);
+ }
+ if (aListener) {
+ remotePrintJob->RegisterListener(aListener);
+ }
+
+ return NS_OK;
+}
+
+PrintingParent::PrintingParent() {
+ mPrintSettingsSvc = do_GetService("@mozilla.org/gfx/printsettings-service;1");
+ MOZ_ASSERT(mPrintSettingsSvc);
+}
+
+PrintingParent::~PrintingParent() = default;
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/toolkit/components/printingui/ipc/PrintingParent.h b/toolkit/components/printingui/ipc/PrintingParent.h
new file mode 100644
index 0000000000..9e4ab9ff03
--- /dev/null
+++ b/toolkit/components/printingui/ipc/PrintingParent.h
@@ -0,0 +1,87 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* vim: set sw=2 ts=8 et tw=80 : */
+/* 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/. */
+
+#ifndef mozilla_embedding_PrintingParent_h
+#define mozilla_embedding_PrintingParent_h
+
+#include "mozilla/dom/PBrowserParent.h"
+#include "mozilla/embedding/PPrintingParent.h"
+
+class nsIPrintSettingsService;
+class nsIWebProgressListener;
+class nsPIDOMWindowOuter;
+class PPrintProgressDialogParent;
+class PPrintSettingsDialogParent;
+
+namespace mozilla {
+namespace layout {
+class PRemotePrintJobParent;
+class RemotePrintJobParent;
+} // namespace layout
+
+namespace embedding {
+
+class PrintingParent final : public PPrintingParent {
+ public:
+ NS_INLINE_DECL_REFCOUNTING(PrintingParent)
+
+ mozilla::ipc::IPCResult RecvShowProgress(
+ PBrowserParent* parent, PPrintProgressDialogParent* printProgressDialog,
+ PRemotePrintJobParent* remotePrintJob, const bool& isForPrinting) final;
+ mozilla::ipc::IPCResult RecvShowPrintDialog(
+ PPrintSettingsDialogParent* aDialog, PBrowserParent* aParent,
+ const PrintData& aData) final;
+
+ mozilla::ipc::IPCResult RecvSavePrintSettings(
+ const PrintData& data, const bool& usePrinterNamePrefix,
+ const uint32_t& flags, nsresult* rv) final;
+
+ PPrintProgressDialogParent* AllocPPrintProgressDialogParent() final;
+
+ bool DeallocPPrintProgressDialogParent(
+ PPrintProgressDialogParent* aActor) final;
+
+ PPrintSettingsDialogParent* AllocPPrintSettingsDialogParent() final;
+
+ bool DeallocPPrintSettingsDialogParent(
+ PPrintSettingsDialogParent* aActor) final;
+
+ void ActorDestroy(ActorDestroyReason aWhy) final;
+
+ MOZ_IMPLICIT PrintingParent();
+
+ /**
+ * Serialize nsIPrintSettings to PrintData ready for sending to a child
+ * process. A RemotePrintJob will be created and added to the PrintData.
+ * An optional progress listener can be given, which will be registered
+ * with the RemotePrintJob, so that progress can be tracked in the parent.
+ *
+ * @param aPrintSettings optional print settings to serialize, otherwise a
+ * default print settings will be used.
+ * @param aProgressListener optional print progress listener.
+ * @param aRemotePrintJob optional remote print job, so that an existing
+ * one can be used.
+ * @param aPrintData PrintData to populate.
+ */
+ nsresult SerializeAndEnsureRemotePrintJob(
+ nsIPrintSettings* aPrintSettings, nsIWebProgressListener* aListener,
+ layout::RemotePrintJobParent* aRemotePrintJob, PrintData* aPrintData);
+
+ private:
+ ~PrintingParent() final;
+
+ nsPIDOMWindowOuter* DOMWindowFromBrowserParent(PBrowserParent* parent);
+
+ nsresult ShowPrintDialog(PBrowserParent* parent, const PrintData& data,
+ PrintData* result);
+
+ nsCOMPtr<nsIPrintSettingsService> mPrintSettingsSvc;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/toolkit/components/printingui/ipc/moz.build b/toolkit/components/printingui/ipc/moz.build
new file mode 100644
index 0000000000..507bfc9d9d
--- /dev/null
+++ b/toolkit/components/printingui/ipc/moz.build
@@ -0,0 +1,34 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+EXPORTS += [
+ "nsPrintingProxy.h",
+]
+
+EXPORTS.mozilla.embedding.printingui += [
+ "PrintingParent.h",
+]
+
+if CONFIG["NS_PRINTING"]:
+ UNIFIED_SOURCES += [
+ "nsPrintingProxy.cpp",
+ "PrintingParent.cpp",
+ "PrintProgressDialogChild.cpp",
+ "PrintProgressDialogParent.cpp",
+ "PrintSettingsDialogChild.cpp",
+ "PrintSettingsDialogParent.cpp",
+ ]
+
+IPDL_SOURCES += [
+ "PPrinting.ipdl",
+ "PPrintingTypes.ipdlh",
+ "PPrintProgressDialog.ipdl",
+ "PPrintSettingsDialog.ipdl",
+]
+
+include("/ipc/chromium/chromium-config.mozbuild")
+
+FINAL_LIBRARY = "xul"
diff --git a/toolkit/components/printingui/ipc/nsPrintingProxy.cpp b/toolkit/components/printingui/ipc/nsPrintingProxy.cpp
new file mode 100644
index 0000000000..fdb1a9725a
--- /dev/null
+++ b/toolkit/components/printingui/ipc/nsPrintingProxy.cpp
@@ -0,0 +1,232 @@
+/* -*- Mode: C++; tab-width: 4; indent-tabs-mode: nil; c-basic-offset: 2 -*-
+ *
+ * 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/BrowserChild.h"
+#include "mozilla/layout/RemotePrintJobChild.h"
+#include "mozilla/SpinEventLoopUntil.h"
+#include "mozilla/Unused.h"
+#include "nsIDocShell.h"
+#include "nsIPrintingPromptService.h"
+#include "nsIPrintSession.h"
+#include "nsPIDOMWindow.h"
+#include "nsPrintSettingsService.h"
+#include "nsServiceManagerUtils.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() = default;
+
+nsPrintingProxy::~nsPrintingProxy() = default;
+
+/* 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,
+ nsIPrintSettings* printSettings) {
+ 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.
+ BrowserChild* pBrowser = nullptr;
+ if (parent) {
+ // Get the BrowserChild 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<nsIBrowserChild> tabchild = docShell->GetBrowserChild();
+ NS_ENSURE_STATE(tabchild);
+
+ pBrowser = static_cast<BrowserChild*>(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, &inSettings);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ nsCOMPtr<nsIPrintSession> session;
+ rv = printSettings->GetPrintSession(getter_AddRefs(session));
+ if (NS_SUCCEEDED(rv) && session) {
+ inSettings.remotePrintJobChild() = session->GetRemotePrintJob();
+ }
+
+ // 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);
+
+ SpinEventLoopUntil([&, dialog]() { return dialog->returned(); });
+
+ rv = dialog->result();
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ rv = printSettingsSvc->DeserializeToPrintSettings(dialog->data(),
+ printSettings);
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingProxy::ShowPrintProgressDialog(
+ mozIDOMWindowProxy* parent,
+ 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 BrowserChild 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<nsIBrowserChild> tabchild = docShell->GetBrowserChild();
+ BrowserChild* pBrowser = static_cast<BrowserChild*>(tabchild.get());
+
+ RefPtr<PrintProgressDialogChild> dialogChild =
+ new PrintProgressDialogChild(openDialogObserver, printSettings);
+
+ SendPPrintProgressDialogConstructor(dialogChild);
+
+ // Get the RemotePrintJob if we have one available.
+ RefPtr<RemotePrintJobChild> remotePrintJob;
+ if (printSettings) {
+ nsCOMPtr<nsIPrintSession> printSession;
+ nsresult rv = printSettings->GetPrintSession(getter_AddRefs(printSession));
+ if (NS_SUCCEEDED(rv) && printSession) {
+ remotePrintJob = printSession->GetRemotePrintJob();
+ }
+ }
+
+ // NOTE: We set notifyOnOpen to true unconditionally. If the parent process
+ // would get `false` for notifyOnOpen, then it will synthesize a notification
+ // which will be sent asynchronously down to the child.
+ *notifyOnOpen = true;
+ mozilla::Unused << SendShowProgress(pBrowser, dialogChild, remotePrintJob,
+ isForPrinting);
+
+ // 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::ShowPageSetupDialog(mozIDOMWindowProxy* parent,
+ 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, &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.
+ MOZ_ASSERT_UNREACHABLE(
+ "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.
+ MOZ_ASSERT_UNREACHABLE(
+ "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;
+}
+
+already_AddRefed<PRemotePrintJobChild>
+nsPrintingProxy::AllocPRemotePrintJobChild() {
+ RefPtr<RemotePrintJobChild> remotePrintJob = new RemotePrintJobChild();
+ return remotePrintJob.forget();
+}
diff --git a/toolkit/components/printingui/ipc/nsPrintingProxy.h b/toolkit/components/printingui/ipc/nsPrintingProxy.h
new file mode 100644
index 0000000000..ba99b35139
--- /dev/null
+++ b/toolkit/components/printingui/ipc/nsPrintingProxy.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef __nsPrintingProxy_h
+#define __nsPrintingProxy_h
+
+#include "nsIPrintingPromptService.h"
+#include "mozilla/embedding/PPrintingChild.h"
+
+namespace mozilla {
+namespace layout {
+class PRemotePrintJobChild;
+}
+} // namespace mozilla
+
+class nsPrintingProxy final : public nsIPrintingPromptService,
+ public mozilla::embedding::PPrintingChild {
+ friend class mozilla::embedding::PPrintingChild;
+
+ public:
+ static already_AddRefed<nsPrintingProxy> GetInstance();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPRINTINGPROMPTSERVICE
+
+ /**
+ * Used to proxy nsIPrintSettings.savePrintSettingsToPrefs calls to the
+ * parent process.
+ *
+ * @param aFlags - kInitSave* flags from nsIPrintSettings's to specify
+ * which settings to save.
+ */
+ nsresult SavePrintSettings(nsIPrintSettings* aPS, bool aUsePrinterNamePrefix,
+ uint32_t aFlags);
+
+ protected:
+ PPrintProgressDialogChild* AllocPPrintProgressDialogChild() final;
+
+ bool DeallocPPrintProgressDialogChild(
+ PPrintProgressDialogChild* aActor) final;
+
+ PPrintSettingsDialogChild* AllocPPrintSettingsDialogChild() final;
+
+ bool DeallocPPrintSettingsDialogChild(
+ PPrintSettingsDialogChild* aActor) final;
+
+ already_AddRefed<PRemotePrintJobChild> AllocPRemotePrintJobChild() final;
+
+ private:
+ nsPrintingProxy();
+
+ ~nsPrintingProxy() final;
+
+ nsresult Init();
+};
+
+#endif
diff --git a/toolkit/components/printingui/moz.build b/toolkit/components/printingui/moz.build
new file mode 100644
index 0000000000..babf5f1dec
--- /dev/null
+++ b/toolkit/components/printingui/moz.build
@@ -0,0 +1,22 @@
+# -*- Mode: python; indent-tabs-mode: nil; tab-width: 40 -*-
+# vim: set filetype=python:
+# 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/.
+
+with Files("**"):
+ BUG_COMPONENT = ("Toolkit", "Printing")
+
+DIRS += ["ipc"]
+
+if CONFIG["NS_PRINTING"]:
+ UNIFIED_SOURCES += [
+ "nsPrintingPromptService.cpp",
+ ]
+ if CONFIG["MOZ_WIDGET_TOOLKIT"] == "windows" or CONFIG["MOZ_PDF_PRINTING"]:
+ UNIFIED_SOURCES += [
+ "nsPrintProgress.cpp",
+ "nsPrintProgressParams.cpp",
+ ]
+
+FINAL_LIBRARY = "xul"
diff --git a/toolkit/components/printingui/nsPrintProgress.cpp b/toolkit/components/printingui/nsPrintProgress.cpp
new file mode 100644
index 0000000000..a85b866600
--- /dev/null
+++ b/toolkit/components/printingui/nsPrintProgress.cpp
@@ -0,0 +1,265 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "nsPrintProgress.h"
+
+#include "mozilla/dom/BrowsingContext.h"
+#include "nsArray.h"
+#include "nsIDocShell.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIPrintSettings.h"
+#include "nsIAppWindow.h"
+#include "nsXPCOM.h"
+#include "nsIObserver.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIComponentManager.h"
+#include "nsPIDOMWindow.h"
+#include "nsXULAppAPI.h"
+
+using mozilla::dom::BrowsingContext;
+
+NS_IMPL_ADDREF(nsPrintProgress)
+NS_IMPL_RELEASE(nsPrintProgress)
+
+NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintProgress)
+ NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
+ NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
+NS_INTERFACE_MAP_END
+
+nsPrintProgress::nsPrintProgress(nsIPrintSettings* aPrintSettings) {
+ m_closeProgress = false;
+ m_processCanceled = false;
+ m_pendingStateFlags = -1;
+ m_pendingStateValue = NS_OK;
+ m_PrintSetting = aPrintSettings;
+}
+
+nsPrintProgress::~nsPrintProgress() { (void)ReleaseListeners(); }
+
+NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(
+ mozIDOMWindowProxy* parent, const char* dialogURL, nsISupports* parameters,
+ nsIObserver* openDialogObserver, bool* notifyOnOpen) {
+ *notifyOnOpen = true;
+ m_observer = openDialogObserver;
+ nsresult rv = NS_ERROR_FAILURE;
+
+ if (m_dialog) return NS_ERROR_ALREADY_INITIALIZED;
+
+ if (!dialogURL || !*dialogURL) return NS_ERROR_INVALID_ARG;
+
+ if (parent) {
+ // Set up window.arguments[0]...
+ nsCOMPtr<nsIMutableArray> array = nsArray::Create();
+
+ nsCOMPtr<nsISupportsInterfacePointer> ifptr =
+ do_CreateInstance(NS_SUPPORTS_INTERFACE_POINTER_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ ifptr->SetData(static_cast<nsIPrintProgress*>(this));
+ ifptr->SetDataIID(&NS_GET_IID(nsIPrintProgress));
+
+ array->AppendElement(ifptr);
+
+ array->AppendElement(parameters);
+
+ // We will set the opener of the dialog to be the nsIDOMWindow for the
+ // browser XUL window itself, as opposed to the content. That way, the
+ // progress window has access to the opener.
+ nsCOMPtr<nsPIDOMWindowOuter> pParentWindow =
+ nsPIDOMWindowOuter::From(parent);
+ NS_ENSURE_STATE(pParentWindow);
+ nsCOMPtr<nsIDocShell> docShell = pParentWindow->GetDocShell();
+ NS_ENSURE_STATE(docShell);
+
+ nsCOMPtr<nsIDocShellTreeOwner> owner;
+ docShell->GetTreeOwner(getter_AddRefs(owner));
+
+ nsCOMPtr<nsIAppWindow> ownerAppWindow = do_GetInterface(owner);
+ nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerAppWindow);
+ NS_ENSURE_STATE(ownerWindow);
+
+ nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow =
+ nsPIDOMWindowOuter::From(ownerWindow);
+
+ // Open the dialog.
+ RefPtr<BrowsingContext> newBC;
+
+ rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
+ u"_blank"_ns,
+ u"chrome,titlebar,dependent,centerscreen"_ns,
+ array, getter_AddRefs(newBC));
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose) {
+ m_closeProgress = true;
+ // XXX Invalid cast of bool to nsresult (bug 778106)
+ return OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP,
+ (nsresult)forceClose);
+}
+
+NS_IMETHODIMP nsPrintProgress::GetPrompter(nsIPrompt** _retval) {
+ NS_ENSURE_ARG_POINTER(_retval);
+ *_retval = nullptr;
+
+ if (!m_closeProgress && m_dialog) {
+ nsCOMPtr<nsPIDOMWindowOuter> window = do_QueryInterface(m_dialog);
+ MOZ_ASSERT(window);
+ return window->GetPrompter(_retval);
+ }
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP nsPrintProgress::GetProcessCanceledByUser(
+ bool* aProcessCanceledByUser) {
+ NS_ENSURE_ARG_POINTER(aProcessCanceledByUser);
+ *aProcessCanceledByUser = m_processCanceled;
+ return NS_OK;
+}
+NS_IMETHODIMP nsPrintProgress::SetProcessCanceledByUser(
+ bool aProcessCanceledByUser) {
+ if (XRE_IsE10sParentProcess()) {
+ MOZ_ASSERT(m_observer);
+ m_observer->Observe(nullptr, "cancelled", nullptr);
+ }
+ if (m_PrintSetting) m_PrintSetting->SetIsCancelled(true);
+ m_processCanceled = aProcessCanceledByUser;
+ OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP, NS_OK);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::RegisterListener(
+ nsIWebProgressListener* listener) {
+ if (!listener) // Nothing to do with a null listener!
+ return NS_OK;
+
+ m_listenerList.AppendObject(listener);
+ if (m_closeProgress || m_processCanceled)
+ listener->OnStateChange(nullptr, nullptr,
+ nsIWebProgressListener::STATE_STOP, NS_OK);
+ else {
+ listener->OnStatusChange(nullptr, nullptr, NS_OK, m_pendingStatus.get());
+ if (m_pendingStateFlags != -1)
+ listener->OnStateChange(nullptr, nullptr, m_pendingStateFlags,
+ m_pendingStateValue);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::UnregisterListener(
+ nsIWebProgressListener* listener) {
+ if (listener) m_listenerList.RemoveObject(listener);
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::DoneIniting() {
+ if (m_observer) {
+ m_observer->Observe(nullptr, nullptr, nullptr);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::OnStateChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ uint32_t aStateFlags,
+ nsresult aStatus) {
+ if (XRE_IsE10sParentProcess() &&
+ aStateFlags & nsIWebProgressListener::STATE_STOP) {
+ // If we're in an e10s parent, m_observer is a PrintProgressDialogParent,
+ // so we let it know that printing has completed, because it might mean that
+ // its PrintProgressDialogChild has already been deleted.
+ m_observer->Observe(nullptr, "completed", nullptr);
+ }
+
+ m_pendingStateFlags = aStateFlags;
+ m_pendingStateValue = aStatus;
+
+ uint32_t count = m_listenerList.Count();
+ for (uint32_t i = count - 1; i < count; i--) {
+ nsCOMPtr<nsIWebProgressListener> progressListener =
+ m_listenerList.SafeObjectAt(i);
+ if (progressListener)
+ progressListener->OnStateChange(aWebProgress, aRequest, aStateFlags,
+ aStatus);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::OnProgressChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ int32_t aCurSelfProgress,
+ int32_t aMaxSelfProgress,
+ int32_t aCurTotalProgress,
+ int32_t aMaxTotalProgress) {
+ if (XRE_IsE10sParentProcess() && aCurSelfProgress &&
+ aCurSelfProgress >= aMaxSelfProgress) {
+ // If we're in an e10s parent, m_observer is a PrintProgressDialogParent,
+ // so we let it know that printing has completed, because it might mean that
+ // its PrintProgressDialogChild has already been deleted.
+ m_observer->Observe(nullptr, "completed", nullptr);
+ }
+
+ uint32_t count = m_listenerList.Count();
+ for (uint32_t i = count - 1; i < count; i--) {
+ nsCOMPtr<nsIWebProgressListener> progressListener =
+ m_listenerList.SafeObjectAt(i);
+ if (progressListener)
+ progressListener->OnProgressChange(aWebProgress, aRequest,
+ aCurSelfProgress, aMaxSelfProgress,
+ aCurTotalProgress, aMaxTotalProgress);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::OnLocationChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ nsIURI* location,
+ uint32_t aFlags) {
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::OnStatusChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ nsresult aStatus,
+ const char16_t* aMessage) {
+ if (aMessage && *aMessage) m_pendingStatus = aMessage;
+
+ uint32_t count = m_listenerList.Count();
+ for (uint32_t i = count - 1; i < count; i--) {
+ nsCOMPtr<nsIWebProgressListener> progressListener =
+ m_listenerList.SafeObjectAt(i);
+ if (progressListener)
+ progressListener->OnStatusChange(aWebProgress, aRequest, aStatus,
+ aMessage);
+ }
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::OnSecurityChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ uint32_t aState) {
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::OnContentBlockingEvent(
+ nsIWebProgress* aWebProgress, nsIRequest* aRequest, uint32_t aEvent) {
+ return NS_OK;
+}
+
+nsresult nsPrintProgress::ReleaseListeners() {
+ m_listenerList.Clear();
+
+ return NS_OK;
+}
diff --git a/toolkit/components/printingui/nsPrintProgress.h b/toolkit/components/printingui/nsPrintProgress.h
new file mode 100644
index 0000000000..81e89fbea1
--- /dev/null
+++ b/toolkit/components/printingui/nsPrintProgress.h
@@ -0,0 +1,44 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef __nsPrintProgress_h
+#define __nsPrintProgress_h
+
+#include "nsIPrintProgress.h"
+
+#include "nsCOMArray.h"
+#include "nsCOMPtr.h"
+#include "nsString.h"
+
+class nsIDOMWindow;
+class nsIObserver;
+class nsIPrintSettings;
+
+class nsPrintProgress : public nsIPrintProgress {
+ public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIPRINTPROGRESS
+ NS_DECL_NSIWEBPROGRESSLISTENER
+
+ explicit nsPrintProgress(nsIPrintSettings* aPrintSettings);
+
+ protected:
+ virtual ~nsPrintProgress();
+
+ private:
+ nsresult ReleaseListeners();
+
+ bool m_closeProgress;
+ bool m_processCanceled;
+ nsString m_pendingStatus;
+ int32_t m_pendingStateFlags;
+ nsresult m_pendingStateValue;
+ nsCOMPtr<nsIDOMWindow> m_dialog;
+ nsCOMArray<nsIWebProgressListener> m_listenerList;
+ nsCOMPtr<nsIObserver> m_observer;
+ nsCOMPtr<nsIPrintSettings> m_PrintSetting;
+};
+
+#endif
diff --git a/toolkit/components/printingui/nsPrintProgressParams.cpp b/toolkit/components/printingui/nsPrintProgressParams.cpp
new file mode 100644
index 0000000000..39086d49e7
--- /dev/null
+++ b/toolkit/components/printingui/nsPrintProgressParams.cpp
@@ -0,0 +1,37 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "nsPrintProgressParams.h"
+#include "nsReadableUtils.h"
+
+NS_IMPL_ISUPPORTS(nsPrintProgressParams, nsIPrintProgressParams)
+
+nsPrintProgressParams::nsPrintProgressParams() = default;
+
+nsPrintProgressParams::~nsPrintProgressParams() = default;
+
+NS_IMETHODIMP
+nsPrintProgressParams::GetDocTitle(nsAString& aDocTitle) {
+ aDocTitle = mDocTitle;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintProgressParams::SetDocTitle(const nsAString& aDocTitle) {
+ mDocTitle = aDocTitle;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintProgressParams::GetDocURL(nsAString& aDocURL) {
+ aDocURL = mDocURL;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintProgressParams::SetDocURL(const nsAString& aDocURL) {
+ mDocURL = aDocURL;
+ return NS_OK;
+}
diff --git a/toolkit/components/printingui/nsPrintProgressParams.h b/toolkit/components/printingui/nsPrintProgressParams.h
new file mode 100644
index 0000000000..fff8c077c5
--- /dev/null
+++ b/toolkit/components/printingui/nsPrintProgressParams.h
@@ -0,0 +1,27 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef __nsPrintProgressParams_h
+#define __nsPrintProgressParams_h
+
+#include "nsIPrintProgressParams.h"
+#include "nsString.h"
+
+class nsPrintProgressParams : public nsIPrintProgressParams {
+ public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPRINTPROGRESSPARAMS
+
+ nsPrintProgressParams();
+
+ protected:
+ virtual ~nsPrintProgressParams();
+
+ private:
+ nsString mDocTitle;
+ nsString mDocURL;
+};
+
+#endif
diff --git a/toolkit/components/printingui/nsPrintingPromptService.cpp b/toolkit/components/printingui/nsPrintingPromptService.cpp
new file mode 100644
index 0000000000..0ee201ca82
--- /dev/null
+++ b/toolkit/components/printingui/nsPrintingPromptService.cpp
@@ -0,0 +1,225 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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 "nsPrintingPromptService.h"
+
+#include "mozilla/ClearOnShutdown.h"
+#include "mozilla/RefPtr.h"
+#include "mozilla/StaticPtr.h"
+#include "nsISupportsUtils.h"
+#include "nsString.h"
+#include "nsIPrintDialogService.h"
+#include "nsPIDOMWindow.h"
+#include "nsServiceManagerUtils.h"
+#include "nsXULAppAPI.h"
+
+// Printing Progress Includes
+#if !defined(XP_MACOSX)
+# include "nsPrintProgress.h"
+# include "nsPrintProgressParams.h"
+
+static const char* kPrintProgressDialogURL =
+ "chrome://global/content/printProgress.xhtml";
+static const char* kPrtPrvProgressDialogURL =
+ "chrome://global/content/printPreviewProgress.xhtml";
+#endif
+
+using namespace mozilla;
+
+NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService,
+ nsIWebProgressListener)
+
+StaticRefPtr<nsPrintingPromptService> sSingleton;
+
+/* static */
+already_AddRefed<nsPrintingPromptService>
+nsPrintingPromptService::GetSingleton() {
+ MOZ_ASSERT(XRE_IsParentProcess(),
+ "The content process must use nsPrintingProxy");
+
+ if (!sSingleton) {
+ sSingleton = new nsPrintingPromptService();
+ sSingleton->Init();
+ ClearOnShutdown(&sSingleton);
+ }
+
+ return do_AddRef(sSingleton);
+}
+
+nsPrintingPromptService::nsPrintingPromptService() = default;
+
+nsPrintingPromptService::~nsPrintingPromptService() = default;
+
+nsresult nsPrintingPromptService::Init() {
+#if !defined(XP_MACOSX)
+ nsresult rv;
+ mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
+ return rv;
+#else
+ return NS_OK;
+#endif
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy* parent,
+ nsIPrintSettings* printSettings) {
+ NS_ENSURE_ARG(printSettings);
+
+ nsCOMPtr<nsIPrintDialogService> dlgPrint(
+ do_GetService(NS_PRINTDIALOGSERVICE_CONTRACTID));
+ if (dlgPrint)
+ return dlgPrint->Show(nsPIDOMWindowOuter::From(parent), printSettings);
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPrintProgressDialog(
+ mozIDOMWindowProxy* parent,
+ nsIPrintSettings* printSettings, // ok to be null
+ nsIObserver* openDialogObserver, // ok to be null
+ bool isForPrinting, nsIWebProgressListener** webProgressListener,
+ nsIPrintProgressParams** printProgressParams, bool* notifyOnOpen) {
+#if !defined(XP_MACOSX)
+ NS_ENSURE_ARG(webProgressListener);
+ NS_ENSURE_ARG(printProgressParams);
+ NS_ENSURE_ARG(notifyOnOpen);
+
+ *notifyOnOpen = false;
+ if (mPrintProgress) {
+ *webProgressListener = nullptr;
+ *printProgressParams = nullptr;
+ return NS_ERROR_FAILURE;
+ }
+
+ nsPrintProgress* prtProgress = new nsPrintProgress(printSettings);
+ mPrintProgress = prtProgress;
+ mWebProgressListener = prtProgress;
+
+ nsCOMPtr<nsIPrintProgressParams> prtProgressParams =
+ new nsPrintProgressParams();
+
+ nsCOMPtr<mozIDOMWindowProxy> parentWindow = parent;
+
+ if (mWatcher && !parentWindow) {
+ mWatcher->GetActiveWindow(getter_AddRefs(parentWindow));
+ }
+
+ if (parentWindow) {
+ mPrintProgress->OpenProgressDialog(
+ parentWindow,
+ isForPrinting ? kPrintProgressDialogURL : kPrtPrvProgressDialogURL,
+ prtProgressParams, openDialogObserver, notifyOnOpen);
+ }
+
+ prtProgressParams.forget(printProgressParams);
+ NS_ADDREF(*webProgressListener = this);
+
+ return NS_OK;
+#else
+ return NS_ERROR_NOT_IMPLEMENTED;
+#endif
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPageSetupDialog(mozIDOMWindowProxy* parent,
+ nsIPrintSettings* printSettings) {
+ NS_ENSURE_ARG(printSettings);
+
+ nsCOMPtr<nsIPrintDialogService> dlgPrint(
+ do_GetService(NS_PRINTDIALOGSERVICE_CONTRACTID));
+ if (dlgPrint)
+ return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent),
+ printSettings);
+
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnStateChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ uint32_t aStateFlags, nsresult aStatus) {
+#if !defined(XP_MACOSX)
+ if ((aStateFlags & STATE_STOP) && mWebProgressListener) {
+ mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags,
+ aStatus);
+ if (mPrintProgress) {
+ mPrintProgress->CloseProgressDialog(true);
+ }
+ mPrintProgress = nullptr;
+ mWebProgressListener = nullptr;
+ }
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnProgressChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ int32_t aCurSelfProgress,
+ int32_t aMaxSelfProgress,
+ int32_t aCurTotalProgress,
+ int32_t aMaxTotalProgress) {
+#if !defined(XP_MACOSX)
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnProgressChange(
+ aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress,
+ aCurTotalProgress, aMaxTotalProgress);
+ }
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnLocationChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ nsIURI* location, uint32_t aFlags) {
+#if !defined(XP_MACOSX)
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnLocationChange(aWebProgress, aRequest,
+ location, aFlags);
+ }
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnStatusChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest, nsresult aStatus,
+ const char16_t* aMessage) {
+#if !defined(XP_MACOSX)
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus,
+ aMessage);
+ }
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnSecurityChange(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ uint32_t aState) {
+#if !defined(XP_MACOSX)
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest,
+ aState);
+ }
+#endif
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnContentBlockingEvent(nsIWebProgress* aWebProgress,
+ nsIRequest* aRequest,
+ uint32_t aEvent) {
+#if !defined(XP_MACOSX)
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnContentBlockingEvent(aWebProgress, aRequest,
+ aEvent);
+ }
+#endif
+ return NS_OK;
+}
diff --git a/toolkit/components/printingui/nsPrintingPromptService.h b/toolkit/components/printingui/nsPrintingPromptService.h
new file mode 100644
index 0000000000..fa3504a5d1
--- /dev/null
+++ b/toolkit/components/printingui/nsPrintingPromptService.h
@@ -0,0 +1,54 @@
+/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
+/* 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/. */
+
+#ifndef __nsPrintingPromptService_h
+#define __nsPrintingPromptService_h
+
+// {E042570C-62DE-4bb6-A6E0-798E3C07B4DF}
+#define NS_PRINTINGPROMPTSERVICE_CID \
+ { \
+ 0xe042570c, 0x62de, 0x4bb6, { \
+ 0xa6, 0xe0, 0x79, 0x8e, 0x3c, 0x7, 0xb4, 0xdf \
+ } \
+ }
+#define NS_PRINTINGPROMPTSERVICE_CONTRACTID \
+ "@mozilla.org/embedcomp/printingprompt-service;1"
+
+#include "nsCOMPtr.h"
+#include "nsIPrintingPromptService.h"
+#include "nsIWindowWatcher.h"
+
+// Printing Progress Includes
+#include "nsIWebProgressListener.h"
+#if !defined(XP_MACOSX)
+# include "nsPrintProgress.h"
+
+class nsIDOMWindow;
+class nsIDialogParamBlock;
+#endif
+
+class nsPrintingPromptService final : public nsIPrintingPromptService,
+ public nsIWebProgressListener {
+ public:
+ static already_AddRefed<nsPrintingPromptService> GetSingleton();
+
+ NS_DECL_NSIPRINTINGPROMPTSERVICE
+ NS_DECL_NSIWEBPROGRESSLISTENER
+ NS_DECL_ISUPPORTS
+
+ protected:
+ nsPrintingPromptService();
+ virtual ~nsPrintingPromptService();
+ nsresult Init();
+
+ private:
+#if !defined(XP_MACOSX)
+ nsCOMPtr<nsIWindowWatcher> mWatcher;
+ nsCOMPtr<nsIPrintProgress> mPrintProgress;
+ nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
+#endif
+};
+
+#endif