diff options
Diffstat (limited to 'embedding/components/printingui/ipc')
19 files changed, 1720 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 + |