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 212764 a9530d7f005aa70510c19c11c1eaaaf8a27af0fe
parent 212763 24a95294f600d50960d388151fa1e8d28d0474ba
child 212765 b89b931eec260a0ff12826e361353f26e2aeea8c
push id9615
push usermconley@mozilla.com
push dateTue, 28 Oct 2014 20:56:31 +0000
treeherderfx-team@a9530d7f005a [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersblassey
bugs1082579
milestone36.0a1
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();