summaryrefslogtreecommitdiffstats
path: root/embedding/components/printingui
diff options
context:
space:
mode:
authorMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
committerMatt A. Tobin <mattatobin@localhost.localdomain>2018-02-02 04:16:08 -0500
commit5f8de423f190bbb79a62f804151bc24824fa32d8 (patch)
tree10027f336435511475e392454359edea8e25895d /embedding/components/printingui
parent49ee0794b5d912db1f95dce6eb52d781dc210db5 (diff)
downloadUXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.gz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.lz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.tar.xz
UXP-5f8de423f190bbb79a62f804151bc24824fa32d8.zip
Add m-esr52 at 52.6.0
Diffstat (limited to 'embedding/components/printingui')
-rw-r--r--embedding/components/printingui/ipc/PPrintProgressDialog.ipdl35
-rw-r--r--embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl29
-rw-r--r--embedding/components/printingui/ipc/PPrinting.ipdl48
-rw-r--r--embedding/components/printingui/ipc/PPrintingTypes.ipdlh126
-rw-r--r--embedding/components/printingui/ipc/PrintDataUtils.cpp158
-rw-r--r--embedding/components/printingui/ipc/PrintDataUtils.h39
-rw-r--r--embedding/components/printingui/ipc/PrintProgressDialogChild.cpp132
-rw-r--r--embedding/components/printingui/ipc/PrintProgressDialogChild.h40
-rw-r--r--embedding/components/printingui/ipc/PrintProgressDialogParent.cpp113
-rw-r--r--embedding/components/printingui/ipc/PrintProgressDialogParent.h64
-rw-r--r--embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp38
-rw-r--r--embedding/components/printingui/ipc/PrintSettingsDialogChild.h35
-rw-r--r--embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp28
-rw-r--r--embedding/components/printingui/ipc/PrintSettingsDialogParent.h29
-rw-r--r--embedding/components/printingui/ipc/PrintingParent.cpp336
-rw-r--r--embedding/components/printingui/ipc/PrintingParent.h109
-rw-r--r--embedding/components/printingui/ipc/moz.build35
-rw-r--r--embedding/components/printingui/ipc/nsPrintingProxy.cpp269
-rw-r--r--embedding/components/printingui/ipc/nsPrintingProxy.h57
-rw-r--r--embedding/components/printingui/mac/moz.build16
-rw-r--r--embedding/components/printingui/mac/nsPrintProgress.cpp213
-rw-r--r--embedding/components/printingui/mac/nsPrintProgress.h44
-rw-r--r--embedding/components/printingui/mac/nsPrintProgressParams.cpp47
-rw-r--r--embedding/components/printingui/mac/nsPrintProgressParams.h28
-rw-r--r--embedding/components/printingui/mac/nsPrintingPromptService.h43
-rw-r--r--embedding/components/printingui/mac/nsPrintingPromptServiceX.mm128
-rw-r--r--embedding/components/printingui/moz.build17
-rw-r--r--embedding/components/printingui/unixshared/moz.build13
-rw-r--r--embedding/components/printingui/unixshared/nsPrintProgress.cpp267
-rw-r--r--embedding/components/printingui/unixshared/nsPrintProgress.h46
-rw-r--r--embedding/components/printingui/unixshared/nsPrintProgressParams.cpp47
-rw-r--r--embedding/components/printingui/unixshared/nsPrintProgressParams.h28
-rw-r--r--embedding/components/printingui/unixshared/nsPrintingPromptService.cpp298
-rw-r--r--embedding/components/printingui/unixshared/nsPrintingPromptService.h58
-rw-r--r--embedding/components/printingui/win/moz.build18
-rw-r--r--embedding/components/printingui/win/nsPrintDialogUtil.cpp854
-rw-r--r--embedding/components/printingui/win/nsPrintDialogUtil.h12
-rw-r--r--embedding/components/printingui/win/nsPrintProgress.cpp293
-rw-r--r--embedding/components/printingui/win/nsPrintProgress.h43
-rw-r--r--embedding/components/printingui/win/nsPrintProgressParams.cpp47
-rw-r--r--embedding/components/printingui/win/nsPrintProgressParams.h27
-rw-r--r--embedding/components/printingui/win/nsPrintingPromptService.cpp341
-rw-r--r--embedding/components/printingui/win/nsPrintingPromptService.h58
43 files changed, 4706 insertions, 0 deletions
diff --git a/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl b/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl
new file mode 100644
index 000000000..1da29ef87
--- /dev/null
+++ b/embedding/components/printingui/ipc/PPrintProgressDialog.ipdl
@@ -0,0 +1,35 @@
+/* -*- 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();
+};
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl b/embedding/components/printingui/ipc/PPrintSettingsDialog.ipdl
new file mode 100644
index 000000000..3e436892e
--- /dev/null
+++ b/embedding/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/embedding/components/printingui/ipc/PPrinting.ipdl b/embedding/components/printingui/ipc/PPrinting.ipdl
new file mode 100644
index 000000000..0b4a1cf64
--- /dev/null
+++ b/embedding/components/printingui/ipc/PPrinting.ipdl
@@ -0,0 +1,48 @@
+/* -*- 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:
+ sync ShowProgress(PBrowser browser,
+ PPrintProgressDialog printProgressDialog,
+ nullable PRemotePrintJob remotePrintJob,
+ bool isForPrinting)
+ returns(bool notifyOnOpen,
+ nsresult rv);
+
+ 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/embedding/components/printingui/ipc/PPrintingTypes.ipdlh b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh
new file mode 100644
index 000000000..084047baf
--- /dev/null
+++ b/embedding/components/printingui/ipc/PPrintingTypes.ipdlh
@@ -0,0 +1,126 @@
+/* -*- 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;
+ int32_t startPageRange;
+ int32_t endPageRange;
+ 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;
+ short printRange;
+ nsString title;
+ nsString docURL;
+ nsString headerStrLeft;
+ nsString headerStrCenter;
+ nsString headerStrRight;
+ nsString footerStrLeft;
+ nsString footerStrCenter;
+ nsString footerStrRight;
+
+ short howToEnableFrameUI;
+ bool isCancelled;
+ short printFrameTypeUsage;
+ short printFrameType;
+ bool printSilent;
+ bool shrinkToFit;
+ bool showPrintProgress;
+
+ nsString paperName;
+ short paperData;
+ double paperWidth;
+ double paperHeight;
+ short paperSizeUnit;
+ bool printReversed;
+ bool printInColor;
+ int32_t orientation;
+ int32_t numCopies;
+ nsString printerName;
+ bool printToFile;
+ nsString toFileName;
+ short outputFormat;
+ int32_t printPageDelay;
+ int32_t resolution;
+ int32_t duplex;
+ bool isInitializedFromPrinter;
+ bool isInitializedFromPrefs;
+ int32_t optionFlags;
+
+ /* Windows-specific things */
+ nsString driverName;
+ nsString deviceName;
+ double printableWidthInInches;
+ double printableHeightInInches;
+ bool isFramesetDocument;
+ bool isFramesetFrameSelected;
+ bool isIFrameSelected;
+ bool isRangeSelection;
+ 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;
+
+ /**
+ * OS X specific things.
+ */
+ nsString printJobName;
+ bool printAllPages;
+ bool mustCollate;
+ nsString disposition;
+ /** TODO: Is there an "unsigned short" primitive? **/
+ short pagesAcross;
+ short pagesDown;
+ double printTime;
+ bool detailedErrorReporting;
+ nsString faxNumber;
+ bool addHeaderAndFooter;
+ bool fileNameExtensionHidden;
+ /*
+ * Holds the scaling factor from the Print dialog when shrink
+ * to fit is not used. This is needed by the child when it
+ * isn't using remote printing. When shrink to fit is enabled
+ * (default), print dialog code ensures this value is 1.0.
+ */
+ float scalingFactor;
+ /*
+ * Scaling factor for converting from OS X native paper size
+ * units to inches.
+ */
+ float widthScale;
+ float heightScale;
+ double adjustedPaperWidth;
+ double adjustedPaperHeight;
+};
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/embedding/components/printingui/ipc/PrintDataUtils.cpp b/embedding/components/printingui/ipc/PrintDataUtils.cpp
new file mode 100644
index 000000000..30e2075b6
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintDataUtils.cpp
@@ -0,0 +1,158 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 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/. */
+
+#include "PrintDataUtils.h"
+#include "nsIPrintSettings.h"
+#include "nsIServiceManager.h"
+#include "nsIWebBrowserPrint.h"
+#include "nsXPIDLString.h"
+
+namespace mozilla {
+namespace embedding {
+
+/**
+ * MockWebBrowserPrint is a mostly useless implementation of nsIWebBrowserPrint,
+ * but wraps a PrintData so that it's able to return information to print
+ * settings dialogs that need an nsIWebBrowserPrint to interrogate.
+ */
+
+NS_IMPL_ISUPPORTS(MockWebBrowserPrint, nsIWebBrowserPrint);
+
+MockWebBrowserPrint::MockWebBrowserPrint(const PrintData &aData)
+ : mData(aData)
+{
+ MOZ_COUNT_CTOR(MockWebBrowserPrint);
+}
+
+MockWebBrowserPrint::~MockWebBrowserPrint()
+{
+ MOZ_COUNT_DTOR(MockWebBrowserPrint);
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetGlobalPrintSettings(nsIPrintSettings **aGlobalPrintSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetCurrentPrintSettings(nsIPrintSettings **aCurrentPrintSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetCurrentChildDOMWindow(mozIDOMWindowProxy **aCurrentPrintSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetDoingPrint(bool *aDoingPrint)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetDoingPrintPreview(bool *aDoingPrintPreview)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetIsFramesetDocument(bool *aIsFramesetDocument)
+{
+ *aIsFramesetDocument = mData.isFramesetDocument();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetIsFramesetFrameSelected(bool *aIsFramesetFrameSelected)
+{
+ *aIsFramesetFrameSelected = mData.isFramesetFrameSelected();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetIsIFrameSelected(bool *aIsIFrameSelected)
+{
+ *aIsIFrameSelected = mData.isIFrameSelected();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetIsRangeSelection(bool *aIsRangeSelection)
+{
+ *aIsRangeSelection = mData.isRangeSelection();
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::GetPrintPreviewNumPages(int32_t *aPrintPreviewNumPages)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::Print(nsIPrintSettings* aThePrintSettings,
+ nsIWebProgressListener* aWPListener)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::PrintPreview(nsIPrintSettings* aThePrintSettings,
+ mozIDOMWindowProxy* aChildDOMWin,
+ nsIWebProgressListener* aWPListener)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::PrintPreviewNavigate(int16_t aNavType,
+ int32_t aPageNum)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::Cancel()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::EnumerateDocumentNames(uint32_t* aCount,
+ char16_t*** aResult)
+{
+ *aCount = 0;
+ *aResult = nullptr;
+
+ if (mData.printJobName().IsEmpty()) {
+ return NS_OK;
+ }
+
+ // The only consumer that cares about this is the OS X printing
+ // dialog, and even then, it only cares about the first document
+ // name. That's why we only send a single document name through
+ // PrintData.
+ char16_t** array = (char16_t**) moz_xmalloc(sizeof(char16_t*));
+ array[0] = ToNewUnicode(mData.printJobName());
+
+ *aCount = 1;
+ *aResult = array;
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::ExitPrintPreview()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+} // namespace embedding
+} // namespace mozilla
+
diff --git a/embedding/components/printingui/ipc/PrintDataUtils.h b/embedding/components/printingui/ipc/PrintDataUtils.h
new file mode 100644
index 000000000..da313b2f3
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintDataUtils.h
@@ -0,0 +1,39 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 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_PrintDataUtils_h
+#define mozilla_embedding_PrintDataUtils_h
+
+#include "mozilla/embedding/PPrinting.h"
+#include "nsIWebBrowserPrint.h"
+
+/**
+ * nsIPrintSettings and nsIWebBrowserPrint information is sent back and forth
+ * across PPrinting via the PrintData struct. These are utilities for
+ * manipulating PrintData that can be used on either side of the communications
+ * channel.
+ */
+
+namespace mozilla {
+namespace embedding {
+
+class MockWebBrowserPrint final : public nsIWebBrowserPrint
+{
+public:
+ explicit MockWebBrowserPrint(const PrintData &aData);
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIWEBBROWSERPRINT
+
+private:
+ ~MockWebBrowserPrint();
+ PrintData mData;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/embedding/components/printingui/ipc/PrintProgressDialogChild.cpp b/embedding/components/printingui/ipc/PrintProgressDialogChild.cpp
new file mode 100644
index 000000000..a6dc5de4e
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintProgressDialogChild.cpp
@@ -0,0 +1,132 @@
+/* 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 "PrintProgressDialogChild.h"
+
+class nsIWebProgress;
+class nsIRequest;
+
+using mozilla::Unused;
+
+namespace mozilla {
+namespace embedding {
+
+NS_IMPL_ISUPPORTS(PrintProgressDialogChild,
+ nsIWebProgressListener,
+ nsIPrintProgressParams)
+
+PrintProgressDialogChild::PrintProgressDialogChild(
+ nsIObserver* aOpenObserver) :
+ mOpenObserver(aOpenObserver)
+{
+ MOZ_COUNT_CTOR(PrintProgressDialogChild);
+}
+
+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);
+ MOZ_COUNT_DTOR(PrintProgressDialogChild);
+}
+
+bool
+PrintProgressDialogChild::RecvDialogOpened()
+{
+ // nsPrintEngine'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 true;
+}
+
+// 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;
+}
+
+// nsIPrintProgressParams
+
+NS_IMETHODIMP PrintProgressDialogChild::GetDocTitle(char16_t* *aDocTitle)
+{
+ NS_ENSURE_ARG(aDocTitle);
+
+ *aDocTitle = ToNewUnicode(mDocTitle);
+ return NS_OK;
+}
+
+NS_IMETHODIMP PrintProgressDialogChild::SetDocTitle(const char16_t* aDocTitle)
+{
+ mDocTitle = aDocTitle;
+ Unused << SendDocTitleChange(nsString(aDocTitle));
+ return NS_OK;
+}
+
+NS_IMETHODIMP PrintProgressDialogChild::GetDocURL(char16_t **aDocURL)
+{
+ NS_ENSURE_ARG(aDocURL);
+
+ *aDocURL = ToNewUnicode(mDocURL);
+ return NS_OK;
+}
+
+NS_IMETHODIMP PrintProgressDialogChild::SetDocURL(const char16_t* aDocURL)
+{
+ mDocURL = aDocURL;
+ Unused << SendDocURLChange(nsString(aDocURL));
+ return NS_OK;
+}
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/embedding/components/printingui/ipc/PrintProgressDialogChild.h b/embedding/components/printingui/ipc/PrintProgressDialogChild.h
new file mode 100644
index 000000000..b0a7105d7
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintProgressDialogChild.h
@@ -0,0 +1,40 @@
+/* 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 "nsIPrintProgressParams.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);
+
+ virtual bool RecvDialogOpened() override;
+
+private:
+ virtual ~PrintProgressDialogChild();
+ nsCOMPtr<nsIObserver> mOpenObserver;
+ nsString mDocTitle;
+ nsString mDocURL;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/embedding/components/printingui/ipc/PrintProgressDialogParent.cpp b/embedding/components/printingui/ipc/PrintProgressDialogParent.cpp
new file mode 100644
index 000000000..6e34704ff
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintProgressDialogParent.cpp
@@ -0,0 +1,113 @@
+/* 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 "nsIPrintProgressParams.h"
+#include "nsIWebProgressListener.h"
+#include "PrintProgressDialogParent.h"
+
+using mozilla::Unused;
+
+namespace mozilla {
+namespace embedding {
+
+NS_IMPL_ISUPPORTS(PrintProgressDialogParent, nsIObserver)
+
+PrintProgressDialogParent::PrintProgressDialogParent() :
+ mActive(true)
+{
+ MOZ_COUNT_CTOR(PrintProgressDialogParent);
+}
+
+PrintProgressDialogParent::~PrintProgressDialogParent()
+{
+ MOZ_COUNT_DTOR(PrintProgressDialogParent);
+}
+
+void
+PrintProgressDialogParent::SetWebProgressListener(nsIWebProgressListener* aListener)
+{
+ mWebProgressListener = aListener;
+}
+
+void
+PrintProgressDialogParent::SetPrintProgressParams(nsIPrintProgressParams* aParams)
+{
+ mPrintProgressParams = aParams;
+}
+
+bool
+PrintProgressDialogParent::RecvStateChange(const long& stateFlags,
+ const nsresult& status)
+{
+ if (mWebProgressListener) {
+ mWebProgressListener->OnStateChange(nullptr, nullptr, stateFlags, status);
+ }
+ return true;
+}
+
+bool
+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 true;
+}
+
+bool
+PrintProgressDialogParent::RecvDocTitleChange(const nsString& newTitle)
+{
+ if (mPrintProgressParams) {
+ mPrintProgressParams->SetDocTitle(newTitle.get());
+ }
+ return true;
+}
+
+bool
+PrintProgressDialogParent::RecvDocURLChange(const nsString& newURL)
+{
+ if (mPrintProgressParams) {
+ mPrintProgressParams->SetDocURL(newURL.get());
+ }
+ return true;
+}
+
+void
+PrintProgressDialogParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+}
+
+bool
+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 true;
+}
+
+// nsIObserver
+NS_IMETHODIMP
+PrintProgressDialogParent::Observe(nsISupports *aSubject, const char *aTopic,
+ const char16_t *aData)
+{
+ if (mActive) {
+ Unused << SendDialogOpened();
+ } 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/embedding/components/printingui/ipc/PrintProgressDialogParent.h b/embedding/components/printingui/ipc/PrintProgressDialogParent.h
new file mode 100644
index 000000000..540609162
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintProgressDialogParent.h
@@ -0,0 +1,64 @@
+/* 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 bool
+ RecvStateChange(
+ const long& stateFlags,
+ const nsresult& status) override;
+
+ virtual bool
+ RecvProgressChange(
+ const long& curSelfProgress,
+ const long& maxSelfProgress,
+ const long& curTotalProgress,
+ const long& maxTotalProgress) override;
+
+ virtual bool
+ RecvDocTitleChange(const nsString& newTitle) override;
+
+ virtual bool
+ RecvDocURLChange(const nsString& newURL) override;
+
+ virtual void
+ ActorDestroy(ActorDestroyReason aWhy) override;
+
+ virtual bool
+ Recv__delete__() override;
+
+private:
+ virtual ~PrintProgressDialogParent();
+
+ nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
+ nsCOMPtr<nsIPrintProgressParams> mPrintProgressParams;
+ bool mActive;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp b/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp
new file mode 100644
index 000000000..ee9c5de59
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintSettingsDialogChild.cpp
@@ -0,0 +1,38 @@
+/* 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);
+}
+
+bool
+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 true;
+}
+
+} // namespace embedding
+} // namespace mozilla
diff --git a/embedding/components/printingui/ipc/PrintSettingsDialogChild.h b/embedding/components/printingui/ipc/PrintSettingsDialogChild.h
new file mode 100644
index 000000000..6db60e221
--- /dev/null
+++ b/embedding/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 bool 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/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp b/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp
new file mode 100644
index 000000000..016677d96
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintSettingsDialogParent.cpp
@@ -0,0 +1,28 @@
+/* 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/embedding/components/printingui/ipc/PrintSettingsDialogParent.h b/embedding/components/printingui/ipc/PrintSettingsDialogParent.h
new file mode 100644
index 000000000..e655903e7
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintSettingsDialogParent.h
@@ -0,0 +1,29 @@
+/* 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/embedding/components/printingui/ipc/PrintingParent.cpp b/embedding/components/printingui/ipc/PrintingParent.cpp
new file mode 100644
index 000000000..46469844a
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintingParent.cpp
@@ -0,0 +1,336 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* 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/TabParent.h"
+#include "mozilla/Preferences.h"
+#include "mozilla/Unused.h"
+#include "nsIContent.h"
+#include "nsIDocument.h"
+#include "nsIDOMWindow.h"
+#include "nsIPrintingPromptService.h"
+#include "nsIPrintProgressParams.h"
+#include "nsIPrintSettingsService.h"
+#include "nsIServiceManager.h"
+#include "nsServiceManagerUtils.h"
+#include "nsIWebProgressListener.h"
+#include "PrintingParent.h"
+#include "PrintDataUtils.h"
+#include "PrintProgressDialogParent.h"
+#include "PrintSettingsDialogParent.h"
+#include "mozilla/layout/RemotePrintJobParent.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+using namespace mozilla::layout;
+
+namespace mozilla {
+namespace embedding {
+bool
+PrintingParent::RecvShowProgress(PBrowserParent* parent,
+ PPrintProgressDialogParent* printProgressDialog,
+ PRemotePrintJobParent* remotePrintJob,
+ const bool& isForPrinting,
+ bool* notifyOnOpen,
+ nsresult* result)
+{
+ *result = NS_ERROR_FAILURE;
+ *notifyOnOpen = false;
+
+ nsCOMPtr<nsPIDOMWindowOuter> parentWin = DOMWindowFromBrowserParent(parent);
+ if (!parentWin) {
+ return true;
+ }
+
+ nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
+
+ if (!pps) {
+ return true;
+ }
+
+ PrintProgressDialogParent* dialogParent =
+ static_cast<PrintProgressDialogParent*>(printProgressDialog);
+ nsCOMPtr<nsIObserver> observer = do_QueryInterface(dialogParent);
+
+ nsCOMPtr<nsIWebProgressListener> printProgressListener;
+ nsCOMPtr<nsIPrintProgressParams> printProgressParams;
+
+ *result = pps->ShowProgress(parentWin, nullptr, nullptr, observer,
+ isForPrinting,
+ getter_AddRefs(printProgressListener),
+ getter_AddRefs(printProgressParams),
+ notifyOnOpen);
+ NS_ENSURE_SUCCESS(*result, true);
+
+ 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);
+
+ return true;
+}
+
+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;
+ }
+
+ // The initSettings we got can be wrapped using
+ // PrintDataUtils' MockWebBrowserPrint, which implements enough of
+ // nsIWebBrowserPrint to keep the dialogs happy.
+ nsCOMPtr<nsIWebBrowserPrint> wbp = new MockWebBrowserPrint(aData);
+
+ // 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);
+
+ // 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 ||
+ Preferences::GetBool("print.always_print_silent", printSilently)) {
+ nsXPIDLString printerName;
+ rv = settings->GetPrinterName(getter_Copies(printerName));
+ NS_ENSURE_SUCCESS(rv, rv);
+
+ settings->SetIsInitializedFromPrinter(false);
+ mPrintSettingsSvc->InitPrintSettingsFromPrinter(printerName, settings);
+ } else {
+ rv = pps->ShowPrintDialog(parentWin, wbp, settings);
+ NS_ENSURE_SUCCESS(rv, rv);
+ }
+
+ if (isPrintPreview) {
+ // For print preview we don't want a RemotePrintJob just the settings.
+ rv = mPrintSettingsSvc->SerializeToPrintData(settings, nullptr, aResult);
+ } else {
+ rv = SerializeAndEnsureRemotePrintJob(settings, nullptr, remotePrintJob,
+ aResult);
+ }
+
+ return rv;
+}
+
+bool
+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 << aDialog->Send__delete__(aDialog, rv);
+ } else {
+ mozilla::Unused << aDialog->Send__delete__(aDialog, resultData);
+ }
+ return true;
+}
+
+bool
+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, true);
+
+ *aResult = mPrintSettingsSvc->DeserializeToPrintSettings(aData, settings);
+ NS_ENSURE_SUCCESS(*aResult, true);
+
+ *aResult = mPrintSettingsSvc->SavePrintSettingsToPrefs(settings,
+ aUsePrinterNamePrefix,
+ aFlags);
+
+ return true;
+}
+
+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;
+}
+
+PRemotePrintJobParent*
+PrintingParent::AllocPRemotePrintJobParent()
+{
+ MOZ_ASSERT_UNREACHABLE("No default constructors for implementations.");
+ return nullptr;
+}
+
+bool
+PrintingParent::DeallocPRemotePrintJobParent(PRemotePrintJobParent* aDoomed)
+{
+ delete aDoomed;
+ return true;
+}
+
+void
+PrintingParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+}
+
+nsPIDOMWindowOuter*
+PrintingParent::DOMWindowFromBrowserParent(PBrowserParent* parent)
+{
+ if (!parent) {
+ return nullptr;
+ }
+
+ TabParent* tabParent = TabParent::GetFrom(parent);
+ if (!tabParent) {
+ return nullptr;
+ }
+
+ nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement();
+ if (!frameElement) {
+ return nullptr;
+ }
+
+ nsCOMPtr<nsIContent> frame(do_QueryInterface(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, nullptr,
+ 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()
+{
+ MOZ_COUNT_CTOR(PrintingParent);
+
+ mPrintSettingsSvc =
+ do_GetService("@mozilla.org/gfx/printsettings-service;1");
+ MOZ_ASSERT(mPrintSettingsSvc);
+}
+
+PrintingParent::~PrintingParent()
+{
+ MOZ_COUNT_DTOR(PrintingParent);
+}
+
+} // namespace embedding
+} // namespace mozilla
+
diff --git a/embedding/components/printingui/ipc/PrintingParent.h b/embedding/components/printingui/ipc/PrintingParent.h
new file mode 100644
index 000000000..66f87726c
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintingParent.h
@@ -0,0 +1,109 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: nil; c-basic-offset: 4 -*- */
+/* vim: set sw=4 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 embedding {
+
+class PrintingParent final : public PPrintingParent
+{
+public:
+ NS_INLINE_DECL_REFCOUNTING(PrintingParent)
+
+ virtual bool
+ RecvShowProgress(PBrowserParent* parent,
+ PPrintProgressDialogParent* printProgressDialog,
+ PRemotePrintJobParent* remotePrintJob,
+ const bool& isForPrinting,
+ bool* notifyOnOpen,
+ nsresult* result);
+ virtual bool
+ RecvShowPrintDialog(PPrintSettingsDialogParent* aDialog,
+ PBrowserParent* aParent,
+ const PrintData& aData);
+
+ virtual bool
+ RecvSavePrintSettings(const PrintData& data,
+ const bool& usePrinterNamePrefix,
+ const uint32_t& flags,
+ nsresult* rv);
+
+ virtual PPrintProgressDialogParent*
+ AllocPPrintProgressDialogParent();
+
+ virtual bool
+ DeallocPPrintProgressDialogParent(PPrintProgressDialogParent* aActor);
+
+ virtual PPrintSettingsDialogParent*
+ AllocPPrintSettingsDialogParent();
+
+ virtual bool
+ DeallocPPrintSettingsDialogParent(PPrintSettingsDialogParent* aActor);
+
+ virtual PRemotePrintJobParent*
+ AllocPRemotePrintJobParent();
+
+ virtual bool
+ DeallocPRemotePrintJobParent(PRemotePrintJobParent* aActor);
+
+ virtual void
+ ActorDestroy(ActorDestroyReason aWhy);
+
+ 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:
+ virtual ~PrintingParent();
+
+ nsPIDOMWindowOuter*
+ DOMWindowFromBrowserParent(PBrowserParent* parent);
+
+ nsresult
+ ShowPrintDialog(PBrowserParent* parent,
+ const PrintData& data,
+ PrintData* result);
+
+ nsCOMPtr<nsIPrintSettingsService> mPrintSettingsSvc;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
diff --git a/embedding/components/printingui/ipc/moz.build b/embedding/components/printingui/ipc/moz.build
new file mode 100644
index 000000000..29822e652
--- /dev/null
+++ b/embedding/components/printingui/ipc/moz.build
@@ -0,0 +1,35 @@
+# -*- 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',
+ 'PrintDataUtils.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/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;
+}
diff --git a/embedding/components/printingui/ipc/nsPrintingProxy.h b/embedding/components/printingui/ipc/nsPrintingProxy.h
new file mode 100644
index 000000000..6b4d9cf5a
--- /dev/null
+++ b/embedding/components/printingui/ipc/nsPrintingProxy.h
@@ -0,0 +1,57 @@
+/* -*- 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;
+}
+}
+
+class nsPrintingProxy: public nsIPrintingPromptService,
+ public mozilla::embedding::PPrintingChild
+{
+ virtual ~nsPrintingProxy();
+
+public:
+ nsPrintingProxy();
+
+ static already_AddRefed<nsPrintingProxy> GetInstance();
+
+ nsresult Init();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPRINTINGPROMPTSERVICE
+
+ nsresult SavePrintSettings(nsIPrintSettings* aPS,
+ bool aUsePrinterNamePrefix,
+ uint32_t aFlags);
+
+ virtual PPrintProgressDialogChild*
+ AllocPPrintProgressDialogChild() override;
+
+ virtual bool
+ DeallocPPrintProgressDialogChild(PPrintProgressDialogChild* aActor) override;
+
+ virtual PPrintSettingsDialogChild*
+ AllocPPrintSettingsDialogChild() override;
+
+ virtual bool
+ DeallocPPrintSettingsDialogChild(PPrintSettingsDialogChild* aActor) override;
+
+ virtual PRemotePrintJobChild*
+ AllocPRemotePrintJobChild() override;
+
+ virtual bool
+ DeallocPRemotePrintJobChild(PRemotePrintJobChild* aActor) override;
+};
+
+#endif
+
diff --git a/embedding/components/printingui/mac/moz.build b/embedding/components/printingui/mac/moz.build
new file mode 100644
index 000000000..aa3047c53
--- /dev/null
+++ b/embedding/components/printingui/mac/moz.build
@@ -0,0 +1,16 @@
+# -*- 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/.
+
+UNIFIED_SOURCES += [
+ 'nsPrintProgress.cpp',
+ 'nsPrintProgressParams.cpp',
+]
+
+SOURCES += [
+ 'nsPrintingPromptServiceX.mm',
+]
+
+FINAL_LIBRARY = 'xul'
diff --git a/embedding/components/printingui/mac/nsPrintProgress.cpp b/embedding/components/printingui/mac/nsPrintProgress.cpp
new file mode 100644
index 000000000..0ae0a63d9
--- /dev/null
+++ b/embedding/components/printingui/mac/nsPrintProgress.cpp
@@ -0,0 +1,213 @@
+/* -*- 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 "nsIBaseWindow.h"
+#include "nsXPCOM.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIComponentManager.h"
+#include "nsPIDOMWindow.h"
+
+NS_IMPL_ADDREF(nsPrintProgress)
+NS_IMPL_RELEASE(nsPrintProgress)
+
+NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback)
+ NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
+ NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback)
+ NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
+NS_INTERFACE_MAP_END_THREADSAFE
+
+
+nsPrintProgress::nsPrintProgress()
+{
+ m_closeProgress = false;
+ m_processCanceled = false;
+ m_pendingStateFlags = -1;
+ m_pendingStateValue = NS_OK;
+}
+
+nsPrintProgress::~nsPrintProgress()
+{
+ (void)ReleaseListeners();
+}
+
+NS_IMETHODIMP nsPrintProgress::OpenProgressDialog(mozIDOMWindowProxy *parent,
+ const char *dialogURL,
+ nsISupports *parameters,
+ nsIObserver *openDialogObserver,
+ bool *notifyOnOpen)
+{
+ MOZ_ASSERT_UNREACHABLE("The nsPrintingPromptService::ShowProgress "
+ "implementation for OS X returns "
+ "NS_ERROR_NOT_IMPLEMENTED, so we should never get "
+ "here.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose)
+{
+ MOZ_ASSERT_UNREACHABLE("The nsPrintingPromptService::ShowProgress "
+ "implementation for OS X returns "
+ "NS_ERROR_NOT_IMPLEMENTED, so we should never get "
+ "here.");
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+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)
+{
+ 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)
+{
+ 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)
+{
+ 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_OK;
+}
+
+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 state)
+{
+ return NS_OK;
+}
+
+nsresult nsPrintProgress::ReleaseListeners()
+{
+ m_listenerList.Clear();
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status)
+{
+ return OnStatusChange(nullptr, nullptr, NS_OK, status);
+}
+
+NS_IMETHODIMP nsPrintProgress::StartMeteors()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::StopMeteors()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell,
+ mozIDOMWindowProxy *window)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::CloseWindow()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
diff --git a/embedding/components/printingui/mac/nsPrintProgress.h b/embedding/components/printingui/mac/nsPrintProgress.h
new file mode 100644
index 000000000..938558c3e
--- /dev/null
+++ b/embedding/components/printingui/mac/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 "nsIPrintStatusFeedback.h"
+#include "nsIObserver.h"
+#include "nsString.h"
+
+class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback
+{
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIPRINTPROGRESS
+ NS_DECL_NSIWEBPROGRESSLISTENER
+ NS_DECL_NSIPRINTSTATUSFEEDBACK
+
+ nsPrintProgress();
+
+protected:
+ virtual ~nsPrintProgress();
+
+private:
+ nsresult ReleaseListeners();
+
+ bool m_closeProgress;
+ bool m_processCanceled;
+ nsString m_pendingStatus;
+ int32_t m_pendingStateFlags;
+ nsresult m_pendingStateValue;
+ // XXX This member is read-only.
+ nsCOMPtr<mozIDOMWindowProxy> m_dialog;
+ nsCOMArray<nsIWebProgressListener> m_listenerList;
+ nsCOMPtr<nsIObserver> m_observer;
+};
+
+#endif
diff --git a/embedding/components/printingui/mac/nsPrintProgressParams.cpp b/embedding/components/printingui/mac/nsPrintProgressParams.cpp
new file mode 100644
index 000000000..eba86b298
--- /dev/null
+++ b/embedding/components/printingui/mac/nsPrintProgressParams.cpp
@@ -0,0 +1,47 @@
+/* -*- 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()
+{
+}
+
+nsPrintProgressParams::~nsPrintProgressParams()
+{
+}
+
+NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle)
+{
+ NS_ENSURE_ARG(aDocTitle);
+
+ *aDocTitle = ToNewUnicode(mDocTitle);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle)
+{
+ mDocTitle = aDocTitle;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL)
+{
+ NS_ENSURE_ARG(aDocURL);
+
+ *aDocURL = ToNewUnicode(mDocURL);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL)
+{
+ mDocURL = aDocURL;
+ return NS_OK;
+}
+
diff --git a/embedding/components/printingui/mac/nsPrintProgressParams.h b/embedding/components/printingui/mac/nsPrintProgressParams.h
new file mode 100644
index 000000000..65c00d98f
--- /dev/null
+++ b/embedding/components/printingui/mac/nsPrintProgressParams.h
@@ -0,0 +1,28 @@
+/* -*- 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/embedding/components/printingui/mac/nsPrintingPromptService.h b/embedding/components/printingui/mac/nsPrintingPromptService.h
new file mode 100644
index 000000000..0334db223
--- /dev/null
+++ b/embedding/components/printingui/mac/nsPrintingPromptService.h
@@ -0,0 +1,43 @@
+/* -*- 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 "nsPIPromptService.h"
+#include "nsIWindowWatcher.h"
+
+// Printing Progress Includes
+#include "nsPrintProgress.h"
+#include "nsIWebProgressListener.h"
+
+class nsPrintingPromptService: public nsIPrintingPromptService,
+ public nsIWebProgressListener
+{
+public:
+ nsPrintingPromptService();
+
+ nsresult Init();
+
+ NS_DECL_NSIPRINTINGPROMPTSERVICE
+ NS_DECL_NSIWEBPROGRESSLISTENER
+ NS_DECL_ISUPPORTS
+
+protected:
+ virtual ~nsPrintingPromptService();
+
+private:
+ nsCOMPtr<nsIPrintProgress> mPrintProgress;
+};
+
+#endif
diff --git a/embedding/components/printingui/mac/nsPrintingPromptServiceX.mm b/embedding/components/printingui/mac/nsPrintingPromptServiceX.mm
new file mode 100644
index 000000000..3b956100b
--- /dev/null
+++ b/embedding/components/printingui/mac/nsPrintingPromptServiceX.mm
@@ -0,0 +1,128 @@
+/* -*- 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 "nsPrintingPromptService.h"
+
+#include "nsCOMPtr.h"
+#include "nsServiceManagerUtils.h"
+#include "nsObjCExceptions.h"
+
+#include "nsIPrintingPromptService.h"
+#include "nsIFactory.h"
+#include "nsIPrintDialogService.h"
+#include "nsPIDOMWindow.h"
+
+//*****************************************************************************
+// nsPrintingPromptService
+//*****************************************************************************
+
+NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
+
+nsPrintingPromptService::nsPrintingPromptService()
+{
+}
+
+nsPrintingPromptService::~nsPrintingPromptService()
+{
+}
+
+nsresult nsPrintingPromptService::Init()
+{
+ return NS_OK;
+}
+
+//*****************************************************************************
+// nsPrintingPromptService::nsIPrintingPromptService
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+
+ nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
+ NS_PRINTDIALOGSERVICE_CONTRACTID));
+ if (dlgPrint) {
+ return dlgPrint->Show(nsPIDOMWindowOuter::From(parent), printSettings,
+ webBrowserPrint);
+ }
+
+ return NS_ERROR_FAILURE;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::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)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
+{
+ NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
+ nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
+ NS_PRINTDIALOGSERVICE_CONTRACTID));
+ if (dlgPrint) {
+ return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent), printSettings);
+ }
+
+ return NS_ERROR_FAILURE;
+
+ NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, const char16_t *printerName, nsIPrintSettings *printSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+
+//*****************************************************************************
+// nsPrintingPromptService::nsIWebProgressListener
+//*****************************************************************************
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
+{
+ return NS_OK;
+}
+
+/* void onProgressChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in long aCurSelfProgress, in long aMaxSelfProgress, in long aCurTotalProgress, in long aMaxTotalProgress); */
+NS_IMETHODIMP
+nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
+{
+ return NS_OK;
+}
+
+/* void onLocationChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsIURI location, in unsigned long aFlags); */
+NS_IMETHODIMP
+nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
+{
+ return NS_OK;
+}
+
+/* void onStatusChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in nsresult aStatus, in wstring aMessage); */
+NS_IMETHODIMP
+nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
+{
+ return NS_OK;
+}
+
+/* void onSecurityChange (in nsIWebProgress aWebProgress, in nsIRequest aRequest, in unsigned long state); */
+NS_IMETHODIMP
+nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
+{
+ return NS_OK;
+}
diff --git a/embedding/components/printingui/moz.build b/embedding/components/printingui/moz.build
new file mode 100644
index 000000000..ea9ece413
--- /dev/null
+++ b/embedding/components/printingui/moz.build
@@ -0,0 +1,17 @@
+# -*- 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/.
+
+toolkit = CONFIG['MOZ_WIDGET_TOOLKIT']
+
+DIRS += ['ipc']
+
+if CONFIG['NS_PRINTING']:
+ if toolkit == 'windows':
+ DIRS += ['win']
+ elif toolkit == 'cocoa':
+ DIRS += ['mac']
+ elif CONFIG['MOZ_PDF_PRINTING']:
+ DIRS += ['unixshared']
diff --git a/embedding/components/printingui/unixshared/moz.build b/embedding/components/printingui/unixshared/moz.build
new file mode 100644
index 000000000..b204f402f
--- /dev/null
+++ b/embedding/components/printingui/unixshared/moz.build
@@ -0,0 +1,13 @@
+# -*- 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/.
+
+UNIFIED_SOURCES += [
+ 'nsPrintingPromptService.cpp',
+ 'nsPrintProgress.cpp',
+ 'nsPrintProgressParams.cpp',
+]
+
+FINAL_LIBRARY = 'xul'
diff --git a/embedding/components/printingui/unixshared/nsPrintProgress.cpp b/embedding/components/printingui/unixshared/nsPrintProgress.cpp
new file mode 100644
index 000000000..1a871c008
--- /dev/null
+++ b/embedding/components/printingui/unixshared/nsPrintProgress.cpp
@@ -0,0 +1,267 @@
+/* -*- 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 "nsArray.h"
+#include "nsIBaseWindow.h"
+#include "nsIDocShell.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIXULWindow.h"
+#include "nsXPCOM.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIComponentManager.h"
+#include "nsPIDOMWindow.h"
+
+
+NS_IMPL_ADDREF(nsPrintProgress)
+NS_IMPL_RELEASE(nsPrintProgress)
+
+NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback)
+ NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
+ NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback)
+ NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
+NS_INTERFACE_MAP_END_THREADSAFE
+
+
+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, /*weak =*/ false);
+
+ array->AppendElement(parameters, /*weak =*/ false);
+
+ // 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.
+ auto* pParentWindow = nsPIDOMWindowOuter::From(parent);
+ nsCOMPtr<nsIDocShell> docShell = pParentWindow->GetDocShell();
+ NS_ENSURE_STATE(docShell);
+
+ nsCOMPtr<nsIDocShellTreeOwner> owner;
+ docShell->GetTreeOwner(getter_AddRefs(owner));
+
+ nsCOMPtr<nsIXULWindow> ownerXULWindow = do_GetInterface(owner);
+ nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerXULWindow);
+ NS_ENSURE_STATE(ownerWindow);
+
+ nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow = nsPIDOMWindowOuter::From(ownerWindow);
+
+ // Open the dialog.
+ nsCOMPtr<nsPIDOMWindowOuter> newWindow;
+
+ rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
+ NS_LITERAL_STRING("_blank"),
+ NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
+ array, getter_AddRefs(newWindow));
+ }
+
+ 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(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)
+{
+ 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)
+{
+ 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 state)
+{
+ return NS_OK;
+}
+
+nsresult nsPrintProgress::ReleaseListeners()
+{
+ m_listenerList.Clear();
+
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status)
+{
+ return OnStatusChange(nullptr, nullptr, NS_OK, status);
+}
+
+NS_IMETHODIMP nsPrintProgress::StartMeteors()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::StopMeteors()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell, mozIDOMWindowProxy *window)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::CloseWindow()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
diff --git a/embedding/components/printingui/unixshared/nsPrintProgress.h b/embedding/components/printingui/unixshared/nsPrintProgress.h
new file mode 100644
index 000000000..5b60151c0
--- /dev/null
+++ b/embedding/components/printingui/unixshared/nsPrintProgress.h
@@ -0,0 +1,46 @@
+/* -*- 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 "nsIPrintingPromptService.h"
+
+#include "nsCOMArray.h"
+#include "nsCOMPtr.h"
+#include "nsIDOMWindow.h"
+#include "nsIPrintStatusFeedback.h"
+#include "nsIObserver.h"
+#include "nsString.h"
+
+class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback
+{
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIPRINTPROGRESS
+ NS_DECL_NSIWEBPROGRESSLISTENER
+ NS_DECL_NSIPRINTSTATUSFEEDBACK
+
+ 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/embedding/components/printingui/unixshared/nsPrintProgressParams.cpp b/embedding/components/printingui/unixshared/nsPrintProgressParams.cpp
new file mode 100644
index 000000000..eba86b298
--- /dev/null
+++ b/embedding/components/printingui/unixshared/nsPrintProgressParams.cpp
@@ -0,0 +1,47 @@
+/* -*- 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()
+{
+}
+
+nsPrintProgressParams::~nsPrintProgressParams()
+{
+}
+
+NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle)
+{
+ NS_ENSURE_ARG(aDocTitle);
+
+ *aDocTitle = ToNewUnicode(mDocTitle);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle)
+{
+ mDocTitle = aDocTitle;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL)
+{
+ NS_ENSURE_ARG(aDocURL);
+
+ *aDocURL = ToNewUnicode(mDocURL);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL)
+{
+ mDocURL = aDocURL;
+ return NS_OK;
+}
+
diff --git a/embedding/components/printingui/unixshared/nsPrintProgressParams.h b/embedding/components/printingui/unixshared/nsPrintProgressParams.h
new file mode 100644
index 000000000..839d0e08e
--- /dev/null
+++ b/embedding/components/printingui/unixshared/nsPrintProgressParams.h
@@ -0,0 +1,28 @@
+/* -*- 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/embedding/components/printingui/unixshared/nsPrintingPromptService.cpp b/embedding/components/printingui/unixshared/nsPrintingPromptService.cpp
new file mode 100644
index 000000000..fd10a4742
--- /dev/null
+++ b/embedding/components/printingui/unixshared/nsPrintingPromptService.cpp
@@ -0,0 +1,298 @@
+/* -*- Mode: C++; tab-width: 2; 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 "nsPrintingPromptService.h"
+
+#include "nsArray.h"
+#include "nsIComponentManager.h"
+#include "nsIDialogParamBlock.h"
+#include "nsIDOMWindow.h"
+#include "nsIServiceManager.h"
+#include "nsISupportsUtils.h"
+#include "nsString.h"
+#include "nsIPrintDialogService.h"
+
+// Printing Progress Includes
+#include "nsPrintProgress.h"
+#include "nsPrintProgressParams.h"
+
+static const char *kPrintDialogURL = "chrome://global/content/printdialog.xul";
+static const char *kPrintProgressDialogURL = "chrome://global/content/printProgress.xul";
+static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul";
+static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul";
+static const char *kPrinterPropertiesURL = "chrome://global/content/printjoboptions.xul";
+
+/****************************************************************
+ ************************* ParamBlock ***************************
+ ****************************************************************/
+
+class ParamBlock {
+
+public:
+ ParamBlock()
+ {
+ mBlock = 0;
+ }
+ ~ParamBlock()
+ {
+ NS_IF_RELEASE(mBlock);
+ }
+ nsresult Init() {
+ return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock);
+ }
+ nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; }
+ operator nsIDialogParamBlock * () const { return mBlock; }
+
+private:
+ nsIDialogParamBlock *mBlock;
+};
+
+/****************************************************************
+ ***************** nsPrintingPromptService **********************
+ ****************************************************************/
+
+NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
+
+nsPrintingPromptService::nsPrintingPromptService()
+{
+}
+
+nsPrintingPromptService::~nsPrintingPromptService()
+{
+}
+
+nsresult
+nsPrintingPromptService::Init()
+{
+ nsresult rv;
+ mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
+ return rv;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent,
+ nsIWebBrowserPrint *webBrowserPrint,
+ nsIPrintSettings *printSettings)
+{
+ NS_ENSURE_ARG(webBrowserPrint);
+ NS_ENSURE_ARG(printSettings);
+
+ // Try to access a component dialog
+ nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
+ NS_PRINTDIALOGSERVICE_CONTRACTID));
+ if (dlgPrint)
+ return dlgPrint->Show(nsPIDOMWindowOuter::From(parent),
+ printSettings, webBrowserPrint);
+
+ // Show the built-in dialog instead
+ ParamBlock block;
+ nsresult rv = block.Init();
+ if (NS_FAILED(rv))
+ return rv;
+
+ block->SetInt(0, 0);
+ return DoDialog(parent, block, webBrowserPrint, printSettings, kPrintDialogURL);
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::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(webProgressListener);
+ NS_ENSURE_ARG(printProgressParams);
+ NS_ENSURE_ARG(notifyOnOpen);
+
+ *notifyOnOpen = false;
+
+ 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;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent,
+ nsIPrintSettings *printSettings,
+ nsIObserver *aObs)
+{
+ NS_ENSURE_ARG(printSettings);
+
+ // Try to access a component dialog
+ nsCOMPtr<nsIPrintDialogService> dlgPrint(do_GetService(
+ NS_PRINTDIALOGSERVICE_CONTRACTID));
+ if (dlgPrint)
+ return dlgPrint->ShowPageSetup(nsPIDOMWindowOuter::From(parent),
+ printSettings);
+
+ ParamBlock block;
+ nsresult rv = block.Init();
+ if (NS_FAILED(rv))
+ return rv;
+
+ block->SetInt(0, 0);
+ return DoDialog(parent, block, nullptr, printSettings, kPageSetupDialogURL);
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent,
+ const char16_t *printerName,
+ nsIPrintSettings *printSettings)
+{
+ /* fixme: We simply ignore the |aPrinter| argument here
+ * We should get the supported printer attributes from the printer and
+ * populate the print job options dialog with these data instead of using
+ * the "default set" here.
+ * However, this requires changes on all platforms and is another big chunk
+ * of patches ... ;-(
+ */
+ NS_ENSURE_ARG(printerName);
+ NS_ENSURE_ARG(printSettings);
+
+ ParamBlock block;
+ nsresult rv = block.Init();
+ if (NS_FAILED(rv))
+ return rv;
+
+ block->SetInt(0, 0);
+ return DoDialog(parent, block, nullptr, printSettings, kPrinterPropertiesURL);
+
+}
+
+nsresult
+nsPrintingPromptService::DoDialog(mozIDOMWindowProxy *aParent,
+ nsIDialogParamBlock *aParamBlock,
+ nsIWebBrowserPrint *aWebBrowserPrint,
+ nsIPrintSettings* aPS,
+ const char *aChromeURL)
+{
+ NS_ENSURE_ARG(aParamBlock);
+ NS_ENSURE_ARG(aPS);
+ NS_ENSURE_ARG(aChromeURL);
+
+ if (!mWatcher)
+ return NS_ERROR_FAILURE;
+
+ // get a parent, if at all possible
+ // (though we'd rather this didn't fail, it's OK if it does. so there's
+ // no failure or null check.)
+ nsCOMPtr<mozIDOMWindowProxy> activeParent;
+ if (!aParent)
+ {
+ mWatcher->GetActiveWindow(getter_AddRefs(activeParent));
+ aParent = activeParent;
+ }
+
+ // create a nsIMutableArray of the parameters
+ // being passed to the window
+ nsCOMPtr<nsIMutableArray> array = nsArray::Create();
+
+ nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS));
+ NS_ASSERTION(psSupports, "PrintSettings must be a supports");
+ array->AppendElement(psSupports, /*weak =*/ false);
+
+ if (aWebBrowserPrint) {
+ nsCOMPtr<nsISupports> wbpSupports(do_QueryInterface(aWebBrowserPrint));
+ NS_ASSERTION(wbpSupports, "nsIWebBrowserPrint must be a supports");
+ array->AppendElement(wbpSupports, /*weak =*/ false);
+ }
+
+ nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock));
+ NS_ASSERTION(blkSupps, "IOBlk must be a supports");
+ array->AppendElement(blkSupps, /*weak =*/ false);
+
+ nsCOMPtr<mozIDOMWindowProxy> dialog;
+ nsresult rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank",
+ "centerscreen,chrome,modal,titlebar", array,
+ getter_AddRefs(dialog));
+
+ // if aWebBrowserPrint is not null then we are printing
+ // so we want to pass back NS_ERROR_ABORT on cancel
+ if (NS_SUCCEEDED(rv) && aWebBrowserPrint)
+ {
+ int32_t status;
+ aParamBlock->GetInt(0, &status);
+ return status == 0?NS_ERROR_ABORT:NS_OK;
+ }
+
+ return rv;
+}
+
+//////////////////////////////////////////////////////////////////////
+// nsIWebProgressListener
+//////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
+{
+ if ((aStateFlags & STATE_STOP) && mWebProgressListener) {
+ mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
+ if (mPrintProgress) {
+ mPrintProgress->CloseProgressDialog(true);
+ }
+ mPrintProgress = nullptr;
+ mWebProgressListener = nullptr;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
+{
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
+{
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
+{
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
+{
+ if (mWebProgressListener) {
+ return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, state);
+ }
+ return NS_OK;
+}
diff --git a/embedding/components/printingui/unixshared/nsPrintingPromptService.h b/embedding/components/printingui/unixshared/nsPrintingPromptService.h
new file mode 100644
index 000000000..cc0c76929
--- /dev/null
+++ b/embedding/components/printingui/unixshared/nsPrintingPromptService.h
@@ -0,0 +1,58 @@
+/* -*- 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 "nsPIPromptService.h"
+#include "nsIWindowWatcher.h"
+
+// Printing Progress Includes
+#include "nsPrintProgress.h"
+#include "nsPrintProgressParams.h"
+#include "nsIWebProgressListener.h"
+
+class nsIDOMWindow;
+class nsIDialogParamBlock;
+
+class nsPrintingPromptService: public nsIPrintingPromptService,
+ public nsIWebProgressListener
+{
+
+public:
+
+ nsPrintingPromptService();
+
+ nsresult Init();
+
+ NS_DECL_NSIPRINTINGPROMPTSERVICE
+ NS_DECL_NSIWEBPROGRESSLISTENER
+ NS_DECL_ISUPPORTS
+
+protected:
+ virtual ~nsPrintingPromptService();
+
+private:
+ nsresult DoDialog(mozIDOMWindowProxy *aParent,
+ nsIDialogParamBlock *aParamBlock,
+ nsIWebBrowserPrint *aWebBrowserPrint,
+ nsIPrintSettings* aPS,
+ const char *aChromeURL);
+
+ nsCOMPtr<nsIWindowWatcher> mWatcher;
+ nsCOMPtr<nsIPrintProgress> mPrintProgress;
+ nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
+};
+
+#endif
+
diff --git a/embedding/components/printingui/win/moz.build b/embedding/components/printingui/win/moz.build
new file mode 100644
index 000000000..fe7b11b2d
--- /dev/null
+++ b/embedding/components/printingui/win/moz.build
@@ -0,0 +1,18 @@
+# -*- 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/.
+
+UNIFIED_SOURCES += [
+ 'nsPrintDialogUtil.cpp',
+ 'nsPrintingPromptService.cpp',
+ 'nsPrintProgress.cpp',
+ 'nsPrintProgressParams.cpp',
+]
+
+EXPORTS += [
+ 'nsPrintDialogUtil.h',
+]
+
+FINAL_LIBRARY = 'xul'
diff --git a/embedding/components/printingui/win/nsPrintDialogUtil.cpp b/embedding/components/printingui/win/nsPrintDialogUtil.cpp
new file mode 100644
index 000000000..896c58e85
--- /dev/null
+++ b/embedding/components/printingui/win/nsPrintDialogUtil.cpp
@@ -0,0 +1,854 @@
+/* -*- 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/. */
+
+/* -------------------------------------------------------------------
+To Build This:
+
+ You need to add this to the the makefile.win in mozilla/dom/base:
+
+ .\$(OBJDIR)\nsFlyOwnPrintDialog.obj \
+
+
+ And this to the makefile.win in mozilla/content/build:
+
+WIN_LIBS= \
+ winspool.lib \
+ comctl32.lib \
+ comdlg32.lib
+
+---------------------------------------------------------------------- */
+
+#include "plstr.h"
+#include <windows.h>
+#include <tchar.h>
+
+#include <unknwn.h>
+#include <commdlg.h>
+
+#include "nsIWebBrowserPrint.h"
+#include "nsString.h"
+#include "nsIServiceManager.h"
+#include "nsReadableUtils.h"
+#include "nsIPrintSettings.h"
+#include "nsIPrintSettingsWin.h"
+#include "nsIPrinterEnumerator.h"
+
+#include "nsRect.h"
+
+#include "nsIPrefService.h"
+#include "nsIPrefBranch.h"
+
+#include "nsCRT.h"
+#include "prenv.h" /* for PR_GetEnv */
+
+#include <windows.h>
+#include <winspool.h>
+
+// For Localization
+#include "nsIStringBundle.h"
+
+// For NS_CopyUnicodeToNative
+#include "nsNativeCharsetUtils.h"
+
+// This is for extending the dialog
+#include <dlgs.h>
+
+#include "nsWindowsHelpers.h"
+#include "WinUtils.h"
+
+// Default labels for the radio buttons
+static const char* kAsLaidOutOnScreenStr = "As &laid out on the screen";
+static const char* kTheSelectedFrameStr = "The selected &frame";
+static const char* kEachFrameSeparately = "&Each frame separately";
+
+
+//-----------------------------------------------
+// Global Data
+//-----------------------------------------------
+// Identifies which new radio btn was cliked on
+static UINT gFrameSelectedRadioBtn = 0;
+
+// Indicates whether the native print dialog was successfully extended
+static bool gDialogWasExtended = false;
+
+#define PRINTDLG_PROPERTIES "chrome://global/locale/printdialog.properties"
+
+static HWND gParentWnd = nullptr;
+
+//----------------------------------------------------------------------------------
+// Return localized bundle for resource strings
+static nsresult
+GetLocalizedBundle(const char * aPropFileName, nsIStringBundle** aStrBundle)
+{
+ NS_ENSURE_ARG_POINTER(aPropFileName);
+ NS_ENSURE_ARG_POINTER(aStrBundle);
+
+ nsresult rv;
+ nsCOMPtr<nsIStringBundle> bundle;
+
+
+ // Create bundle
+ nsCOMPtr<nsIStringBundleService> stringService =
+ do_GetService(NS_STRINGBUNDLE_CONTRACTID, &rv);
+ if (NS_SUCCEEDED(rv) && stringService) {
+ rv = stringService->CreateBundle(aPropFileName, aStrBundle);
+ }
+
+ return rv;
+}
+
+//--------------------------------------------------------
+// Return localized string
+static nsresult
+GetLocalizedString(nsIStringBundle* aStrBundle, const char* aKey, nsString& oVal)
+{
+ NS_ENSURE_ARG_POINTER(aStrBundle);
+ NS_ENSURE_ARG_POINTER(aKey);
+
+ // Determine default label from string bundle
+ nsXPIDLString valUni;
+ nsAutoString key;
+ key.AssignWithConversion(aKey);
+ nsresult rv = aStrBundle->GetStringFromName(key.get(), getter_Copies(valUni));
+ if (NS_SUCCEEDED(rv) && valUni) {
+ oVal.Assign(valUni);
+ } else {
+ oVal.Truncate();
+ }
+ return rv;
+}
+
+//--------------------------------------------------------
+// Set a multi-byte string in the control
+static void SetTextOnWnd(HWND aControl, const nsString& aStr)
+{
+ nsAutoCString text;
+ if (NS_SUCCEEDED(NS_CopyUnicodeToNative(aStr, text))) {
+ ::SetWindowText(aControl, text.get());
+ }
+}
+
+//--------------------------------------------------------
+// Will get the control and localized string by "key"
+static void SetText(HWND aParent,
+ UINT aId,
+ nsIStringBundle* aStrBundle,
+ const char* aKey)
+{
+ HWND wnd = GetDlgItem (aParent, aId);
+ if (!wnd) {
+ return;
+ }
+ nsAutoString str;
+ nsresult rv = GetLocalizedString(aStrBundle, aKey, str);
+ if (NS_SUCCEEDED(rv)) {
+ SetTextOnWnd(wnd, str);
+ }
+}
+
+//--------------------------------------------------------
+static void SetRadio(HWND aParent,
+ UINT aId,
+ bool aIsSet,
+ bool isEnabled = true)
+{
+ HWND wnd = ::GetDlgItem (aParent, aId);
+ if (!wnd) {
+ return;
+ }
+ if (!isEnabled) {
+ ::EnableWindow(wnd, FALSE);
+ return;
+ }
+ ::EnableWindow(wnd, TRUE);
+ ::SendMessage(wnd, BM_SETCHECK, (WPARAM)aIsSet, (LPARAM)0);
+}
+
+//--------------------------------------------------------
+static void SetRadioOfGroup(HWND aDlg, int aRadId)
+{
+ int radioIds[] = {rad4, rad5, rad6};
+ int numRads = 3;
+
+ for (int i=0;i<numRads;i++) {
+ HWND radWnd = ::GetDlgItem(aDlg, radioIds[i]);
+ if (radWnd != nullptr) {
+ ::SendMessage(radWnd, BM_SETCHECK, (WPARAM)(radioIds[i] == aRadId), (LPARAM)0);
+ }
+ }
+}
+
+//--------------------------------------------------------
+typedef struct {
+ const char * mKeyStr;
+ long mKeyId;
+} PropKeyInfo;
+
+// These are the control ids used in the dialog and
+// defined by MS-Windows in commdlg.h
+static PropKeyInfo gAllPropKeys[] = {
+ {"printFramesTitleWindows", grp3},
+ {"asLaidOutWindows", rad4},
+ {"selectedFrameWindows", rad5},
+ {"separateFramesWindows", rad6},
+ {nullptr, 0}};
+
+//--------------------------------------------------------
+//--------------------------------------------------------
+//--------------------------------------------------------
+//--------------------------------------------------------
+// Get the absolute coords of the child windows relative
+// to its parent window
+static void GetLocalRect(HWND aWnd, RECT& aRect, HWND aParent)
+{
+ ::GetWindowRect(aWnd, &aRect);
+
+ // MapWindowPoints converts screen coordinates to client coordinates.
+ // It works correctly in both left-to-right and right-to-left windows.
+ ::MapWindowPoints(nullptr, aParent, (LPPOINT)&aRect, 2);
+}
+
+//--------------------------------------------------------
+// Show or Hide the control
+static void Show(HWND aWnd, bool bState)
+{
+ if (aWnd) {
+ ::ShowWindow(aWnd, bState?SW_SHOW:SW_HIDE);
+ }
+}
+
+//--------------------------------------------------------
+// Create a child window "control"
+static HWND CreateControl(LPCTSTR aType,
+ DWORD aStyle,
+ HINSTANCE aHInst,
+ HWND aHdlg,
+ int aId,
+ const nsAString& aStr,
+ const nsIntRect& aRect)
+{
+ nsAutoCString str;
+ if (NS_FAILED(NS_CopyUnicodeToNative(aStr, str)))
+ return nullptr;
+
+ HWND hWnd = ::CreateWindow (aType, str.get(),
+ WS_CHILD | WS_CLIPSIBLINGS | WS_VISIBLE | aStyle,
+ aRect.x, aRect.y, aRect.width, aRect.height,
+ (HWND)aHdlg, (HMENU)(intptr_t)aId,
+ aHInst, nullptr);
+ if (hWnd == nullptr) return nullptr;
+
+ // get the native font for the dialog and
+ // set it into the new control
+ HFONT hFont = (HFONT)::SendMessage(aHdlg, WM_GETFONT, (WPARAM)0, (LPARAM)0);
+ if (hFont != nullptr) {
+ ::SendMessage(hWnd, WM_SETFONT, (WPARAM) hFont, (LPARAM)0);
+ }
+ return hWnd;
+}
+
+//--------------------------------------------------------
+// Create a Radio Button
+static HWND CreateRadioBtn(HINSTANCE aHInst,
+ HWND aHdlg,
+ int aId,
+ const char* aStr,
+ const nsIntRect& aRect)
+{
+ nsString cStr;
+ cStr.AssignWithConversion(aStr);
+ return CreateControl("BUTTON", BS_RADIOBUTTON, aHInst, aHdlg, aId, cStr, aRect);
+}
+
+//--------------------------------------------------------
+// Create a Group Box
+static HWND CreateGroupBox(HINSTANCE aHInst,
+ HWND aHdlg,
+ int aId,
+ const nsAString& aStr,
+ const nsIntRect& aRect)
+{
+ return CreateControl("BUTTON", BS_GROUPBOX, aHInst, aHdlg, aId, aStr, aRect);
+}
+
+//--------------------------------------------------------
+// Localizes and initializes the radio buttons and group
+static void InitializeExtendedDialog(HWND hdlg, int16_t aHowToEnableFrameUI)
+{
+ MOZ_ASSERT(aHowToEnableFrameUI != nsIPrintSettings::kFrameEnableNone,
+ "should not be called");
+
+ // Localize the new controls in the print dialog
+ nsCOMPtr<nsIStringBundle> strBundle;
+ if (NS_SUCCEEDED(GetLocalizedBundle(PRINTDLG_PROPERTIES, getter_AddRefs(strBundle)))) {
+ int32_t i = 0;
+ while (gAllPropKeys[i].mKeyStr != nullptr) {
+ SetText(hdlg, gAllPropKeys[i].mKeyId, strBundle, gAllPropKeys[i].mKeyStr);
+ i++;
+ }
+ }
+
+ // Set up radio buttons
+ if (aHowToEnableFrameUI == nsIPrintSettings::kFrameEnableAll) {
+ SetRadio(hdlg, rad4, false);
+ SetRadio(hdlg, rad5, true);
+ SetRadio(hdlg, rad6, false);
+ // set default so user doesn't have to actually press on it
+ gFrameSelectedRadioBtn = rad5;
+
+ } else { // nsIPrintSettings::kFrameEnableAsIsAndEach
+ SetRadio(hdlg, rad4, false);
+ SetRadio(hdlg, rad5, false, false);
+ SetRadio(hdlg, rad6, true);
+ // set default so user doesn't have to actually press on it
+ gFrameSelectedRadioBtn = rad6;
+ }
+}
+
+
+//--------------------------------------------------------
+// Special Hook Procedure for handling the print dialog messages
+static UINT CALLBACK PrintHookProc(HWND hdlg, UINT uiMsg, WPARAM wParam, LPARAM lParam)
+{
+
+ if (uiMsg == WM_COMMAND) {
+ UINT id = LOWORD(wParam);
+ if (id == rad4 || id == rad5 || id == rad6) {
+ gFrameSelectedRadioBtn = id;
+ SetRadioOfGroup(hdlg, id);
+ }
+
+ } else if (uiMsg == WM_INITDIALOG) {
+ PRINTDLG * printDlg = (PRINTDLG *)lParam;
+ if (printDlg == nullptr) return 0L;
+
+ int16_t howToEnableFrameUI = (int16_t)printDlg->lCustData;
+ // don't add frame options if they would be disabled anyway
+ // because there are no frames
+ if (howToEnableFrameUI == nsIPrintSettings::kFrameEnableNone)
+ return TRUE;
+
+ HINSTANCE hInst = (HINSTANCE)::GetWindowLongPtr(hdlg, GWLP_HINSTANCE);
+ if (hInst == nullptr) return 0L;
+
+ // Start by getting the local rects of several of the controls
+ // so we can calculate where the new controls are
+ HWND wnd = ::GetDlgItem(hdlg, grp1);
+ if (wnd == nullptr) return 0L;
+ RECT dlgRect;
+ GetLocalRect(wnd, dlgRect, hdlg);
+
+ wnd = ::GetDlgItem(hdlg, rad1); // this is the top control "All"
+ if (wnd == nullptr) return 0L;
+ RECT rad1Rect;
+ GetLocalRect(wnd, rad1Rect, hdlg);
+
+ wnd = ::GetDlgItem(hdlg, rad2); // this is the bottom control "Selection"
+ if (wnd == nullptr) return 0L;
+ RECT rad2Rect;
+ GetLocalRect(wnd, rad2Rect, hdlg);
+
+ wnd = ::GetDlgItem(hdlg, rad3); // this is the middle control "Pages"
+ if (wnd == nullptr) return 0L;
+ RECT rad3Rect;
+ GetLocalRect(wnd, rad3Rect, hdlg);
+
+ HWND okWnd = ::GetDlgItem(hdlg, IDOK);
+ if (okWnd == nullptr) return 0L;
+ RECT okRect;
+ GetLocalRect(okWnd, okRect, hdlg);
+
+ wnd = ::GetDlgItem(hdlg, grp4); // this is the "Print range" groupbox
+ if (wnd == nullptr) return 0L;
+ RECT prtRect;
+ GetLocalRect(wnd, prtRect, hdlg);
+
+
+ // calculate various different "gaps" for layout purposes
+
+ int rbGap = rad3Rect.top - rad1Rect.bottom; // gap between radiobtns
+ int grpBotGap = dlgRect.bottom - rad2Rect.bottom; // gap from bottom rb to bottom of grpbox
+ int grpGap = dlgRect.top - prtRect.bottom ; // gap between group boxes
+ int top = dlgRect.bottom + grpGap;
+ int radHgt = rad1Rect.bottom - rad1Rect.top + 1; // top of new group box
+ int y = top+(rad1Rect.top-dlgRect.top); // starting pos of first radio
+ int rbWidth = dlgRect.right - rad1Rect.left - 5; // measure from rb left to the edge of the groupbox
+ // (5 is arbitrary)
+ nsIntRect rect;
+
+ // Create and position the radio buttons
+ //
+ // If any one control cannot be created then
+ // hide the others and bail out
+ //
+ rect.SetRect(rad1Rect.left, y, rbWidth,radHgt);
+ HWND rad4Wnd = CreateRadioBtn(hInst, hdlg, rad4, kAsLaidOutOnScreenStr, rect);
+ if (rad4Wnd == nullptr) return 0L;
+ y += radHgt + rbGap;
+
+ rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
+ HWND rad5Wnd = CreateRadioBtn(hInst, hdlg, rad5, kTheSelectedFrameStr, rect);
+ if (rad5Wnd == nullptr) {
+ Show(rad4Wnd, FALSE); // hide
+ return 0L;
+ }
+ y += radHgt + rbGap;
+
+ rect.SetRect(rad1Rect.left, y, rbWidth, radHgt);
+ HWND rad6Wnd = CreateRadioBtn(hInst, hdlg, rad6, kEachFrameSeparately, rect);
+ if (rad6Wnd == nullptr) {
+ Show(rad4Wnd, FALSE); // hide
+ Show(rad5Wnd, FALSE); // hide
+ return 0L;
+ }
+ y += radHgt + grpBotGap;
+
+ // Create and position the group box
+ rect.SetRect (dlgRect.left, top, dlgRect.right-dlgRect.left+1, y-top+1);
+ HWND grpBoxWnd = CreateGroupBox(hInst, hdlg, grp3, NS_LITERAL_STRING("Print Frame"), rect);
+ if (grpBoxWnd == nullptr) {
+ Show(rad4Wnd, FALSE); // hide
+ Show(rad5Wnd, FALSE); // hide
+ Show(rad6Wnd, FALSE); // hide
+ return 0L;
+ }
+
+ // Here we figure out the old height of the dlg
+ // then figure its gap from the old grpbx to the bottom
+ // then size the dlg
+ RECT pr, cr;
+ ::GetWindowRect(hdlg, &pr);
+ ::GetClientRect(hdlg, &cr);
+
+ int dlgHgt = (cr.bottom - cr.top) + 1;
+ int bottomGap = dlgHgt - okRect.bottom;
+ pr.bottom += (dlgRect.bottom-dlgRect.top) + grpGap + 1 - (dlgHgt-dlgRect.bottom) + bottomGap;
+
+ ::SetWindowPos(hdlg, nullptr, pr.left, pr.top, pr.right-pr.left+1, pr.bottom-pr.top+1,
+ SWP_NOMOVE|SWP_NOREDRAW|SWP_NOZORDER);
+
+ // figure out the new height of the dialog
+ ::GetClientRect(hdlg, &cr);
+ dlgHgt = (cr.bottom - cr.top) + 1;
+
+ // Reposition the OK and Cancel btns
+ int okHgt = okRect.bottom - okRect.top + 1;
+ ::SetWindowPos(okWnd, nullptr, okRect.left, dlgHgt-bottomGap-okHgt, 0, 0,
+ SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER);
+
+ HWND cancelWnd = ::GetDlgItem(hdlg, IDCANCEL);
+ if (cancelWnd == nullptr) return 0L;
+
+ RECT cancelRect;
+ GetLocalRect(cancelWnd, cancelRect, hdlg);
+ int cancelHgt = cancelRect.bottom - cancelRect.top + 1;
+ ::SetWindowPos(cancelWnd, nullptr, cancelRect.left, dlgHgt-bottomGap-cancelHgt, 0, 0,
+ SWP_NOSIZE|SWP_NOREDRAW|SWP_NOZORDER);
+
+ // localize and initialize the groupbox and radiobuttons
+ InitializeExtendedDialog(hdlg, howToEnableFrameUI);
+
+ // Looks like we were able to extend the dialog
+ gDialogWasExtended = true;
+ return TRUE;
+ }
+ return 0L;
+}
+
+//----------------------------------------------------------------------------------
+// Returns a Global Moveable Memory Handle to a DevMode
+// from the Printer by the name of aPrintName
+//
+// NOTE:
+// This function assumes that aPrintName has already been converted from
+// unicode
+//
+static nsReturnRef<nsHGLOBAL>
+CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName,
+ nsIPrintSettings* aPS)
+{
+ nsHPRINTER hPrinter = nullptr;
+ // const cast kludge for silly Win32 api's
+ LPWSTR printName = const_cast<wchar_t*>(static_cast<const wchar_t*>(aPrintName.get()));
+ BOOL status = ::OpenPrinterW(printName, &hPrinter, nullptr);
+ if (!status) {
+ return nsReturnRef<nsHGLOBAL>();
+ }
+
+ // Make sure hPrinter is closed on all paths
+ nsAutoPrinter autoPrinter(hPrinter);
+
+ // Get the buffer size
+ LONG needed = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, nullptr,
+ nullptr, 0);
+ if (needed < 0) {
+ return nsReturnRef<nsHGLOBAL>();
+ }
+
+ // Allocate a buffer of the correct size.
+ nsAutoDevMode newDevMode((LPDEVMODEW)::HeapAlloc(::GetProcessHeap(), HEAP_ZERO_MEMORY,
+ needed));
+ if (!newDevMode) {
+ return nsReturnRef<nsHGLOBAL>();
+ }
+
+ nsHGLOBAL hDevMode = ::GlobalAlloc(GHND, needed);
+ nsAutoGlobalMem globalDevMode(hDevMode);
+ if (!hDevMode) {
+ return nsReturnRef<nsHGLOBAL>();
+ }
+
+ LONG ret = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, newDevMode,
+ nullptr, DM_OUT_BUFFER);
+ if (ret != IDOK) {
+ return nsReturnRef<nsHGLOBAL>();
+ }
+
+ // Lock memory and copy contents from DEVMODE (current printer)
+ // to Global Memory DEVMODE
+ LPDEVMODEW devMode = (DEVMODEW *)::GlobalLock(hDevMode);
+ if (!devMode) {
+ return nsReturnRef<nsHGLOBAL>();
+ }
+
+ memcpy(devMode, newDevMode.get(), needed);
+ // Initialize values from the PrintSettings
+ nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aPS);
+ MOZ_ASSERT(psWin);
+ psWin->CopyToNative(devMode);
+
+ // Sets back the changes we made to the DevMode into the Printer Driver
+ ret = ::DocumentPropertiesW(gParentWnd, hPrinter, printName, devMode, devMode,
+ DM_IN_BUFFER | DM_OUT_BUFFER);
+ if (ret != IDOK) {
+ ::GlobalUnlock(hDevMode);
+ return nsReturnRef<nsHGLOBAL>();
+ }
+
+ ::GlobalUnlock(hDevMode);
+
+ return globalDevMode.out();
+}
+
+//------------------------------------------------------------------
+// helper
+static void GetDefaultPrinterNameFromGlobalPrinters(nsXPIDLString &printerName)
+{
+ nsCOMPtr<nsIPrinterEnumerator> prtEnum = do_GetService("@mozilla.org/gfx/printerenumerator;1");
+ if (prtEnum) {
+ prtEnum->GetDefaultPrinterName(getter_Copies(printerName));
+ }
+}
+
+// Determine whether we have a completely native dialog
+// or whether we cshould extend it
+static bool ShouldExtendPrintDialog()
+{
+ nsresult rv;
+ nsCOMPtr<nsIPrefService> prefs =
+ do_GetService(NS_PREFSERVICE_CONTRACTID, &rv);
+ NS_ENSURE_SUCCESS(rv, true);
+ nsCOMPtr<nsIPrefBranch> prefBranch;
+ rv = prefs->GetBranch(nullptr, getter_AddRefs(prefBranch));
+ NS_ENSURE_SUCCESS(rv, true);
+
+ bool result;
+ rv = prefBranch->GetBoolPref("print.extend_native_print_dialog", &result);
+ NS_ENSURE_SUCCESS(rv, true);
+ return result;
+}
+
+//------------------------------------------------------------------
+// Displays the native Print Dialog
+static nsresult
+ShowNativePrintDialog(HWND aHWnd,
+ nsIPrintSettings* aPrintSettings)
+{
+ //NS_ENSURE_ARG_POINTER(aHWnd);
+ NS_ENSURE_ARG_POINTER(aPrintSettings);
+
+ gDialogWasExtended = false;
+
+ // Get the Print Name to be used
+ nsXPIDLString printerName;
+ aPrintSettings->GetPrinterName(getter_Copies(printerName));
+
+ // If there is no name then use the default printer
+ if (printerName.IsEmpty()) {
+ GetDefaultPrinterNameFromGlobalPrinters(printerName);
+ } else {
+ HANDLE hPrinter = nullptr;
+ if(!::OpenPrinterW(const_cast<wchar_t*>(static_cast<const wchar_t*>(printerName.get())),
+ &hPrinter, nullptr)) {
+ // If the last used printer is not found, we should use default printer.
+ GetDefaultPrinterNameFromGlobalPrinters(printerName);
+ } else {
+ ::ClosePrinter(hPrinter);
+ }
+ }
+
+ // Now create a DEVNAMES struct so the the dialog is initialized correctly.
+
+ uint32_t len = printerName.Length();
+ nsHGLOBAL hDevNames = ::GlobalAlloc(GHND, sizeof(wchar_t) * (len + 1)
+ + sizeof(DEVNAMES));
+ nsAutoGlobalMem autoDevNames(hDevNames);
+ if (!hDevNames) {
+ return NS_ERROR_OUT_OF_MEMORY;
+ }
+
+ DEVNAMES* pDevNames = (DEVNAMES*)::GlobalLock(hDevNames);
+ if (!pDevNames) {
+ return NS_ERROR_FAILURE;
+ }
+ pDevNames->wDriverOffset = sizeof(DEVNAMES)/sizeof(wchar_t);
+ pDevNames->wDeviceOffset = sizeof(DEVNAMES)/sizeof(wchar_t);
+ pDevNames->wOutputOffset = sizeof(DEVNAMES)/sizeof(wchar_t)+len;
+ pDevNames->wDefault = 0;
+
+ memcpy(pDevNames+1, printerName, (len + 1) * sizeof(wchar_t));
+ ::GlobalUnlock(hDevNames);
+
+ // Create a Moveable Memory Object that holds a new DevMode
+ // from the Printer Name
+ // The PRINTDLG.hDevMode requires that it be a moveable memory object
+ // NOTE: autoDevMode is automatically freed when any error occurred
+ nsAutoGlobalMem autoDevMode(CreateGlobalDevModeAndInit(printerName, aPrintSettings));
+
+ // Prepare to Display the Print Dialog
+ PRINTDLGW prntdlg;
+ memset(&prntdlg, 0, sizeof(PRINTDLGW));
+
+ prntdlg.lStructSize = sizeof(prntdlg);
+ prntdlg.hwndOwner = aHWnd;
+ prntdlg.hDevMode = autoDevMode.get();
+ prntdlg.hDevNames = hDevNames;
+ prntdlg.hDC = nullptr;
+ prntdlg.Flags = PD_ALLPAGES | PD_RETURNIC |
+ PD_USEDEVMODECOPIESANDCOLLATE | PD_COLLATE;
+
+ // if there is a current selection then enable the "Selection" radio button
+ int16_t howToEnableFrameUI = nsIPrintSettings::kFrameEnableNone;
+ bool isOn;
+ aPrintSettings->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn);
+ if (!isOn) {
+ prntdlg.Flags |= PD_NOSELECTION;
+ }
+ aPrintSettings->GetHowToEnableFrameUI(&howToEnableFrameUI);
+
+ int32_t pg = 1;
+ aPrintSettings->GetStartPageRange(&pg);
+ prntdlg.nFromPage = pg;
+
+ aPrintSettings->GetEndPageRange(&pg);
+ prntdlg.nToPage = pg;
+
+ prntdlg.nMinPage = 1;
+ prntdlg.nMaxPage = 0xFFFF;
+ prntdlg.nCopies = 1;
+ prntdlg.lpfnSetupHook = nullptr;
+ prntdlg.lpSetupTemplateName = nullptr;
+ prntdlg.hPrintTemplate = nullptr;
+ prntdlg.hSetupTemplate = nullptr;
+
+ prntdlg.hInstance = nullptr;
+ prntdlg.lpPrintTemplateName = nullptr;
+
+ if (!ShouldExtendPrintDialog()) {
+ prntdlg.lCustData = 0;
+ prntdlg.lpfnPrintHook = nullptr;
+ } else {
+ // Set up print dialog "hook" procedure for extending the dialog
+ prntdlg.lCustData = (DWORD)howToEnableFrameUI;
+ prntdlg.lpfnPrintHook = (LPPRINTHOOKPROC)PrintHookProc;
+ prntdlg.Flags |= PD_ENABLEPRINTHOOK;
+ }
+
+ BOOL result;
+ {
+ mozilla::widget::WinUtils::AutoSystemDpiAware dpiAwareness;
+ result = ::PrintDlgW(&prntdlg);
+ }
+
+ if (TRUE == result) {
+ // check to make sure we don't have any nullptr pointers
+ NS_ENSURE_TRUE(aPrintSettings && prntdlg.hDevMode, NS_ERROR_FAILURE);
+
+ if (prntdlg.hDevNames == nullptr) {
+ return NS_ERROR_FAILURE;
+ }
+ // Lock the deviceNames and check for nullptr
+ DEVNAMES *devnames = (DEVNAMES *)::GlobalLock(prntdlg.hDevNames);
+ if (devnames == nullptr) {
+ return NS_ERROR_FAILURE;
+ }
+
+ char16_t* device = &(((char16_t *)devnames)[devnames->wDeviceOffset]);
+ char16_t* driver = &(((char16_t *)devnames)[devnames->wDriverOffset]);
+
+ // Check to see if the "Print To File" control is checked
+ // then take the name from devNames and set it in the PrintSettings
+ //
+ // NOTE:
+ // As per Microsoft SDK documentation the returned value offset from
+ // devnames->wOutputOffset is either "FILE:" or nullptr
+ // if the "Print To File" checkbox is checked it MUST be "FILE:"
+ // We assert as an extra safety check.
+ if (prntdlg.Flags & PD_PRINTTOFILE) {
+ char16ptr_t fileName = &(((wchar_t *)devnames)[devnames->wOutputOffset]);
+ NS_ASSERTION(wcscmp(fileName, L"FILE:") == 0, "FileName must be `FILE:`");
+ aPrintSettings->SetToFileName(fileName);
+ aPrintSettings->SetPrintToFile(true);
+ } else {
+ // clear "print to file" info
+ aPrintSettings->SetPrintToFile(false);
+ aPrintSettings->SetToFileName(nullptr);
+ }
+
+ nsCOMPtr<nsIPrintSettingsWin> psWin(do_QueryInterface(aPrintSettings));
+ if (!psWin) {
+ return NS_ERROR_FAILURE;
+ }
+
+ // Setup local Data members
+ psWin->SetDeviceName(device);
+ psWin->SetDriverName(driver);
+
+#if defined(DEBUG_rods) || defined(DEBUG_dcone)
+ wprintf(L"printer: driver %s, device %s flags: %d\n", driver, device, prntdlg.Flags);
+#endif
+ // fill the print options with the info from the dialog
+
+ aPrintSettings->SetPrinterName(device);
+
+ if (prntdlg.Flags & PD_SELECTION) {
+ aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSelection);
+
+ } else if (prntdlg.Flags & PD_PAGENUMS) {
+ aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeSpecifiedPageRange);
+ aPrintSettings->SetStartPageRange(prntdlg.nFromPage);
+ aPrintSettings->SetEndPageRange(prntdlg.nToPage);
+
+ } else { // (prntdlg.Flags & PD_ALLPAGES)
+ aPrintSettings->SetPrintRange(nsIPrintSettings::kRangeAllPages);
+ }
+
+ if (howToEnableFrameUI != nsIPrintSettings::kFrameEnableNone) {
+ // make sure the dialog got extended
+ if (gDialogWasExtended) {
+ // check to see about the frame radio buttons
+ switch (gFrameSelectedRadioBtn) {
+ case rad4:
+ aPrintSettings->SetPrintFrameType(nsIPrintSettings::kFramesAsIs);
+ break;
+ case rad5:
+ aPrintSettings->SetPrintFrameType(nsIPrintSettings::kSelectedFrame);
+ break;
+ case rad6:
+ aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
+ break;
+ } // switch
+ } else {
+ // if it didn't get extended then have it default to printing
+ // each frame separately
+ aPrintSettings->SetPrintFrameType(nsIPrintSettings::kEachFrameSep);
+ }
+ } else {
+ aPrintSettings->SetPrintFrameType(nsIPrintSettings::kNoFrames);
+ }
+ // Unlock DeviceNames
+ ::GlobalUnlock(prntdlg.hDevNames);
+
+ // Transfer the settings from the native data to the PrintSettings
+ LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(prntdlg.hDevMode);
+ if (!devMode || !prntdlg.hDC) {
+ return NS_ERROR_FAILURE;
+ }
+ psWin->SetDevMode(devMode); // copies DevMode
+ psWin->CopyFromNative(prntdlg.hDC, devMode);
+ ::GlobalUnlock(prntdlg.hDevMode);
+ ::DeleteDC(prntdlg.hDC);
+
+#if defined(DEBUG_rods) || defined(DEBUG_dcone)
+ bool printSelection = prntdlg.Flags & PD_SELECTION;
+ bool printAllPages = prntdlg.Flags & PD_ALLPAGES;
+ bool printNumPages = prntdlg.Flags & PD_PAGENUMS;
+ int32_t fromPageNum = 0;
+ int32_t toPageNum = 0;
+
+ if (printNumPages) {
+ fromPageNum = prntdlg.nFromPage;
+ toPageNum = prntdlg.nToPage;
+ }
+ if (printSelection) {
+ printf("Printing the selection\n");
+
+ } else if (printAllPages) {
+ printf("Printing all the pages\n");
+
+ } else {
+ printf("Printing from page no. %d to %d\n", fromPageNum, toPageNum);
+ }
+#endif
+
+ } else {
+ ::SetFocus(aHWnd);
+ aPrintSettings->SetIsCancelled(true);
+ return NS_ERROR_ABORT;
+ }
+
+ return NS_OK;
+}
+
+//------------------------------------------------------------------
+static void
+PrepareForPrintDialog(nsIWebBrowserPrint* aWebBrowserPrint, nsIPrintSettings* aPS)
+{
+ NS_ASSERTION(aWebBrowserPrint, "Can't be null");
+ NS_ASSERTION(aPS, "Can't be null");
+
+ bool isFramesetDocument;
+ bool isFramesetFrameSelected;
+ bool isIFrameSelected;
+ bool isRangeSelection;
+
+ aWebBrowserPrint->GetIsFramesetDocument(&isFramesetDocument);
+ aWebBrowserPrint->GetIsFramesetFrameSelected(&isFramesetFrameSelected);
+ aWebBrowserPrint->GetIsIFrameSelected(&isIFrameSelected);
+ aWebBrowserPrint->GetIsRangeSelection(&isRangeSelection);
+
+ // Setup print options for UI
+ if (isFramesetDocument) {
+ if (isFramesetFrameSelected) {
+ aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAll);
+ } else {
+ aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableAsIsAndEach);
+ }
+ } else {
+ aPS->SetHowToEnableFrameUI(nsIPrintSettings::kFrameEnableNone);
+ }
+
+ // Now determine how to set up the Frame print UI
+ aPS->SetPrintOptions(nsIPrintSettings::kEnableSelectionRB, isRangeSelection || isIFrameSelected);
+
+}
+
+//----------------------------------------------------------------------------------
+//-- Show Print Dialog
+//----------------------------------------------------------------------------------
+nsresult NativeShowPrintDialog(HWND aHWnd,
+ nsIWebBrowserPrint* aWebBrowserPrint,
+ nsIPrintSettings* aPrintSettings)
+{
+ PrepareForPrintDialog(aWebBrowserPrint, aPrintSettings);
+
+ nsresult rv = ShowNativePrintDialog(aHWnd, aPrintSettings);
+ if (aHWnd) {
+ ::DestroyWindow(aHWnd);
+ }
+
+ return rv;
+}
+
diff --git a/embedding/components/printingui/win/nsPrintDialogUtil.h b/embedding/components/printingui/win/nsPrintDialogUtil.h
new file mode 100644
index 000000000..ada3da239
--- /dev/null
+++ b/embedding/components/printingui/win/nsPrintDialogUtil.h
@@ -0,0 +1,12 @@
+/* -*- 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 nsFlyOwnDialog_h___
+#define nsFlyOwnDialog_h___
+
+nsresult NativeShowPrintDialog(HWND aHWnd,
+ nsIWebBrowserPrint* aWebBrowserPrint,
+ nsIPrintSettings* aPrintSettings);
+
+#endif /* nsFlyOwnDialog_h___ */
diff --git a/embedding/components/printingui/win/nsPrintProgress.cpp b/embedding/components/printingui/win/nsPrintProgress.cpp
new file mode 100644
index 000000000..0b1c10a2c
--- /dev/null
+++ b/embedding/components/printingui/win/nsPrintProgress.cpp
@@ -0,0 +1,293 @@
+/* -*- 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 "nsArray.h"
+#include "nsIBaseWindow.h"
+#include "nsIDocShell.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIInterfaceRequestorUtils.h"
+#include "nsIXULWindow.h"
+#include "nsXPCOM.h"
+#include "nsISupportsPrimitives.h"
+#include "nsIComponentManager.h"
+#include "nsIServiceManager.h"
+#include "nsPIDOMWindow.h"
+
+#if 0
+NS_IMPL_ADDREF(nsPrintProgress)
+NS_IMPL_RELEASE(nsPrintProgress)
+#else
+NS_IMETHODIMP_(MozExternalRefCountType) nsPrintProgress::AddRef(void)
+{
+ NS_PRECONDITION(int32_t(mRefCnt) >= 0, "illegal refcnt");
+ nsrefcnt count;
+ count = ++mRefCnt;
+ //NS_LOG_ADDREF(this, count, "nsPrintProgress", sizeof(*this));
+ return count;
+}
+
+NS_IMETHODIMP_(MozExternalRefCountType) nsPrintProgress::Release(void)
+{
+ nsrefcnt count;
+ NS_PRECONDITION(0 != mRefCnt, "dup release");
+ count = --mRefCnt;
+ //NS_LOG_RELEASE(this, count, "nsPrintProgress");
+ if (0 == count) {
+ mRefCnt = 1; /* stabilize */
+ /* enable this to find non-threadsafe destructors: */
+ /* NS_ASSERT_OWNINGTHREAD(nsPrintProgress); */
+ delete this;
+ return 0;
+ }
+ return count;
+}
+
+#endif
+
+NS_INTERFACE_MAP_BEGIN(nsPrintProgress)
+ NS_INTERFACE_MAP_ENTRY_AMBIGUOUS(nsISupports, nsIPrintStatusFeedback)
+ NS_INTERFACE_MAP_ENTRY(nsIPrintProgress)
+ NS_INTERFACE_MAP_ENTRY(nsIPrintStatusFeedback)
+ NS_INTERFACE_MAP_ENTRY(nsIWebProgressListener)
+NS_INTERFACE_MAP_END_THREADSAFE
+
+
+nsPrintProgress::nsPrintProgress()
+{
+ m_closeProgress = false;
+ m_processCanceled = false;
+ m_pendingStateFlags = -1;
+ m_pendingStateValue = NS_OK;
+}
+
+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, /*weak =*/ false);
+
+ array->AppendElement(parameters, /*weak = */ false);
+
+ // 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<nsIXULWindow> ownerXULWindow = do_GetInterface(owner);
+ nsCOMPtr<mozIDOMWindowProxy> ownerWindow = do_GetInterface(ownerXULWindow);
+ NS_ENSURE_STATE(ownerWindow);
+
+ nsCOMPtr<nsPIDOMWindowOuter> piOwnerWindow = nsPIDOMWindowOuter::From(ownerWindow);
+
+ // Open the dialog.
+ nsCOMPtr<nsPIDOMWindowOuter> newWindow;
+ rv = piOwnerWindow->OpenDialog(NS_ConvertASCIItoUTF16(dialogURL),
+ NS_LITERAL_STRING("_blank"),
+ NS_LITERAL_STRING("chrome,titlebar,dependent,centerscreen"),
+ array, getter_AddRefs(newWindow));
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP nsPrintProgress::CloseProgressDialog(bool forceClose)
+{
+ m_closeProgress = true;
+ // XXX Casting from bool to nsresult
+ return OnStateChange(nullptr, nullptr, nsIWebProgressListener::STATE_STOP,
+ static_cast<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)
+{
+ 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)
+{
+ 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)
+{
+ 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_OK;
+}
+
+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 state)
+{
+ return NS_OK;
+}
+
+nsresult nsPrintProgress::ReleaseListeners()
+{
+ m_listenerList.Clear();
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgress::ShowStatusString(const char16_t *status)
+{
+ return OnStatusChange(nullptr, nullptr, NS_OK, status);
+}
+
+NS_IMETHODIMP nsPrintProgress::StartMeteors()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::StopMeteors()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::ShowProgress(int32_t percent)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::SetDocShell(nsIDocShell *shell, mozIDOMWindowProxy *window)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP nsPrintProgress::CloseWindow()
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
diff --git a/embedding/components/printingui/win/nsPrintProgress.h b/embedding/components/printingui/win/nsPrintProgress.h
new file mode 100644
index 000000000..adc5a14cc
--- /dev/null
+++ b/embedding/components/printingui/win/nsPrintProgress.h
@@ -0,0 +1,43 @@
+/* -*- 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 "nsIDOMWindow.h"
+#include "nsIPrintStatusFeedback.h"
+#include "nsString.h"
+#include "nsIWindowWatcher.h"
+#include "nsIObserver.h"
+
+class nsPrintProgress : public nsIPrintProgress, public nsIPrintStatusFeedback
+{
+public:
+ NS_DECL_THREADSAFE_ISUPPORTS
+ NS_DECL_NSIPRINTPROGRESS
+ NS_DECL_NSIWEBPROGRESSLISTENER
+ NS_DECL_NSIPRINTSTATUSFEEDBACK
+
+ nsPrintProgress();
+ 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;
+};
+
+#endif
diff --git a/embedding/components/printingui/win/nsPrintProgressParams.cpp b/embedding/components/printingui/win/nsPrintProgressParams.cpp
new file mode 100644
index 000000000..eba86b298
--- /dev/null
+++ b/embedding/components/printingui/win/nsPrintProgressParams.cpp
@@ -0,0 +1,47 @@
+/* -*- 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()
+{
+}
+
+nsPrintProgressParams::~nsPrintProgressParams()
+{
+}
+
+NS_IMETHODIMP nsPrintProgressParams::GetDocTitle(char16_t * *aDocTitle)
+{
+ NS_ENSURE_ARG(aDocTitle);
+
+ *aDocTitle = ToNewUnicode(mDocTitle);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::SetDocTitle(const char16_t * aDocTitle)
+{
+ mDocTitle = aDocTitle;
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::GetDocURL(char16_t * *aDocURL)
+{
+ NS_ENSURE_ARG(aDocURL);
+
+ *aDocURL = ToNewUnicode(mDocURL);
+ return NS_OK;
+}
+
+NS_IMETHODIMP nsPrintProgressParams::SetDocURL(const char16_t * aDocURL)
+{
+ mDocURL = aDocURL;
+ return NS_OK;
+}
+
diff --git a/embedding/components/printingui/win/nsPrintProgressParams.h b/embedding/components/printingui/win/nsPrintProgressParams.h
new file mode 100644
index 000000000..aebfbff7f
--- /dev/null
+++ b/embedding/components/printingui/win/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
+{
+ virtual ~nsPrintProgressParams();
+
+public:
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPRINTPROGRESSPARAMS
+
+ nsPrintProgressParams();
+
+private:
+ nsString mDocTitle;
+ nsString mDocURL;
+};
+
+#endif
diff --git a/embedding/components/printingui/win/nsPrintingPromptService.cpp b/embedding/components/printingui/win/nsPrintingPromptService.cpp
new file mode 100644
index 000000000..83727ee4e
--- /dev/null
+++ b/embedding/components/printingui/win/nsPrintingPromptService.cpp
@@ -0,0 +1,341 @@
+/* -*- 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 "nsCOMPtr.h"
+
+#include "nsPrintingPromptService.h"
+#include "nsIPrintingPromptService.h"
+#include "nsIFactory.h"
+#include "nsPIDOMWindow.h"
+#include "nsReadableUtils.h"
+#include "nsIEmbeddingSiteWindow.h"
+#include "nsIServiceManager.h"
+#include "nsIWebBrowserChrome.h"
+#include "nsIWindowWatcher.h"
+#include "nsPrintDialogUtil.h"
+
+// Printing Progress Includes
+#include "nsPrintProgress.h"
+#include "nsPrintProgressParams.h"
+#include "nsIWebProgressListener.h"
+
+// XP Dialog includes
+#include "nsArray.h"
+#include "nsIDialogParamBlock.h"
+#include "nsISupportsUtils.h"
+
+// Includes need to locate the native Window
+#include "nsIWidget.h"
+#include "nsIBaseWindow.h"
+#include "nsIWebBrowserChrome.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsIDocShellTreeItem.h"
+#include "nsIDocShell.h"
+#include "nsIInterfaceRequestorUtils.h"
+
+
+static const char *kPrintProgressDialogURL = "chrome://global/content/printProgress.xul";
+static const char *kPrtPrvProgressDialogURL = "chrome://global/content/printPreviewProgress.xul";
+static const char *kPageSetupDialogURL = "chrome://global/content/printPageSetup.xul";
+
+/****************************************************************
+ ************************* ParamBlock ***************************
+ ****************************************************************/
+
+class ParamBlock {
+
+public:
+ ParamBlock()
+ {
+ mBlock = 0;
+ }
+ ~ParamBlock()
+ {
+ NS_IF_RELEASE(mBlock);
+ }
+ nsresult Init() {
+ return CallCreateInstance(NS_DIALOGPARAMBLOCK_CONTRACTID, &mBlock);
+ }
+ nsIDialogParamBlock * operator->() const MOZ_NO_ADDREF_RELEASE_ON_RETURN { return mBlock; }
+ operator nsIDialogParamBlock * const () { return mBlock; }
+
+private:
+ nsIDialogParamBlock *mBlock;
+};
+
+//*****************************************************************************
+
+NS_IMPL_ISUPPORTS(nsPrintingPromptService, nsIPrintingPromptService, nsIWebProgressListener)
+
+nsPrintingPromptService::nsPrintingPromptService()
+{
+}
+
+//-----------------------------------------------------------
+nsPrintingPromptService::~nsPrintingPromptService()
+{
+}
+
+//-----------------------------------------------------------
+nsresult
+nsPrintingPromptService::Init()
+{
+ nsresult rv;
+ mWatcher = do_GetService(NS_WINDOWWATCHER_CONTRACTID, &rv);
+ return rv;
+}
+
+//-----------------------------------------------------------
+HWND
+nsPrintingPromptService::GetHWNDForDOMWindow(mozIDOMWindowProxy *aWindow)
+{
+ nsCOMPtr<nsIWebBrowserChrome> chrome;
+
+ // We might be embedded so check this path first
+ if (mWatcher) {
+ nsCOMPtr<mozIDOMWindowProxy> fosterParent;
+ if (!aWindow)
+ { // it will be a dependent window. try to find a foster parent.
+ mWatcher->GetActiveWindow(getter_AddRefs(fosterParent));
+ aWindow = fosterParent;
+ }
+ mWatcher->GetChromeForWindow(aWindow, getter_AddRefs(chrome));
+ }
+
+ if (chrome) {
+ nsCOMPtr<nsIEmbeddingSiteWindow> site(do_QueryInterface(chrome));
+ if (site)
+ {
+ HWND w;
+ site->GetSiteWindow(reinterpret_cast<void **>(&w));
+ return w;
+ }
+ }
+
+ // Now we might be the Browser so check this path
+ nsCOMPtr<nsPIDOMWindowOuter> window = nsPIDOMWindowOuter::From(aWindow);
+
+ nsCOMPtr<nsIDocShellTreeItem> treeItem =
+ do_QueryInterface(window->GetDocShell());
+ if (!treeItem) return nullptr;
+
+ nsCOMPtr<nsIDocShellTreeOwner> treeOwner;
+ treeItem->GetTreeOwner(getter_AddRefs(treeOwner));
+ if (!treeOwner) return nullptr;
+
+ nsCOMPtr<nsIWebBrowserChrome> webBrowserChrome(do_GetInterface(treeOwner));
+ if (!webBrowserChrome) return nullptr;
+
+ nsCOMPtr<nsIBaseWindow> baseWin(do_QueryInterface(webBrowserChrome));
+ if (!baseWin) return nullptr;
+
+ nsCOMPtr<nsIWidget> widget;
+ baseWin->GetMainWidget(getter_AddRefs(widget));
+ if (!widget) return nullptr;
+
+ return (HWND)widget->GetNativeData(NS_NATIVE_TMP_WINDOW);
+
+}
+
+
+///////////////////////////////////////////////////////////////////////////////
+// nsIPrintingPromptService
+
+//-----------------------------------------------------------
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPrintDialog(mozIDOMWindowProxy *parent, nsIWebBrowserPrint *webBrowserPrint, nsIPrintSettings *printSettings)
+{
+ NS_ENSURE_ARG(parent);
+
+ HWND hWnd = GetHWNDForDOMWindow(parent);
+ NS_ASSERTION(hWnd, "Couldn't get native window for PRint Dialog!");
+
+ return NativeShowPrintDialog(hWnd, webBrowserPrint, printSettings);
+}
+
+
+NS_IMETHODIMP
+nsPrintingPromptService::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(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();
+ 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;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPageSetup(mozIDOMWindowProxy *parent, nsIPrintSettings *printSettings, nsIObserver *aObs)
+{
+ NS_ENSURE_ARG(printSettings);
+
+ ParamBlock block;
+ nsresult rv = block.Init();
+ if (NS_FAILED(rv))
+ return rv;
+
+ block->SetInt(0, 0);
+ rv = DoDialog(parent, block, printSettings, kPageSetupDialogURL);
+
+ // if aWebBrowserPrint is not null then we are printing
+ // so we want to pass back NS_ERROR_ABORT on cancel
+ if (NS_SUCCEEDED(rv))
+ {
+ int32_t status;
+ block->GetInt(0, &status);
+ return status == 0?NS_ERROR_ABORT:NS_OK;
+ }
+
+ return rv;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::ShowPrinterProperties(mozIDOMWindowProxy *parent, const char16_t *printerName, nsIPrintSettings *printSettings)
+{
+ return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+//-----------------------------------------------------------
+// Helper to Fly XP Dialog
+nsresult
+nsPrintingPromptService::DoDialog(mozIDOMWindowProxy *aParent,
+ nsIDialogParamBlock *aParamBlock,
+ nsIPrintSettings* aPS,
+ const char *aChromeURL)
+{
+ NS_ENSURE_ARG(aParamBlock);
+ NS_ENSURE_ARG(aPS);
+ NS_ENSURE_ARG(aChromeURL);
+
+ if (!mWatcher)
+ return NS_ERROR_FAILURE;
+
+ // get a parent, if at all possible
+ // (though we'd rather this didn't fail, it's OK if it does. so there's
+ // no failure or null check.)
+ nsCOMPtr<mozIDOMWindowProxy> activeParent; // retain ownership for method lifetime
+ if (!aParent)
+ {
+ mWatcher->GetActiveWindow(getter_AddRefs(activeParent));
+ aParent = activeParent;
+ }
+
+ // create a nsIMutableArray of the parameters
+ // being passed to the window
+ nsCOMPtr<nsIMutableArray> array = nsArray::Create();
+
+ nsCOMPtr<nsISupports> psSupports(do_QueryInterface(aPS));
+ NS_ASSERTION(psSupports, "PrintSettings must be a supports");
+ array->AppendElement(psSupports, /*weak =*/ false);
+
+ nsCOMPtr<nsISupports> blkSupps(do_QueryInterface(aParamBlock));
+ NS_ASSERTION(blkSupps, "IOBlk must be a supports");
+ array->AppendElement(blkSupps, /*weak =*/ false);
+
+ nsCOMPtr<mozIDOMWindowProxy> dialog;
+ nsresult rv = mWatcher->OpenWindow(aParent, aChromeURL, "_blank",
+ "centerscreen,chrome,modal,titlebar", array,
+ getter_AddRefs(dialog));
+
+ return rv;
+}
+
+//////////////////////////////////////////////////////////////////////
+// nsIWebProgressListener
+//////////////////////////////////////////////////////////////////////
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnStateChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t aStateFlags, nsresult aStatus)
+{
+ if ((aStateFlags & STATE_STOP) && mWebProgressListener)
+ {
+ mWebProgressListener->OnStateChange(aWebProgress, aRequest, aStateFlags, aStatus);
+ if (mPrintProgress)
+ {
+ mPrintProgress->CloseProgressDialog(true);
+ }
+ mPrintProgress = nullptr;
+ mWebProgressListener = nullptr;
+ }
+ return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnProgressChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, int32_t aCurSelfProgress, int32_t aMaxSelfProgress, int32_t aCurTotalProgress, int32_t aMaxTotalProgress)
+{
+ if (mWebProgressListener)
+ {
+ return mWebProgressListener->OnProgressChange(aWebProgress, aRequest, aCurSelfProgress, aMaxSelfProgress, aCurTotalProgress, aMaxTotalProgress);
+ }
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnLocationChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsIURI *location, uint32_t aFlags)
+{
+ if (mWebProgressListener)
+ {
+ return mWebProgressListener->OnLocationChange(aWebProgress, aRequest, location, aFlags);
+ }
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnStatusChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, nsresult aStatus, const char16_t *aMessage)
+{
+ if (mWebProgressListener)
+ {
+ return mWebProgressListener->OnStatusChange(aWebProgress, aRequest, aStatus, aMessage);
+ }
+ return NS_ERROR_FAILURE;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptService::OnSecurityChange(nsIWebProgress *aWebProgress, nsIRequest *aRequest, uint32_t state)
+{
+ if (mWebProgressListener)
+ {
+ return mWebProgressListener->OnSecurityChange(aWebProgress, aRequest, state);
+ }
+ return NS_ERROR_FAILURE;
+}
+
+
diff --git a/embedding/components/printingui/win/nsPrintingPromptService.h b/embedding/components/printingui/win/nsPrintingPromptService.h
new file mode 100644
index 000000000..76bc7a804
--- /dev/null
+++ b/embedding/components/printingui/win/nsPrintingPromptService.h
@@ -0,0 +1,58 @@
+/* -*- 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
+
+#include <windows.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 "nsPIPromptService.h"
+#include "nsIWindowWatcher.h"
+
+// Printing Progress Includes
+#include "nsPrintProgress.h"
+#include "nsPrintProgressParams.h"
+#include "nsIWebProgressListener.h"
+
+class nsIDOMWindow;
+class nsIDialogParamBlock;
+
+class nsPrintingPromptService: public nsIPrintingPromptService,
+ public nsIWebProgressListener
+{
+ virtual ~nsPrintingPromptService();
+
+public:
+ nsPrintingPromptService();
+
+ nsresult Init();
+
+ NS_DECL_ISUPPORTS
+ NS_DECL_NSIPRINTINGPROMPTSERVICE
+ NS_DECL_NSIWEBPROGRESSLISTENER
+
+private:
+ HWND GetHWNDForDOMWindow(mozIDOMWindowProxy *parent);
+ nsresult DoDialog(mozIDOMWindowProxy *aParent,
+ nsIDialogParamBlock *aParamBlock,
+ nsIPrintSettings* aPS,
+ const char *aChromeURL);
+
+ nsCOMPtr<nsIWindowWatcher> mWatcher;
+ nsCOMPtr<nsIPrintProgress> mPrintProgress;
+ nsCOMPtr<nsIWebProgressListener> mWebProgressListener;
+
+};
+
+#endif
+