Bug 1658073 - Add SupportsCollation to nsIPrinter r=jwatt,emilio
authorEmily McDonough <emcdonough@mozilla.com>
Fri, 14 Aug 2020 20:41:59 +0000
changeset 544726 f7bdfe3fe0b3dd8c4fcab827a30cc6c72b5d2d65
parent 544725 5254d40a3e218a564bcec311190a7b3339edaea1
child 544727 5b006156349e160b0c31386df43c73665a7a5af5
push id37700
push userdluca@mozilla.com
push dateSat, 15 Aug 2020 09:31:17 +0000
treeherdermozilla-central@7dcb2bda35c7 [default view] [failures only]
perfherder[talos] [build metrics] [platform microbench] (compared to previous push)
reviewersjwatt, emilio
bugs1658073
milestone81.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 1658073 - Add SupportsCollation to nsIPrinter r=jwatt,emilio Differential Revision: https://phabricator.services.mozilla.com/D86643
widget/nsIPrinter.idl
widget/nsPrinterBase.cpp
widget/nsPrinterBase.h
widget/nsPrinterCUPS.cpp
widget/nsPrinterCUPS.h
widget/windows/nsPrinterWin.cpp
widget/windows/nsPrinterWin.h
--- a/widget/nsIPrinter.idl
+++ b/widget/nsIPrinter.idl
@@ -30,9 +30,16 @@ interface nsIPrinter : nsISupports
   readonly attribute Promise supportsDuplex;
 
   /**
    * Returns a Promise that resolves to true or false to indicate whether this
    * printer supports color printing.
    */
   [implicit_jscontext]
   readonly attribute Promise supportsColor;
+
+  /**
+   * Returns a Promise that resolves to true or false to indicate whether this
+   * printer supports collation.
+   */
+  [implicit_jscontext]
+  readonly attribute Promise supportsCollation;
 };
--- a/widget/nsPrinterBase.cpp
+++ b/widget/nsPrinterBase.cpp
@@ -74,16 +74,23 @@ NS_IMETHODIMP nsPrinterBase::GetSupports
 
 NS_IMETHODIMP nsPrinterBase::GetSupportsColor(JSContext* aCx,
                                               Promise** aResultPromise) {
   return AsyncPromiseAttributeGetter(aCx, aResultPromise,
                                      AsyncAttribute::SupportsColor,
                                      &nsPrinterBase::SupportsColor);
 }
 
+NS_IMETHODIMP nsPrinterBase::GetSupportsCollation(JSContext* aCx,
+                                                  Promise** aResultPromise) {
+  return AsyncPromiseAttributeGetter(aCx, aResultPromise,
+                                     AsyncAttribute::SupportsCollation,
+                                     &nsPrinterBase::SupportsCollation);
+}
+
 NS_IMETHODIMP nsPrinterBase::GetPaperList(JSContext* aCx,
                                           Promise** aResultPromise) {
   return AsyncPromiseAttributeGetter(aCx, aResultPromise,
                                      AsyncAttribute::PaperList,
                                      &nsPrinterBase::PaperList);
 }
 
 void nsPrinterBase::QueryMarginsForPaper(Promise& aPromise, uint64_t aPaperId) {
--- a/widget/nsPrinterBase.h
+++ b/widget/nsPrinterBase.h
@@ -26,31 +26,33 @@ class Promise;
 
 class nsPrinterBase : public nsIPrinter {
  public:
   using Promise = mozilla::dom::Promise;
   using MarginDouble = mozilla::gfx::MarginDouble;
 
   NS_IMETHOD GetSupportsDuplex(JSContext*, Promise**) final;
   NS_IMETHOD GetSupportsColor(JSContext*, Promise**) final;
+  NS_IMETHOD GetSupportsCollation(JSContext*, Promise**) final;
   NS_IMETHOD GetPaperList(JSContext*, Promise**) final;
 
   NS_DECL_CYCLE_COLLECTING_ISUPPORTS
   NS_DECL_CYCLE_COLLECTION_CLASS(nsPrinterBase)
 
   // No copy or move, we're an identity.
   nsPrinterBase(const nsPrinterBase&) = delete;
   nsPrinterBase(nsPrinterBase&&) = delete;
 
   void QueryMarginsForPaper(Promise&, uint64_t aPaperId);
 
  private:
   enum class AsyncAttribute {
     SupportsDuplex = 0,
     SupportsColor,
+    SupportsCollation,
     PaperList,
     // Just a guard.
     Last,
   };
 
   template <typename Result, typename... Args>
   using BackgroundTask = Result (nsPrinterBase::*)(Args...) const;
 
@@ -63,16 +65,17 @@ class nsPrinterBase : public nsIPrinter 
  protected:
   nsPrinterBase();
   virtual ~nsPrinterBase();
 
   // Implementation-specific methods. These must not make assumptions about
   // which thread they run on.
   virtual bool SupportsDuplex() const = 0;
   virtual bool SupportsColor() const = 0;
+  virtual bool SupportsCollation() const = 0;
   virtual nsTArray<mozilla::PaperInfo> PaperList() const = 0;
   virtual MarginDouble GetMarginsForPaper(uint64_t aPaperId) const = 0;
 
  private:
   mozilla::EnumeratedArray<AsyncAttribute, AsyncAttribute::Last,
                            RefPtr<Promise>>
       mAsyncAttributePromises;
 };
--- a/widget/nsPrinterCUPS.cpp
+++ b/widget/nsPrinterCUPS.cpp
@@ -2,17 +2,17 @@
 /* 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 "nsPrinterCUPS.h"
 #include "nsPaper.h"
 #include "nsPrinterBase.h"
 
-using namespace mozilla;
+#include "plstr.h"
 
 nsPrinterCUPS::~nsPrinterCUPS() {
   if (mPrinterInfo) {
     mShim.cupsFreeDestInfo(mPrinterInfo);
     mPrinterInfo = nullptr;
   }
   if (mPrinter) {
     mShim.cupsFreeDests(1, mPrinter);
@@ -34,16 +34,29 @@ nsPrinterCUPS::GetName(nsAString& aName)
 bool nsPrinterCUPS::SupportsDuplex() const {
   return Supports(CUPS_SIDES, CUPS_SIDES_TWO_SIDED_PORTRAIT);
 }
 
 bool nsPrinterCUPS::SupportsColor() const {
   return Supports(CUPS_PRINT_COLOR_MODE, CUPS_PRINT_COLOR_MODE_COLOR);
 }
 
+bool nsPrinterCUPS::SupportsCollation() const {
+  // We can't depend on cupsGetIntegerOption existing.
+  const char* const value = mShim.cupsGetOption(
+      "printer-type", mPrinter->num_options, mPrinter->options);
+  if (!value) {
+    return false;
+  }
+  // If the value is non-numeric, then atoi will return 0, which will still
+  // cause this function to return false.
+  const int type = atoi(value);
+  return type & CUPS_PRINTER_COLLATE;
+}
+
 bool nsPrinterCUPS::Supports(const char* option, const char* value) const {
   MOZ_ASSERT(mPrinterInfo);
   return mShim.cupsCheckDestSupported(CUPS_HTTP_DEFAULT, mPrinter, mPrinterInfo,
                                       option, value);
 }
 
 nsTArray<PaperInfo> nsPrinterCUPS::PaperList() const {
   if (!mPrinterInfo) {
--- a/widget/nsPrinterCUPS.h
+++ b/widget/nsPrinterCUPS.h
@@ -13,16 +13,17 @@
 /**
  * @brief Interface to help implementing nsIPrinter using a CUPS printer.
  */
 class nsPrinterCUPS final : public nsPrinterBase {
  public:
   NS_IMETHOD GetName(nsAString& aName) override;
   bool SupportsDuplex() const final;
   bool SupportsColor() const final;
+  bool SupportsCollation() const final;
   nsTArray<mozilla::PaperInfo> PaperList() const final;
   MarginDouble GetMarginsForPaper(uint64_t) const final {
     MOZ_ASSERT_UNREACHABLE(
         "The CUPS API requires us to always get the margin when fetching the "
         "paper list so there should be no need to query it separately");
     return {};
   }
 
--- a/widget/windows/nsPrinterWin.cpp
+++ b/widget/windows/nsPrinterWin.cpp
@@ -73,16 +73,21 @@ bool nsPrinterWin::SupportsDuplex() cons
                                nullptr) == 1;
 }
 
 bool nsPrinterWin::SupportsColor() const {
   return ::DeviceCapabilitiesW(mName.get(), nullptr, DC_COLORDEVICE, nullptr,
                                nullptr) == 1;
 }
 
+bool nsPrinterWin::SupportsCollation() const {
+  return ::DeviceCapabilitiesW(mName.get(), nullptr, DC_COLLATE, nullptr,
+                               nullptr) == 1;
+}
+
 nsTArray<mozilla::PaperInfo> nsPrinterWin::PaperList() const {
   // Paper names are returned in 64 long character buffers.
   auto paperNames =
       GetDeviceCapabilityArray<Array<wchar_t, 64>>(mName.get(), DC_PAPERNAMES);
 
   // Paper IDs are returned as WORDs.
   auto paperIds = GetDeviceCapabilityArray<WORD>(mName.get(), DC_PAPERS);
 
--- a/widget/windows/nsPrinterWin.h
+++ b/widget/windows/nsPrinterWin.h
@@ -9,16 +9,17 @@
 #include "nsPrinterBase.h"
 
 class nsPrinterWin final : public nsPrinterBase {
  public:
   NS_IMETHOD GetName(nsAString& aName) override;
 
   bool SupportsDuplex() const final;
   bool SupportsColor() const final;
+  bool SupportsCollation() const final;
   nsTArray<mozilla::PaperInfo> PaperList() const final;
   MarginDouble GetMarginsForPaper(uint64_t aId) const final;
 
   nsPrinterWin() = delete;
   static already_AddRefed<nsPrinterWin> Create(const nsAString& aName);
 
  private:
   explicit nsPrinterWin(const nsAString& aName);