Bug 1082579 - Introduce PPrinting.ipdl and proxies for opening printing UI. r=blassey.
authorMike Conley <mconley@mozilla.com>
Tue, 28 Oct 2014 11:59:08 -0400
changeset 212782 a9530d7f005aa70510c19c11c1eaaaf8a27af0fe
parent 212781 24a95294f600d50960d388151fa1e8d28d0474ba
child 212783 b89b931eec260a0ff12826e361353f26e2aeea8c
push id27728
push userkwierso@gmail.com
push dateWed, 29 Oct 2014 02:08:04 +0000
treeherdermozilla-central@7e3c85754d32 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey
bugs1082579
milestone36.0a1
first release with
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
last release without
nightly linux32
nightly linux64
nightly mac
nightly win32
nightly win64
Bug 1082579 - Introduce PPrinting.ipdl and proxies for opening printing UI. r=blassey.
browser/app/profile/firefox.js
dom/ipc/ContentChild.cpp
dom/ipc/ContentChild.h
dom/ipc/ContentParent.cpp
dom/ipc/ContentParent.h
dom/ipc/PContent.ipdl
dom/ipc/moz.build
embedding/components/build/moz.build
embedding/components/build/nsEmbeddingModule.cpp
embedding/components/printingui/ipc/PPrinting.ipdl
embedding/components/printingui/ipc/PrintDataUtils.cpp
embedding/components/printingui/ipc/PrintDataUtils.h
embedding/components/printingui/ipc/PrintingParent.cpp
embedding/components/printingui/ipc/PrintingParent.h
embedding/components/printingui/ipc/moz.build
embedding/components/printingui/ipc/nsPrintingPromptServiceProxy.cpp
embedding/components/printingui/ipc/nsPrintingPromptServiceProxy.h
embedding/components/printingui/moz.build
embedding/components/printingui/win/moz.build
embedding/components/printingui/win/nsPrintDialogUtil.cpp
embedding/components/printingui/win/nsPrintDialogUtil.h
view/nsViewManager.cpp
widget/cocoa/nsPrintOptionsX.mm
widget/cocoa/nsWidgetFactory.mm
widget/gtk/nsWidgetFactory.cpp
widget/moz.build
widget/nsIPrintOptions.idl
widget/nsPrintOptionsImpl.cpp
widget/nsPrintOptionsImpl.h
widget/windows/nsPrintOptionsWin.cpp
widget/windows/nsPrintOptionsWin.h
widget/windows/nsWidgetFactory.cpp
--- a/browser/app/profile/firefox.js
+++ b/browser/app/profile/firefox.js
@@ -1761,8 +1761,15 @@ pref("experiments.supported", true);
 
 // Enable the OpenH264 plugin support in the addon manager.
 pref("media.gmp-gmpopenh264.provider.enabled", true);
 
 pref("browser.apps.URL", "https://marketplace.firefox.com/discovery/");
 
 pref("browser.polaris.enabled", false);
 pref("privacy.trackingprotection.ui.enabled", false);
+
+// Temporary pref to allow printing in e10s windows on some platforms.
+#ifdef UNIX_BUT_NOT_MAC
+pref("print.enable_e10s_testing", false);
+#else
+pref("print.enable_e10s_testing", true);
+#endif
--- a/dom/ipc/ContentChild.cpp
+++ b/dom/ipc/ContentChild.cpp
@@ -170,16 +170,17 @@ using namespace mozilla::docshell;
 using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::cellbroadcast;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::ipc;
 using namespace mozilla::dom::mobileconnection;
 using namespace mozilla::dom::mobilemessage;
 using namespace mozilla::dom::telephony;
 using namespace mozilla::dom::voicemail;
+using namespace mozilla::embedding;
 using namespace mozilla::hal_sandbox;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::net;
 using namespace mozilla::jsipc;
 #if defined(MOZ_WIDGET_GONK)
 using namespace mozilla::system;
 #endif
@@ -1386,16 +1387,34 @@ ContentChild::AllocPNeckoChild()
 
 bool
 ContentChild::DeallocPNeckoChild(PNeckoChild* necko)
 {
     delete necko;
     return true;
 }
 
+PPrintingChild*
+ContentChild::AllocPPrintingChild()
+{
+    // The ContentParent should never attempt to allocate the
+    // nsPrintingPromptServiceProxy, which implements PPrintingChild. Instead,
+    // the nsPrintingPromptServiceProxy service is requested and instantiated
+    // via XPCOM, and the constructor of nsPrintingPromptServiceProxy sets up
+    // the IPC connection.
+    NS_NOTREACHED("Should never get here!");
+    return nullptr;
+}
+
+bool
+ContentChild::DeallocPPrintingChild(PPrintingChild* printing)
+{
+    return true;
+}
+
 PScreenManagerChild*
 ContentChild::AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
                                        float* aSystemDefaultScale,
                                        bool* aSuccess)
 {
     // The ContentParent should never attempt to allocate the
     // nsScreenManagerProxy. Instead, the nsScreenManagerProxy
     // service is requested and instantiated via XPCOM, and the
--- a/dom/ipc/ContentChild.h
+++ b/dom/ipc/ContentChild.h
@@ -202,16 +202,19 @@ public:
     virtual PMobileConnectionChild*
     AllocPMobileConnectionChild(const uint32_t& aClientId) MOZ_OVERRIDE;
     virtual bool
     DeallocPMobileConnectionChild(PMobileConnectionChild* aActor) MOZ_OVERRIDE;
 
     virtual PNeckoChild* AllocPNeckoChild() MOZ_OVERRIDE;
     virtual bool DeallocPNeckoChild(PNeckoChild*) MOZ_OVERRIDE;
 
+    virtual PPrintingChild* AllocPPrintingChild() MOZ_OVERRIDE;
+    virtual bool DeallocPPrintingChild(PPrintingChild*) MOZ_OVERRIDE;
+
     virtual PScreenManagerChild*
     AllocPScreenManagerChild(uint32_t* aNumberOfScreens,
                              float* aSystemDefaultScale,
                              bool* aSuccess) MOZ_OVERRIDE;
     virtual bool DeallocPScreenManagerChild(PScreenManagerChild*) MOZ_OVERRIDE;
 
     virtual PExternalHelperAppChild *AllocPExternalHelperAppChild(
             const OptionalURIParams& uri,
--- a/dom/ipc/ContentParent.cpp
+++ b/dom/ipc/ContentParent.cpp
@@ -52,16 +52,17 @@
 #include "mozilla/dom/devicestorage/DeviceStorageRequestParent.h"
 #include "mozilla/dom/mobileconnection/MobileConnectionParent.h"
 #include "mozilla/dom/mobilemessage/SmsParent.h"
 #include "mozilla/dom/power/PowerManagerService.h"
 #include "mozilla/dom/quota/QuotaManager.h"
 #include "mozilla/dom/telephony/TelephonyParent.h"
 #include "mozilla/dom/time/DateCacheCleaner.h"
 #include "mozilla/dom/voicemail/VoicemailParent.h"
+#include "mozilla/embedding/printingui/PrintingParent.h"
 #include "mozilla/hal_sandbox/PHalParent.h"
 #include "mozilla/ipc/BackgroundChild.h"
 #include "mozilla/ipc/BackgroundParent.h"
 #include "mozilla/ipc/FileDescriptorSetParent.h"
 #include "mozilla/ipc/FileDescriptorUtils.h"
 #include "mozilla/ipc/PFileDescriptorSetParent.h"
 #include "mozilla/ipc/TestShellParent.h"
 #include "mozilla/ipc/InputStreamUtils.h"
@@ -203,16 +204,17 @@ using namespace mozilla::dom::bluetooth;
 using namespace mozilla::dom::cellbroadcast;
 using namespace mozilla::dom::devicestorage;
 using namespace mozilla::dom::indexedDB;
 using namespace mozilla::dom::power;
 using namespace mozilla::dom::mobileconnection;
 using namespace mozilla::dom::mobilemessage;
 using namespace mozilla::dom::telephony;
 using namespace mozilla::dom::voicemail;
+using namespace mozilla::embedding;
 using namespace mozilla::hal;
 using namespace mozilla::ipc;
 using namespace mozilla::layers;
 using namespace mozilla::net;
 using namespace mozilla::jsipc;
 using namespace mozilla::widget;
 
 #ifdef ENABLE_TESTS
@@ -3111,16 +3113,35 @@ ContentParent::AllocPNeckoParent()
 
 bool
 ContentParent::DeallocPNeckoParent(PNeckoParent* necko)
 {
     delete necko;
     return true;
 }
 
+PPrintingParent*
+ContentParent::AllocPPrintingParent()
+{
+    return new PrintingParent();
+}
+
+bool
+ContentParent::RecvPPrintingConstructor(PPrintingParent* aActor)
+{
+    return true;
+}
+
+bool
+ContentParent::DeallocPPrintingParent(PPrintingParent* printing)
+{
+    delete printing;
+    return true;
+}
+
 PScreenManagerParent*
 ContentParent::AllocPScreenManagerParent(uint32_t* aNumberOfScreens,
                                          float* aSystemDefaultScale,
                                          bool* aSuccess)
 {
     return new ScreenManagerParent(aNumberOfScreens, aSystemDefaultScale, aSuccess);
 }
 
--- a/dom/ipc/ContentParent.h
+++ b/dom/ipc/ContentParent.h
@@ -240,16 +240,20 @@ public:
                                   const NativeThreadId& tid,
                                   const uint32_t& processType) MOZ_OVERRIDE;
 
     virtual PNeckoParent* AllocPNeckoParent() MOZ_OVERRIDE;
     virtual bool RecvPNeckoConstructor(PNeckoParent* aActor) MOZ_OVERRIDE {
         return PContentParent::RecvPNeckoConstructor(aActor);
     }
 
+    virtual PPrintingParent* AllocPPrintingParent() MOZ_OVERRIDE;
+    virtual bool RecvPPrintingConstructor(PPrintingParent* aActor) MOZ_OVERRIDE;
+    virtual bool DeallocPPrintingParent(PPrintingParent* aActor) MOZ_OVERRIDE;
+
     virtual PScreenManagerParent*
     AllocPScreenManagerParent(uint32_t* aNumberOfScreens,
                               float* aSystemDefaultScale,
                               bool* aSuccess) MOZ_OVERRIDE;
     virtual bool DeallocPScreenManagerParent(PScreenManagerParent* aActor) MOZ_OVERRIDE;
 
     virtual PHalParent* AllocPHalParent() MOZ_OVERRIDE;
     virtual bool RecvPHalConstructor(PHalParent* aActor) MOZ_OVERRIDE {
--- a/dom/ipc/PContent.ipdl
+++ b/dom/ipc/PContent.ipdl
@@ -20,16 +20,17 @@ include protocol PDeviceStorageRequest;
 include protocol PFileDescriptorSet;
 include protocol PFMRadio;
 include protocol PFileSystemRequest;
 include protocol PHal;
 include protocol PImageBridge;
 include protocol PMemoryReportRequest;
 include protocol PMobileConnection;
 include protocol PNecko;
+include protocol PPrinting;
 include protocol PScreenManager;
 include protocol PSharedBufferManager;
 include protocol PSms;
 include protocol PSpeechSynthesis;
 include protocol PStorage;
 include protocol PTelephony;
 include protocol PTestShell;
 include protocol PVoicemail;
@@ -344,16 +345,17 @@ prio(normal upto high) intr protocol PCo
     manages PFileSystemRequest;
     manages PExternalHelperApp;
     manages PFileDescriptorSet;
     manages PFMRadio;
     manages PHal;
     manages PMemoryReportRequest;
     manages PMobileConnection;
     manages PNecko;
+    manages PPrinting;
     manages PScreenManager;
     manages PSms;
     manages PSpeechSynthesis;
     manages PStorage;
     manages PTelephony;
     manages PTestShell;
     manages PVoicemail;
     manages PJavaScript;
@@ -548,16 +550,18 @@ parent:
         returns (bool isSecureURI);
 
     PHal();
 
     PMobileConnection(uint32_t clientId);
 
     PNecko();
 
+    PPrinting();
+
     prio(high) sync PScreenManager()
         returns (uint32_t numberOfScreens,
                  float systemDefaultScale,
                  bool success);
 
     PCellBroadcast();
 
     PSms();
--- a/dom/ipc/moz.build
+++ b/dom/ipc/moz.build
@@ -105,16 +105,17 @@ LOCAL_INCLUDES += [
     '/dom/devicestorage',
     '/dom/filesystem',
     '/dom/fmradio/ipc',
     '/dom/geolocation',
     '/dom/media/webspeech/synth/ipc',
     '/dom/mobilemessage/ipc',
     '/dom/storage',
     '/editor/libeditor',
+    '/embedding/components/printingui/ipc',
     '/extensions/cookie',
     '/extensions/spellcheck/src',
     '/hal/sandbox',
     '/js/ipc',
     '/layout/base',
     '/netwerk/base/src',
     '/toolkit/xre',
     '/uriloader/exthandler',
--- a/embedding/components/build/moz.build
+++ b/embedding/components/build/moz.build
@@ -10,26 +10,31 @@ SOURCES += [
 
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
 LOCAL_INCLUDES += [
     '../appstartup',
     '../commandhandler',
     '../find',
+    '../printingui/ipc',
     '../webbrowserpersist',
     '../windowwatcher',
 ]
 
 if CONFIG['MOZ_WIDGET_TOOLKIT'] == 'windows':
+    DEFINES['PROXY_PRINTING'] = 1
     LOCAL_INCLUDES += [
         '../printingui/win',
     ]
 elif CONFIG['MOZ_WIDGET_TOOLKIT'] == 'cocoa':
     LOCAL_INCLUDES += [
         '../printingui/mac',
     ]
 
 if CONFIG['MOZ_PDF_PRINTING']:
+    DEFINES['PROXY_PRINTING'] = 1
     LOCAL_INCLUDES += [
         '../printingui/unixshared',
     ]
 
+include('/ipc/chromium/chromium-config.mozbuild')
+
--- a/embedding/components/build/nsEmbeddingModule.cpp
+++ b/embedding/components/build/nsEmbeddingModule.cpp
@@ -15,16 +15,17 @@
 #include "nsCommandParams.h"
 #include "nsCommandGroup.h"
 #include "nsBaseCommandController.h"
 #include "nsNetCID.h"
 #include "nsEmbedCID.h"
 
 #ifdef NS_PRINTING
 #include "nsPrintingPromptService.h"
+#include "nsPrintingPromptServiceProxy.h"
 #endif
 
 
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsWindowWatcher, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsAppStartupNotifier)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsFind)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebBrowserFind)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsWebBrowserPersist)
@@ -33,16 +34,19 @@ NS_GENERIC_FACTORY_CONSTRUCTOR(nsCommand
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsCommandParams, Init)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsControllerCommandGroup)
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsBaseCommandController)
 
 #ifdef MOZ_XUL
 NS_GENERIC_FACTORY_CONSTRUCTOR(nsDialogParamBlock)
 #ifdef NS_PRINTING
 NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintingPromptService, Init)
+#ifdef PROXY_PRINTING
+NS_GENERIC_FACTORY_CONSTRUCTOR_INIT(nsPrintingPromptServiceProxy, Init)
+#endif
 #endif
 #endif
 
 #ifdef MOZ_XUL
 NS_DEFINE_NAMED_CID(NS_DIALOGPARAMBLOCK_CID);
 #ifdef NS_PRINTING
 NS_DEFINE_NAMED_CID(NS_PRINTINGPROMPTSERVICE_CID);
 #endif
@@ -57,19 +61,27 @@ NS_DEFINE_NAMED_CID(NS_COMMAND_MANAGER_C
 NS_DEFINE_NAMED_CID(NS_COMMAND_PARAMS_CID);
 NS_DEFINE_NAMED_CID(NS_CONTROLLER_COMMAND_GROUP_CID);
 NS_DEFINE_NAMED_CID(NS_BASECOMMANDCONTROLLER_CID);
 
 static const mozilla::Module::CIDEntry kEmbeddingCIDs[] = {
 #ifdef MOZ_XUL
     { &kNS_DIALOGPARAMBLOCK_CID, false, nullptr, nsDialogParamBlockConstructor },
 #ifdef NS_PRINTING
+
+#ifdef PROXY_PRINTING
+    { &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingPromptServiceConstructor,
+      mozilla::Module::MAIN_PROCESS_ONLY },
+    { &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingPromptServiceProxyConstructor,
+      mozilla::Module::CONTENT_PROCESS_ONLY },
+#else
     { &kNS_PRINTINGPROMPTSERVICE_CID, false, nullptr, nsPrintingPromptServiceConstructor },
 #endif
 #endif
+#endif
     { &kNS_WINDOWWATCHER_CID, false, nullptr, nsWindowWatcherConstructor },
     { &kNS_FIND_CID, false, nullptr, nsFindConstructor },
     { &kNS_WEB_BROWSER_FIND_CID, false, nullptr, nsWebBrowserFindConstructor },
     { &kNS_APPSTARTUPNOTIFIER_CID, false, nullptr, nsAppStartupNotifierConstructor },
     { &kNS_WEBBROWSERPERSIST_CID, false, nullptr, nsWebBrowserPersistConstructor },
     { &kNS_CONTROLLERCOMMANDTABLE_CID, false, nullptr, nsControllerCommandTableConstructor },
     { &kNS_COMMAND_MANAGER_CID, false, nullptr, nsCommandManagerConstructor },
     { &kNS_COMMAND_PARAMS_CID, false, nullptr, nsCommandParamsConstructor },
new file mode 100644
--- /dev/null
+++ b/embedding/components/printingui/ipc/PPrinting.ipdl
@@ -0,0 +1,101 @@
+/* -*- 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 PContent;
+include protocol PBrowser;
+
+namespace mozilla {
+namespace embedding {
+
+struct PrintData {
+  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 paperSizeType;
+  short paperData;
+  double paperWidth;
+  double paperHeight;
+  short paperSizeUnit;
+  nsString plexName;
+  nsString colorspace;
+  nsString resolutionName;
+  bool downloadFonts;
+  bool printReversed;
+  bool printInColor;
+  int32_t orientation;
+  nsString printCommand;
+  int32_t numCopies;
+  nsString printerName;
+  bool printToFile;
+  nsString toFileName;
+  short outputFormat;
+  int32_t printPageDelay;
+  int32_t resolution;
+  int32_t duplex;
+  bool isInitializedFromPrinter;
+  bool isInitializedFromPrefs;
+  bool persistMarginBoxSettings;
+
+  /* Windows-specific things */
+  nsString driverName;
+  nsString deviceName;
+  bool isFramesetDocument;
+  bool isFramesetFrameSelected;
+  bool isIFrameSelected;
+  bool isRangeSelection;
+
+  /* TODO: OS X specific things - specifically, an array of names for the
+   * document to be supplied by nsIWebBrowserPrint::enumerateDocumentNames
+   */
+};
+
+sync protocol PPrinting
+{
+  manager PContent;
+
+parent:
+  sync ShowProgress(PBrowser browser, bool isForPrinting);
+  sync ShowPrintDialog(PBrowser browser, PrintData settings)
+    returns(PrintData modifiedSettings, bool success);
+
+child:
+  __delete__();
+};
+
+} // namespace embedding
+} // namespace mozilla
new file mode 100644
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintDataUtils.cpp
@@ -0,0 +1,143 @@
+/* -*- 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 "nsIPrintOptions.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(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(nsIDOMWindow **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,
+                                  nsIDOMWindow* 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)
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+MockWebBrowserPrint::ExitPrintPreview()
+{
+  return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+} // namespace embedding
+} // namespace mozilla
+
new file mode 100644
--- /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 MOZ_FINAL : public nsIWebBrowserPrint
+{
+public:
+  MockWebBrowserPrint(PrintData aData);
+
+  NS_DECL_ISUPPORTS
+  NS_DECL_NSIWEBBROWSERPRINT
+
+private:
+  ~MockWebBrowserPrint();
+  PrintData mData;
+};
+
+} // namespace embedding
+} // namespace mozilla
+
+#endif
new file mode 100644
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintingParent.cpp
@@ -0,0 +1,150 @@
+/* -*- 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 "mozilla/dom/Element.h"
+#include "mozilla/dom/TabParent.h"
+#include "nsIContent.h"
+#include "nsIDocument.h"
+#include "nsIDOMWindow.h"
+#include "nsIPrintingPromptService.h"
+#include "nsIPrintProgressParams.h"
+#include "nsIServiceManager.h"
+#include "nsIWebProgressListener.h"
+#include "PrintingParent.h"
+#include "nsIPrintOptions.h"
+#include "PrintDataUtils.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+
+namespace mozilla {
+namespace embedding {
+bool
+PrintingParent::RecvShowProgress(PBrowserParent* parent,
+                                 const bool& isForPrinting)
+{
+  TabParent* tabParent = static_cast<TabParent*>(parent);
+  if (!tabParent) {
+    return true;
+  }
+
+  nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement();
+  if (!frameElement) {
+    return true;
+  }
+
+  nsCOMPtr<nsIContent> frame(do_QueryInterface(frameElement));
+  if (!frame) {
+    return true;
+  }
+
+  nsCOMPtr<nsIDOMWindow> parentWin = do_QueryInterface(frame->OwnerDoc()->GetWindow());
+  if (!parentWin) {
+    return true;
+  }
+
+  nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
+
+  if (!pps) {
+    return true;
+  }
+
+  nsCOMPtr<nsIWebProgressListener> printProgressListener;
+  nsCOMPtr<nsIPrintProgressParams> printProgressParams;
+
+  // TODO: What do I do with this thing?
+  bool doNotify = false;
+
+  pps->ShowProgress(parentWin, nullptr, nullptr, nullptr,
+                    isForPrinting,
+                    getter_AddRefs(printProgressListener),
+                    getter_AddRefs(printProgressParams),
+                    &doNotify);
+
+  return true;
+}
+
+bool
+PrintingParent::RecvShowPrintDialog(PBrowserParent* parent,
+                                    const PrintData& data,
+                                    PrintData* retVal,
+                                    bool* success)
+{
+  *success = false;
+
+  TabParent* tabParent = static_cast<TabParent*>(parent);
+  if (!tabParent) {
+    return true;
+  }
+
+  nsCOMPtr<Element> frameElement = tabParent->GetOwnerElement();
+  if (!frameElement) {
+    return true;
+  }
+
+  nsCOMPtr<nsIContent> frame(do_QueryInterface(frameElement));
+  if (!frame) {
+    return true;
+  }
+
+  nsCOMPtr<nsIDOMWindow> parentWin = do_QueryInterface(frame->OwnerDoc()->GetWindow());
+  if (!parentWin) {
+    return true;
+  }
+
+  nsCOMPtr<nsIPrintingPromptService> pps(do_GetService("@mozilla.org/embedcomp/printingprompt-service;1"));
+
+  if (!pps) {
+    return true;
+  }
+
+  // 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(data);
+
+  nsresult rv;
+  nsCOMPtr<nsIPrintOptions> po = do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
+  NS_ENSURE_SUCCESS(rv, true);
+
+  nsCOMPtr<nsIPrintSettings> settings;
+  rv = po->CreatePrintSettings(getter_AddRefs(settings));
+  NS_ENSURE_SUCCESS(rv, true);
+
+  rv = po->DeserializeToPrintSettings(data, settings);
+  NS_ENSURE_SUCCESS(rv, true);
+
+  rv = pps->ShowPrintDialog(parentWin, wbp, settings);
+  NS_ENSURE_SUCCESS(rv, true);
+
+  // And send it back.
+  PrintData result;
+  rv = po->SerializeToPrintData(settings, nullptr, &result);
+  NS_ENSURE_SUCCESS(rv, true);
+
+  *retVal = result;
+  *success = true;
+  return true;
+}
+
+void
+PrintingParent::ActorDestroy(ActorDestroyReason aWhy)
+{
+}
+
+MOZ_IMPLICIT PrintingParent::PrintingParent()
+{
+    MOZ_COUNT_CTOR(PrintingParent);
+}
+
+MOZ_IMPLICIT PrintingParent::~PrintingParent()
+{
+    MOZ_COUNT_DTOR(PrintingParent);
+}
+
+} // namespace embedding
+} // namespace mozilla
+
new file mode 100644
--- /dev/null
+++ b/embedding/components/printingui/ipc/PrintingParent.h
@@ -0,0 +1,37 @@
+/* -*- 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/embedding/PPrintingParent.h"
+#include "mozilla/dom/PBrowserParent.h"
+
+namespace mozilla {
+namespace embedding {
+class PrintingParent : public PPrintingParent
+{
+public:
+    virtual bool
+    RecvShowProgress(PBrowserParent* parent,
+                     const bool& isForPrinting);
+    virtual bool
+    RecvShowPrintDialog(PBrowserParent* parent,
+                        const PrintData& initSettings,
+                        PrintData* retVal,
+                        bool* success);
+
+    virtual void
+    ActorDestroy(ActorDestroyReason aWhy);
+
+    MOZ_IMPLICIT PrintingParent();
+    virtual ~PrintingParent();
+};
+} // namespace embedding
+} // namespace mozilla
+
+#endif
+
new file mode 100644
--- /dev/null
+++ b/embedding/components/printingui/ipc/moz.build
@@ -0,0 +1,25 @@
+# -*- Mode: python; c-basic-offset: 4; 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.mozilla.embedding.printingui += [
+    'PrintingParent.h',
+]
+
+UNIFIED_SOURCES += [
+    'nsPrintingPromptServiceProxy.cpp',
+    'PrintDataUtils.cpp',
+    'PrintingParent.cpp',
+]
+
+IPDL_SOURCES += [
+    'PPrinting.ipdl',
+]
+
+include('/ipc/chromium/chromium-config.mozbuild')
+
+FAIL_ON_WARNINGS = True
+
+FINAL_LIBRARY = 'xul'
new file mode 100644
--- /dev/null
+++ b/embedding/components/printingui/ipc/nsPrintingPromptServiceProxy.cpp
@@ -0,0 +1,135 @@
+/* -*- 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 "mozilla/dom/ContentChild.h"
+#include "mozilla/dom/TabChild.h"
+#include "mozilla/unused.h"
+#include "nsIDocShell.h"
+#include "nsIDocShellTreeOwner.h"
+#include "nsPIDOMWindow.h"
+#include "nsPrintingPromptServiceProxy.h"
+#include "nsIPrintingPromptService.h"
+#include "PrintDataUtils.h"
+#include "nsPrintOptionsImpl.h"
+
+using namespace mozilla;
+using namespace mozilla::dom;
+using namespace mozilla::embedding;
+
+NS_IMPL_ISUPPORTS(nsPrintingPromptServiceProxy, nsIPrintingPromptService)
+
+nsPrintingPromptServiceProxy::nsPrintingPromptServiceProxy()
+{
+}
+
+nsPrintingPromptServiceProxy::~nsPrintingPromptServiceProxy()
+{
+}
+
+nsresult
+nsPrintingPromptServiceProxy::Init()
+{
+  mozilla::unused << ContentChild::GetSingleton()->SendPPrintingConstructor(this);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptServiceProxy::ShowPrintDialog(nsIDOMWindow *parent,
+                                              nsIWebBrowserPrint *webBrowserPrint,
+                                              nsIPrintSettings *printSettings)
+{
+  NS_ENSURE_ARG(parent);
+  NS_ENSURE_ARG(webBrowserPrint);
+  NS_ENSURE_ARG(printSettings);
+
+  // Get the root docshell owner of this nsIDOMWindow, which
+  // should map to a TabChild, which we can then pass up to
+  // the parent.
+  nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(parent);
+  NS_ENSURE_STATE(pwin);
+  nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
+  NS_ENSURE_STATE(docShell);
+  nsCOMPtr<nsIDocShellTreeOwner> owner;
+  nsresult rv = docShell->GetTreeOwner(getter_AddRefs(owner));
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
+  NS_ENSURE_STATE(tabchild);
+
+  TabChild* pBrowser = static_cast<TabChild*>(tabchild.get());
+
+  // Next, serialize the nsIWebBrowserPrint and nsIPrintSettings we were given.
+  nsCOMPtr<nsIPrintOptions> po =
+    do_GetService("@mozilla.org/gfx/printsettings-service;1", &rv);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PrintData inSettings;
+  rv = po->SerializeToPrintData(printSettings, webBrowserPrint, &inSettings);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  PrintData modifiedSettings;
+  bool success;
+
+  mozilla::unused << SendShowPrintDialog(pBrowser, inSettings, &modifiedSettings, &success);
+
+  if (!success) {
+    // Something failed in the parent.
+    return NS_ERROR_FAILURE;
+  }
+
+  rv = po->DeserializeToPrintSettings(modifiedSettings, printSettings);
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptServiceProxy::ShowProgress(nsIDOMWindow*            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 root docshell owner of this nsIDOMWindow, which
+  // should map to a TabChild, which we can then pass up to
+  // the parent.
+  nsCOMPtr<nsPIDOMWindow> pwin = do_QueryInterface(parent);
+  NS_ENSURE_STATE(pwin);
+  nsCOMPtr<nsIDocShell> docShell = pwin->GetDocShell();
+  NS_ENSURE_STATE(docShell);
+  nsCOMPtr<nsIDocShellTreeOwner> owner;
+  nsresult rv = docShell->GetTreeOwner(getter_AddRefs(owner));
+  NS_ENSURE_SUCCESS(rv, rv);
+  nsCOMPtr<nsITabChild> tabchild = do_GetInterface(owner);
+  TabChild* pBrowser = static_cast<TabChild*>(tabchild.get());
+
+  mozilla::unused << SendShowProgress(pBrowser, isForPrinting);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptServiceProxy::ShowPageSetup(nsIDOMWindow *parent,
+                                            nsIPrintSettings *printSettings,
+                                            nsIObserver *aObs)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
+NS_IMETHODIMP
+nsPrintingPromptServiceProxy::ShowPrinterProperties(nsIDOMWindow *parent,
+                                                    const char16_t *printerName,
+                                                    nsIPrintSettings *printSettings)
+{
+    return NS_ERROR_NOT_IMPLEMENTED;
+}
+
new file mode 100644
--- /dev/null
+++ b/embedding/components/printingui/ipc/nsPrintingPromptServiceProxy.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 __nsPrintingPromptServiceProxy_h
+#define __nsPrintingPromptServiceProxy_h
+
+#include "nsIPrintingPromptService.h"
+#include "mozilla/embedding/PPrintingChild.h"
+
+class nsPrintingPromptServiceProxy: public nsIPrintingPromptService,
+                                    public mozilla::embedding::PPrintingChild
+{
+    virtual ~nsPrintingPromptServiceProxy();
+
+public:
+    nsPrintingPromptServiceProxy();
+
+    nsresult Init();
+
+    NS_DECL_ISUPPORTS
+    NS_DECL_NSIPRINTINGPROMPTSERVICE
+};
+
+#endif
+
--- a/embedding/components/printingui/moz.build
+++ b/embedding/components/printingui/moz.build
@@ -1,14 +1,16 @@
 # -*- Mode: python; c-basic-offset: 4; 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 toolkit == 'windows':
     DIRS += ['win']
 elif toolkit == 'cocoa':
     DIRS += ['mac']
 elif CONFIG['MOZ_PDF_PRINTING']:
     DIRS += ['unixshared']
--- a/embedding/components/printingui/win/moz.build
+++ b/embedding/components/printingui/win/moz.build
@@ -6,11 +6,15 @@
 
 UNIFIED_SOURCES += [
     'nsPrintDialogUtil.cpp',
     'nsPrintingPromptService.cpp',
     'nsPrintProgress.cpp',
     'nsPrintProgressParams.cpp',
 ]
 
+EXPORTS += [
+    'nsPrintDialogUtil.h',
+]
+
 FAIL_ON_WARNINGS = True
 
 FINAL_LIBRARY = 'xul'
--- a/embedding/components/printingui/win/nsPrintDialogUtil.cpp
+++ b/embedding/components/printingui/win/nsPrintDialogUtil.cpp
@@ -677,17 +677,17 @@ static UINT CALLBACK PrintHookProc(HWND 
 //----------------------------------------------------------------------------------
 // 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 HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS)
+HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS)
 {
   HGLOBAL hGlobalDevMode = nullptr;
 
   HANDLE 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) {
--- a/embedding/components/printingui/win/nsPrintDialogUtil.h
+++ b/embedding/components/printingui/win/nsPrintDialogUtil.h
@@ -4,9 +4,11 @@
  * 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);
 
+HGLOBAL CreateGlobalDevModeAndInit(const nsXPIDLString& aPrintName, nsIPrintSettings* aPS);
+
 #endif /* nsFlyOwnDialog_h___ */
--- a/view/nsViewManager.cpp
+++ b/view/nsViewManager.cpp
@@ -1061,23 +1061,24 @@ nsViewManager::IsPainting(bool& aIsPaint
 void
 nsViewManager::ProcessPendingUpdates()
 {
   if (!IsRootVM()) {
     RootViewManager()->ProcessPendingUpdates();
     return;
   }
 
-  mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush();
-
   // Flush things like reflows by calling WillPaint on observer presShells.
   if (mPresShell) {
+    mPresShell->GetPresContext()->RefreshDriver()->RevokeViewManagerFlush();
+
     CallWillPaintOnObservers();
+
+    ProcessPendingUpdatesForView(mRootView, true);
   }
-  ProcessPendingUpdatesForView(mRootView, true);
 }
 
 void
 nsViewManager::UpdateWidgetGeometry()
 {
   if (!IsRootVM()) {
     RootViewManager()->UpdateWidgetGeometry();
     return;
--- a/widget/cocoa/nsPrintOptionsX.mm
+++ b/widget/cocoa/nsPrintOptionsX.mm
@@ -24,17 +24,17 @@ nsPrintOptionsX::ReadPrefs(nsIPrintSetti
   rv = nsPrintOptions::ReadPrefs(aPS, aPrinterName, aFlags);
   NS_ASSERTION(NS_SUCCEEDED(rv), "nsPrintOptions::ReadPrefs() failed");
   
   nsRefPtr<nsPrintSettingsX> printSettingsX(do_QueryObject(aPS));
   if (!printSettingsX)
     return NS_ERROR_NO_INTERFACE;
   rv = printSettingsX->ReadPageFormatFromPrefs();
   
-  return rv;
+  return NS_OK;
 }
 
 nsresult nsPrintOptionsX::_CreatePrintSettings(nsIPrintSettings **_retval)
 {
   nsresult rv;
   *_retval = nullptr;
 
   nsPrintSettingsX* printSettings = new nsPrintSettingsX; // does not initially ref count
--- a/widget/cocoa/nsWidgetFactory.mm
+++ b/widget/cocoa/nsWidgetFactory.mm
@@ -135,23 +135,20 @@ static const mozilla::Module::CIDEntry k
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_CLIPBOARDHELPER_CID, false, NULL, nsClipboardHelperConstructor },
   { &kNS_DRAGSERVICE_CID, false, NULL, nsDragServiceConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { &kNS_BIDIKEYBOARD_CID, false, NULL, nsBidiKeyboardConstructor },
   { &kNS_THEMERENDERER_CID, false, NULL, nsNativeThemeCocoaConstructor },
   { &kNS_SCREENMANAGER_CID, false, NULL, nsScreenManagerCocoaConstructor,
     mozilla::Module::MAIN_PROCESS_ONLY },
-  { &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor,
-    mozilla::Module::MAIN_PROCESS_ONLY },
-  { &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor,
-    mozilla::Module::MAIN_PROCESS_ONLY },
+  { &kNS_DEVICE_CONTEXT_SPEC_CID, false, NULL, nsDeviceContextSpecXConstructor },
+  { &kNS_PRINTSESSION_CID, false, NULL, nsPrintSessionConstructor },
   { &kNS_PRINTSETTINGSSERVICE_CID, false, NULL, nsPrintOptionsXConstructor },
-  { &kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor,
-    mozilla::Module::MAIN_PROCESS_ONLY },
+  { &kNS_PRINTDIALOGSERVICE_CID, false, NULL, nsPrintDialogServiceXConstructor },
   { &kNS_IDLE_SERVICE_CID, false, NULL, nsIdleServiceXConstructor },
   { &kNS_SYSTEMALERTSSERVICE_CID, false, NULL, OSXNotificationCenterConstructor },
   { &kNS_NATIVEMENUSERVICE_CID, false, NULL, nsNativeMenuServiceXConstructor },
   { &kNS_MACDOCKSUPPORT_CID, false, NULL, nsMacDockSupportConstructor },
   { &kNS_MACWEBAPPUTILS_CID, false, NULL, nsMacWebAppUtilsConstructor },
   { &kNS_STANDALONENATIVEMENU_CID, false, NULL, nsStandaloneNativeMenuConstructor },
   { &kNS_MACSYSTEMSTATUSBAR_CID, false, NULL, nsSystemStatusBarCocoaConstructor },
   { &kNS_GFXINFO_CID, false, NULL, mozilla::widget::GfxInfoConstructor },
@@ -175,23 +172,20 @@ static const mozilla::Module::ContractID
     mozilla::Module::MAIN_PROCESS_ONLY },
   { "@mozilla.org/widget/clipboardhelper;1", &kNS_CLIPBOARDHELPER_CID },
   { "@mozilla.org/widget/dragservice;1", &kNS_DRAGSERVICE_CID,
     mozilla::Module::MAIN_PROCESS_ONLY },
   { "@mozilla.org/widget/bidikeyboard;1", &kNS_BIDIKEYBOARD_CID },
   { "@mozilla.org/chrome/chrome-native-theme;1", &kNS_THEMERENDERER_CID },
   { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
     mozilla::Module::MAIN_PROCESS_ONLY },
-  { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID,
-    mozilla::Module::MAIN_PROCESS_ONLY },
-  { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID,
-    mozilla::Module::MAIN_PROCESS_ONLY },
+  { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
+  { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
   { "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
-  { NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID,
-    mozilla::Module::MAIN_PROCESS_ONLY },
+  { NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID },
   { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
   { "@mozilla.org/system-alerts-service;1", &kNS_SYSTEMALERTSSERVICE_CID },
   { "@mozilla.org/widget/nativemenuservice;1", &kNS_NATIVEMENUSERVICE_CID },
   { "@mozilla.org/widget/macdocksupport;1", &kNS_MACDOCKSUPPORT_CID },
   { "@mozilla.org/widget/mac-web-app-utils;1", &kNS_MACWEBAPPUTILS_CID },
   { "@mozilla.org/widget/standalonenativemenu;1", &kNS_STANDALONENATIVEMENU_CID },
   { "@mozilla.org/widget/macsystemstatusbar;1", &kNS_MACSYSTEMSTATUSBAR_CID },
   { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
--- a/widget/gtk/nsWidgetFactory.cpp
+++ b/widget/gtk/nsWidgetFactory.cpp
@@ -214,24 +214,20 @@ static const mozilla::Module::CIDEntry k
 #endif
     { &kNS_HTMLFORMATCONVERTER_CID, false, nullptr, nsHTMLFormatConverterConstructor },
     { &kNS_BIDIKEYBOARD_CID, false, nullptr, nsBidiKeyboardConstructor },
     { &kNS_SCREENMANAGER_CID, false, nullptr, nsScreenManagerGtkConstructor,
       Module::MAIN_PROCESS_ONLY },
     { &kNS_THEMERENDERER_CID, false, nullptr, nsNativeThemeGTKConstructor },
 #ifdef NS_PRINTING
     { &kNS_PRINTSETTINGSSERVICE_CID, false, nullptr, nsPrintOptionsGTKConstructor },
-    { &kNS_PRINTER_ENUMERATOR_CID, false, nullptr, nsPrinterEnumeratorGTKConstructor,
-      Module::MAIN_PROCESS_ONLY },
-    { &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor,
-      Module::MAIN_PROCESS_ONLY },
-    { &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecGTKConstructor,
-      Module::MAIN_PROCESS_ONLY },
-    { &kNS_PRINTDIALOGSERVICE_CID, false, nullptr, nsPrintDialogServiceGTKConstructor,
-      Module::MAIN_PROCESS_ONLY },
+    { &kNS_PRINTER_ENUMERATOR_CID, false, nullptr, nsPrinterEnumeratorGTKConstructor },
+    { &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor },
+    { &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecGTKConstructor },
+    { &kNS_PRINTDIALOGSERVICE_CID, false, nullptr, nsPrintDialogServiceGTKConstructor },
 #endif
     { &kNS_IMAGE_TO_PIXBUF_CID, false, nullptr, nsImageToPixbufConstructor },
 #if defined(MOZ_X11)
     { &kNS_IDLE_SERVICE_CID, false, nullptr, nsIdleServiceGTKConstructor },
     { &kNS_GFXINFO_CID, false, nullptr, mozilla::widget::GfxInfoConstructor },
 #endif
     { nullptr }
 };
@@ -251,24 +247,20 @@ static const mozilla::Module::ContractID
 #endif
     { "@mozilla.org/widget/htmlformatconverter;1", &kNS_HTMLFORMATCONVERTER_CID },
     { "@mozilla.org/widget/bidikeyboard;1", &kNS_BIDIKEYBOARD_CID },
     { "@mozilla.org/gfx/screenmanager;1", &kNS_SCREENMANAGER_CID,
       Module::MAIN_PROCESS_ONLY },
     { "@mozilla.org/chrome/chrome-native-theme;1", &kNS_THEMERENDERER_CID },
 #ifdef NS_PRINTING
     { "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
-    { "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID,
-      Module::MAIN_PROCESS_ONLY },
-    { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID,
-      Module::MAIN_PROCESS_ONLY },
-    { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID,
-      Module::MAIN_PROCESS_ONLY },
-    { NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID,
-      Module::MAIN_PROCESS_ONLY },
+    { "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID },
+    { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
+    { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
+    { NS_PRINTDIALOGSERVICE_CONTRACTID, &kNS_PRINTDIALOGSERVICE_CID },
 #endif
     { "@mozilla.org/widget/image-to-gdk-pixbuf;1", &kNS_IMAGE_TO_PIXBUF_CID },
 #if defined(MOZ_X11)
     { "@mozilla.org/widget/idleservice;1", &kNS_IDLE_SERVICE_CID },
     { "@mozilla.org/gfx/info;1", &kNS_GFXINFO_CID },
 #endif
     { nullptr }
 };
--- a/widget/moz.build
+++ b/widget/moz.build
@@ -97,16 +97,17 @@ EXPORTS += [
     'GfxInfoBase.h',
     'GfxInfoCollector.h',
     'InputData.h',
     'nsIDeviceContextSpec.h',
     'nsIPluginWidget.h',
     'nsIRollupListener.h',
     'nsIWidget.h',
     'nsIWidgetListener.h',
+    'nsPrintOptionsImpl.h',
     'nsWidgetInitData.h',
     'nsWidgetsCID.h',
 ]
 
 EXPORTS.mozilla += [
     'BasicEvents.h',
     'CommandList.h',
     'ContentEvents.h',
--- a/widget/nsIPrintOptions.idl
+++ b/widget/nsIPrintOptions.idl
@@ -3,33 +3,42 @@
  * 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 "nsISupports.idl"
 #include "nsIPrintSettings.idl"
 
 %{ C++
 struct nsFont;
+
+namespace mozilla {
+namespace embedding {
+  class PrintData;
+}
+}
 %}
 
 interface nsIStringEnumerator;
+interface nsIWebBrowserPrint;
 
 /**
  * Native types
  */
 [ref] native nsNativeFontRef(nsFont);
+[ref] native PrintDataRef(const mozilla::embedding::PrintData);
+[ptr] native PrintDataPtr(mozilla::embedding::PrintData);
 
 /**
  * Print options interface
  *
  * Do not attempt to freeze this API - it still needs lots of work. Consult
  * John Keiser <jkeiser@netscape.com> and Roland Mainz
  * <roland.mainz@informatik.med.uni-giessen.de> for futher details.
  */
-[scriptable, uuid(92597c2b-109b-40bb-8f93-9b9acfa31de8)]
+[scriptable, uuid(2ac74034-700e-40fd-8059-81d33223af58)]
 
 interface nsIPrintOptions : nsISupports
 {
   /**
    * Show Native Print Options dialog, this may not be supported on all platforms
    */
   void ShowPrintSetupDialog(in nsIPrintSettings aThePrintSettings);
 
@@ -52,16 +61,49 @@ interface nsIPrintOptions : nsISupports
                              aPrintSettings, out boolean aDisplayed);
 
   /**
    * Native data constants
    */
   const short kNativeDataPrintRecord        = 0;
 
   [noscript] voidPtr GetNativeData(in short aDataType);
+
+  /**
+   * Given some nsIPrintSettings and (optionally) an nsIWebBrowserPrint, populates
+   * a PrintData representing them which can be sent over IPC. Values are only
+   * ever read from aSettings and aWBP.
+   *
+   * @param aSettings
+   *        An nsIPrintSettings for a print job.
+   * @param aWBP (optional)
+   *        The nsIWebBrowserPrint for the print job.
+   * @param data
+   *        Pointer to a pre-existing PrintData to populate.
+   *
+   * @return nsresult
+   */
+  [noscript] void SerializeToPrintData(in nsIPrintSettings aPrintSettings,
+                                       in nsIWebBrowserPrint aWebBrowserPrint,
+                                       in PrintDataPtr data);
+
+  /**
+   * This function is the opposite of SerializeToPrintData, in that it takes
+   * a PrintData, and populates a pre-existing nsIPrintSettings with the data
+   * from PrintData.
+   *
+   * @param PrintData
+   *        Printing information sent through IPC.
+   * @param settings
+   *        A pre-existing nsIPrintSettings to populate with the PrintData.
+   *
+   * @return nsresult
+   */
+  [noscript] void DeserializeToPrintSettings(in PrintDataRef data,
+                                             in nsIPrintSettings aPrintSettings);
 };
 
 [scriptable, uuid(5e738fff-404c-4c94-9189-e8f2cce93e94)]
 
 interface nsIPrinterEnumerator : nsISupports
 {
   /**
    * The name of the system default printer. This name should also be
--- a/widget/nsPrintOptionsImpl.cpp
+++ b/widget/nsPrintOptionsImpl.cpp
@@ -1,13 +1,14 @@
 /* -*- 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 "mozilla/embedding/PPrinting.h"
 #include "nsPrintOptionsImpl.h"
 #include "nsReadableUtils.h"
 #include "nsPrintSettingsImpl.h"
 
 #include "nsIDOMWindow.h"
 #include "nsIServiceManager.h"
 #include "nsIDialogParamBlock.h"
 #include "nsXPCOM.h"
@@ -17,18 +18,20 @@
 #include "prprf.h"
 
 #include "nsIStringEnumerator.h"
 #include "nsISupportsPrimitives.h"
 #include "stdlib.h"
 #include "nsAutoPtr.h"
 #include "mozilla/Preferences.h"
 #include "nsPrintfCString.h"
+#include "nsIWebBrowserPrint.h"
 
 using namespace mozilla;
+using namespace mozilla::embedding;
 
 NS_IMPL_ISUPPORTS(nsPrintOptions, nsIPrintOptions, nsIPrintSettingsService)
 
 // Pref Constants
 static const char kMarginTop[]       = "print_margin_top";
 static const char kMarginLeft[]      = "print_margin_left";
 static const char kMarginBottom[]    = "print_margin_bottom";
 static const char kMarginRight[]     = "print_margin_right";
@@ -93,16 +96,231 @@ nsPrintOptions::~nsPrintOptions()
 
 nsresult
 nsPrintOptions::Init()
 {
   return NS_OK;
 }
 
 NS_IMETHODIMP
+nsPrintOptions::SerializeToPrintData(nsIPrintSettings* aSettings,
+                                     nsIWebBrowserPrint* aWBP,
+                                     PrintData* data)
+{
+  aSettings->GetStartPageRange(&data->startPageRange());
+  aSettings->GetEndPageRange(&data->endPageRange());
+
+  aSettings->GetEdgeTop(&data->edgeTop());
+  aSettings->GetEdgeLeft(&data->edgeLeft());
+  aSettings->GetEdgeBottom(&data->edgeBottom());
+  aSettings->GetEdgeRight(&data->edgeRight());
+
+  aSettings->GetMarginTop(&data->marginTop());
+  aSettings->GetMarginLeft(&data->marginLeft());
+  aSettings->GetMarginBottom(&data->marginBottom());
+  aSettings->GetMarginRight(&data->marginRight());
+  aSettings->GetUnwriteableMarginTop(&data->unwriteableMarginTop());
+  aSettings->GetUnwriteableMarginLeft(&data->unwriteableMarginLeft());
+  aSettings->GetUnwriteableMarginBottom(&data->unwriteableMarginBottom());
+  aSettings->GetUnwriteableMarginRight(&data->unwriteableMarginRight());
+
+  aSettings->GetScaling(&data->scaling());
+
+  aSettings->GetPrintBGColors(&data->printBGColors());
+  aSettings->GetPrintBGImages(&data->printBGImages());
+  aSettings->GetPrintRange(&data->printRange());
+
+  // I have no idea if I'm doing this string copying correctly...
+  nsXPIDLString title;
+  aSettings->GetTitle(getter_Copies(title));
+  data->title() = title;
+
+  nsXPIDLString docURL;
+  aSettings->GetDocURL(getter_Copies(docURL));
+  data->docURL() = docURL;
+
+  // Header strings...
+  nsXPIDLString headerStrLeft;
+  aSettings->GetHeaderStrLeft(getter_Copies(headerStrLeft));
+  data->headerStrLeft() = headerStrLeft;
+
+  nsXPIDLString headerStrCenter;
+  aSettings->GetHeaderStrCenter(getter_Copies(headerStrCenter));
+  data->headerStrCenter() = headerStrCenter;
+
+  nsXPIDLString headerStrRight;
+  aSettings->GetHeaderStrRight(getter_Copies(headerStrRight));
+  data->headerStrRight() = headerStrRight;
+
+  // Footer strings...
+  nsXPIDLString footerStrLeft;
+  aSettings->GetFooterStrLeft(getter_Copies(footerStrLeft));
+  data->footerStrLeft() = footerStrLeft;
+
+  nsXPIDLString footerStrCenter;
+  aSettings->GetFooterStrCenter(getter_Copies(footerStrCenter));
+  data->footerStrCenter() = footerStrCenter;
+
+  nsXPIDLString footerStrRight;
+  aSettings->GetFooterStrRight(getter_Copies(footerStrRight));
+  data->footerStrRight() = footerStrRight;
+
+  aSettings->GetHowToEnableFrameUI(&data->howToEnableFrameUI());
+  aSettings->GetIsCancelled(&data->isCancelled());
+  aSettings->GetPrintFrameTypeUsage(&data->printFrameTypeUsage());
+  aSettings->GetPrintFrameType(&data->printFrameType());
+  aSettings->GetPrintSilent(&data->printSilent());
+  aSettings->GetShrinkToFit(&data->shrinkToFit());
+  aSettings->GetShowPrintProgress(&data->showPrintProgress());
+
+  nsXPIDLString paperName;
+  aSettings->GetPaperName(getter_Copies(paperName));
+  data->paperName() = paperName;
+
+  aSettings->GetPaperSizeType(&data->paperSizeType());
+  aSettings->GetPaperData(&data->paperData());
+  aSettings->GetPaperWidth(&data->paperWidth());
+  aSettings->GetPaperHeight(&data->paperHeight());
+  aSettings->GetPaperSizeUnit(&data->paperSizeUnit());
+
+  nsXPIDLString plexName;
+  aSettings->GetPlexName(getter_Copies(plexName));
+  data->plexName() = plexName;
+
+  nsXPIDLString colorspace;
+  aSettings->GetColorspace(getter_Copies(colorspace));
+  data->colorspace() = colorspace;
+
+  nsXPIDLString resolutionName;
+  aSettings->GetResolutionName(getter_Copies(resolutionName));
+  data->resolutionName() = resolutionName;
+
+  aSettings->GetDownloadFonts(&data->downloadFonts());
+  aSettings->GetPrintReversed(&data->printReversed());
+  aSettings->GetPrintInColor(&data->printInColor());
+  aSettings->GetOrientation(&data->orientation());
+
+  nsXPIDLString printCommand;
+  aSettings->GetPrintCommand(getter_Copies(printCommand));
+  data->printCommand() = printCommand;
+
+  aSettings->GetNumCopies(&data->numCopies());
+
+  nsXPIDLString printerName;
+  aSettings->GetPrinterName(getter_Copies(printerName));
+  data->printerName() = printerName;
+
+  aSettings->GetPrintToFile(&data->printToFile());
+
+  nsXPIDLString toFileName;
+  aSettings->GetToFileName(getter_Copies(toFileName));
+  data->toFileName() = toFileName;
+
+  aSettings->GetOutputFormat(&data->outputFormat());
+  aSettings->GetPrintPageDelay(&data->printPageDelay());
+  aSettings->GetResolution(&data->resolution());
+  aSettings->GetDuplex(&data->duplex());
+  aSettings->GetIsInitializedFromPrinter(&data->isInitializedFromPrinter());
+  aSettings->GetIsInitializedFromPrefs(&data->isInitializedFromPrefs());
+  aSettings->GetPersistMarginBoxSettings(&data->persistMarginBoxSettings());
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintOptions::DeserializeToPrintSettings(const PrintData& data,
+                                           nsIPrintSettings* settings)
+{
+  settings->SetStartPageRange(data.startPageRange());
+  settings->SetEndPageRange(data.endPageRange());
+
+  settings->SetEdgeTop(data.edgeTop());
+  settings->SetEdgeLeft(data.edgeLeft());
+  settings->SetEdgeBottom(data.edgeBottom());
+  settings->SetEdgeRight(data.edgeRight());
+
+  settings->SetMarginTop(data.marginTop());
+  settings->SetMarginLeft(data.marginLeft());
+  settings->SetMarginBottom(data.marginBottom());
+  settings->SetMarginRight(data.marginRight());
+  settings->SetUnwriteableMarginTop(data.unwriteableMarginTop());
+  settings->SetUnwriteableMarginLeft(data.unwriteableMarginLeft());
+  settings->SetUnwriteableMarginBottom(data.unwriteableMarginBottom());
+  settings->SetUnwriteableMarginRight(data.unwriteableMarginRight());
+
+  settings->SetScaling(data.scaling());
+
+  settings->SetPrintBGColors(data.printBGColors());
+  settings->SetPrintBGImages(data.printBGImages());
+  settings->SetPrintRange(data.printRange());
+
+  // I have no idea if I'm doing this string copying correctly...
+  settings->SetTitle(data.title().get());
+  settings->SetDocURL(data.docURL().get());
+
+  // Header strings...
+  settings->SetHeaderStrLeft(data.headerStrLeft().get());
+  settings->SetHeaderStrCenter(data.headerStrCenter().get());
+  settings->SetHeaderStrRight(data.headerStrRight().get());
+
+  // Footer strings...
+  settings->SetFooterStrLeft(data.footerStrLeft().get());
+  settings->SetFooterStrCenter(data.footerStrCenter().get());
+  settings->SetFooterStrRight(data.footerStrRight().get());
+
+  settings->SetHowToEnableFrameUI(data.howToEnableFrameUI());
+  settings->SetIsCancelled(data.isCancelled());
+  settings->SetPrintFrameTypeUsage(data.printFrameTypeUsage());
+  settings->SetPrintFrameType(data.printFrameType());
+  settings->SetPrintSilent(data.printSilent());
+  settings->SetShrinkToFit(data.shrinkToFit());
+  settings->SetShowPrintProgress(data.showPrintProgress());
+
+  settings->SetPaperName(data.paperName().get());
+
+  settings->SetPaperSizeType(data.paperSizeType());
+  settings->SetPaperData(data.paperData());
+  settings->SetPaperWidth(data.paperWidth());
+  settings->SetPaperHeight(data.paperHeight());
+  settings->SetPaperSizeUnit(data.paperSizeUnit());
+
+  settings->SetPlexName(data.plexName().get());
+
+  settings->SetColorspace(data.colorspace().get());
+
+  settings->SetResolutionName(data.resolutionName().get());
+
+  settings->SetDownloadFonts(data.downloadFonts());
+  settings->SetPrintReversed(data.printReversed());
+  settings->SetPrintInColor(data.printInColor());
+  settings->SetOrientation(data.orientation());
+
+  settings->SetPrintCommand(data.printCommand().get());
+
+  settings->SetNumCopies(data.numCopies());
+
+  settings->SetPrinterName(data.printerName().get());
+
+  settings->SetPrintToFile(data.printToFile());
+
+  settings->SetToFileName(data.toFileName().get());
+
+  settings->SetOutputFormat(data.outputFormat());
+  settings->SetPrintPageDelay(data.printPageDelay());
+  settings->SetResolution(data.resolution());
+  settings->SetDuplex(data.duplex());
+  settings->SetIsInitializedFromPrinter(data.isInitializedFromPrinter());
+  settings->SetIsInitializedFromPrefs(data.isInitializedFromPrefs());
+  settings->SetPersistMarginBoxSettings(data.persistMarginBoxSettings());
+
+  return NS_OK;
+}
+
+
+NS_IMETHODIMP
 nsPrintOptions::ShowPrintSetupDialog(nsIPrintSettings *aPS)
 {
   NS_ENSURE_ARG_POINTER(aPS);
   nsresult rv;
 
   // create a nsISupportsArray of the parameters
   // being passed to the window
   nsCOMPtr<nsISupportsArray> array;
--- a/widget/nsPrintOptionsImpl.h
+++ b/widget/nsPrintOptionsImpl.h
@@ -2,22 +2,26 @@
  *
  * 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 nsPrintOptionsImpl_h__
 #define nsPrintOptionsImpl_h__
 
+#include "mozilla/embedding/PPrinting.h"
 #include "nsCOMPtr.h"
 #include "nsIPrintOptions.h"
 #include "nsIPrintSettingsService.h"
 #include "nsString.h"
 #include "nsFont.h"
 
+class nsIPrintSettings;
+class nsIWebBrowserPrint;
+
 /**
  *   Class nsPrintOptions
  */
 class nsPrintOptions : public nsIPrintOptions,
                        public nsIPrintSettingsService
 {
 public:
   NS_DECL_ISUPPORTS
--- a/widget/windows/nsPrintOptionsWin.cpp
+++ b/widget/windows/nsPrintOptionsWin.cpp
@@ -1,20 +1,25 @@
 /* -*- 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 "nsCOMPtr.h"
 #include "nsPrintOptionsWin.h"
 #include "nsPrintSettingsWin.h"
+#include "nsPrintDialogUtil.h"
 
 #include "nsGfxCIID.h"
 #include "nsIServiceManager.h"
+#include "nsIWebBrowserPrint.h"
+
 const char kPrinterEnumeratorContractID[] = "@mozilla.org/gfx/printerenumerator;1";
 
+using namespace mozilla::embedding;
+
 /** ---------------------------------------------------
  *  See documentation in nsPrintOptionsWin.h
  *	@update 6/21/00 dwc
  */
 nsPrintOptionsWin::nsPrintOptionsWin()
 {
 
 }
@@ -22,16 +27,81 @@ nsPrintOptionsWin::nsPrintOptionsWin()
 /** ---------------------------------------------------
  *  See documentation in nsPrintOptionsImpl.h
  *	@update 6/21/00 dwc
  */
 nsPrintOptionsWin::~nsPrintOptionsWin()
 {
 }
 
+NS_IMETHODIMP
+nsPrintOptionsWin::SerializeToPrintData(nsIPrintSettings* aSettings,
+                                        nsIWebBrowserPrint* aWBP,
+                                        PrintData* data)
+{
+  nsresult rv = nsPrintOptions::SerializeToPrintData(aSettings, aWBP, data);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  // Windows wants this information for its print dialogs
+  if (aWBP) {
+    aWBP->GetIsFramesetDocument(&data->isFramesetDocument());
+    aWBP->GetIsFramesetFrameSelected(&data->isFramesetFrameSelected());
+    aWBP->GetIsIFrameSelected(&data->isIFrameSelected());
+    aWBP->GetIsRangeSelection(&data->isRangeSelection());
+  }
+
+  nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(aSettings);
+  if (!psWin) {
+    return NS_ERROR_FAILURE;
+  }
+
+  char16_t* deviceName;
+  char16_t* driverName;
+
+  psWin->GetDeviceName(&deviceName);
+  psWin->GetDriverName(&driverName);
+
+  data->deviceName().Assign(deviceName);
+  data->driverName().Assign(driverName);
+
+  free(deviceName);
+  free(driverName);
+
+  return NS_OK;
+}
+
+NS_IMETHODIMP
+nsPrintOptionsWin::DeserializeToPrintSettings(const PrintData& data,
+                                              nsIPrintSettings* settings)
+{
+  nsresult rv = nsPrintOptions::DeserializeToPrintSettings(data, settings);
+  NS_ENSURE_SUCCESS(rv, rv);
+
+  nsCOMPtr<nsIPrintSettingsWin> psWin = do_QueryInterface(settings);
+  if (!settings) {
+    return NS_ERROR_FAILURE;
+  }
+
+  psWin->SetDeviceName(data.deviceName().get());
+  psWin->SetDriverName(data.driverName().get());
+
+  // We also need to prepare a DevMode and stuff it into our newly
+  // created nsIPrintSettings...
+  nsXPIDLString printerName;
+  settings->GetPrinterName(getter_Copies(printerName));
+  HGLOBAL gDevMode = CreateGlobalDevModeAndInit(printerName, settings);
+  LPDEVMODEW devMode = (LPDEVMODEW)::GlobalLock(gDevMode);
+  psWin->SetDevMode(devMode);
+
+  ::GlobalUnlock(gDevMode);
+  ::GlobalFree(gDevMode);
+
+  return NS_OK;
+}
+
 /* nsIPrintSettings CreatePrintSettings (); */
 nsresult nsPrintOptionsWin::_CreatePrintSettings(nsIPrintSettings **_retval)
 {
   *_retval = nullptr;
   nsPrintSettingsWin* printSettings = new nsPrintSettingsWin(); // does not initially ref count
   NS_ENSURE_TRUE(printSettings, NS_ERROR_OUT_OF_MEMORY);
 
   NS_ADDREF(*_retval = printSettings); // ref count
--- a/widget/windows/nsPrintOptionsWin.h
+++ b/widget/windows/nsPrintOptionsWin.h
@@ -2,26 +2,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 nsPrintOptionsWin_h__
 #define nsPrintOptionsWin_h__
 
+#include "mozilla/embedding/PPrinting.h"
 #include "nsPrintOptionsImpl.h"  
 
+class nsIPrintSettings;
+class nsIWebBrowserPrint;
 
 //*****************************************************************************
 //***    nsPrintOptions
 //*****************************************************************************
 class nsPrintOptionsWin : public nsPrintOptions
 {
 public:
   nsPrintOptionsWin();
   virtual ~nsPrintOptionsWin();
 
+  NS_IMETHODIMP SerializeToPrintData(nsIPrintSettings* aSettings,
+                                     nsIWebBrowserPrint* aWBP,
+                                     mozilla::embedding::PrintData* data);
+  NS_IMETHODIMP DeserializeToPrintSettings(const mozilla::embedding::PrintData& data,
+                                           nsIPrintSettings* settings);
+
   virtual nsresult _CreatePrintSettings(nsIPrintSettings **_retval);
 };
 
 
 
 #endif /* nsPrintOptions_h__ */
--- a/widget/windows/nsWidgetFactory.cpp
+++ b/widget/windows/nsWidgetFactory.cpp
@@ -239,22 +239,19 @@ static const mozilla::Module::CIDEntry k
   { &kNS_WIN_JUMPLISTSHORTCUT_CID, false, nullptr, JumpListShortcutConstructor },
   { &kNS_DRAGSERVICE_CID, false, nullptr, nsDragServiceConstructor, Module::MAIN_PROCESS_ONLY },
   { &kNS_BIDIKEYBOARD_CID, false, nullptr, nsBidiKeyboardConstructor },
 #ifdef MOZ_METRO
   { &kNS_WIN_METROUTILS_CID, false, nullptr, nsWinMetroUtilsConstructor },
 #endif
 #ifdef NS_PRINTING
   { &kNS_PRINTSETTINGSSERVICE_CID, false, nullptr, nsPrintOptionsWinConstructor },
-  { &kNS_PRINTER_ENUMERATOR_CID, false, nullptr, nsPrinterEnumeratorWinConstructor,
-    Module::MAIN_PROCESS_ONLY },
-  { &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor,
-    Module::MAIN_PROCESS_ONLY },
-  { &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecWinConstructor,
-    Module::MAIN_PROCESS_ONLY },
+  { &kNS_PRINTER_ENUMERATOR_CID, false, nullptr, nsPrinterEnumeratorWinConstructor },
+  { &kNS_PRINTSESSION_CID, false, nullptr, nsPrintSessionConstructor },
+  { &kNS_DEVICE_CONTEXT_SPEC_CID, false, nullptr, nsDeviceContextSpecWinConstructor },
 #endif
   { nullptr }
 };
 
 static const mozilla::Module::ContractIDEntry kWidgetContracts[] = {
   { "@mozilla.org/widgets/window/win;1", &kNS_WINDOW_CID },
   { "@mozilla.org/widgets/child_window/win;1", &kNS_CHILD_CID },
   { "@mozilla.org/filepicker;1", &kNS_FILEPICKER_CID, Module::MAIN_PROCESS_ONLY },
@@ -277,22 +274,19 @@ static const mozilla::Module::ContractID
   { "@mozilla.org/windows-jumplistshortcut;1", &kNS_WIN_JUMPLISTSHORTCUT_CID },
   { "@mozilla.org/widget/dragservice;1", &kNS_DRAGSERVICE_CID, Module::MAIN_PROCESS_ONLY },
   { "@mozilla.org/widget/bidikeyboard;1", &kNS_BIDIKEYBOARD_CID },
 #ifdef MOZ_METRO
   { "@mozilla.org/windows-metroutils;1", &kNS_WIN_METROUTILS_CID },
 #endif
 #ifdef NS_PRINTING
   { "@mozilla.org/gfx/printsettings-service;1", &kNS_PRINTSETTINGSSERVICE_CID },
-  { "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID,
-    Module::MAIN_PROCESS_ONLY },
-  { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID,
-    Module::MAIN_PROCESS_ONLY },
-  { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID,
-    Module::MAIN_PROCESS_ONLY },
+  { "@mozilla.org/gfx/printerenumerator;1", &kNS_PRINTER_ENUMERATOR_CID },
+  { "@mozilla.org/gfx/printsession;1", &kNS_PRINTSESSION_CID },
+  { "@mozilla.org/gfx/devicecontextspec;1", &kNS_DEVICE_CONTEXT_SPEC_CID },
 #endif
   { nullptr }
 };
 
 static void
 nsWidgetWindowsModuleDtor()
 {
   KeyboardLayout::Shutdown();