Bug 1715716 [wpt PR 29323] - Use unittest.mock instead of the mock package, a=testonly
[gecko.git] / widget / nsPrinterCUPS.h
bloba917a0d6bc3d2af29ca6a68c4904f0d917d96dd1
1 /* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 2; -*- */
2 /* This Source Code Form is subject to the terms of the Mozilla Public
3 * License, v. 2.0. If a copy of the MPL was not distributed with this
4 * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
6 #ifndef nsPrinterCUPS_h___
7 #define nsPrinterCUPS_h___
9 #include "nsPrinterBase.h"
10 #include "nsPrintSettingsImpl.h"
11 #include "nsCUPSShim.h"
12 #include "nsString.h"
14 #include "mozilla/DataMutex.h"
15 #include "mozilla/FunctionRef.h"
16 #include "mozilla/RecursiveMutex.h"
18 /**
19 * @brief Interface to help implementing nsIPrinter using a CUPS printer.
21 class nsPrinterCUPS final : public nsPrinterBase {
22 public:
23 NS_IMETHOD GetName(nsAString& aName) override;
24 NS_IMETHOD GetSystemName(nsAString& aName) override;
25 bool SupportsDuplex() const final;
26 bool SupportsColor() const final;
27 bool SupportsMonochrome() const final;
28 bool SupportsCollation() const final;
29 PrinterInfo CreatePrinterInfo() const final;
30 MarginDouble GetMarginsForPaper(nsString aPaperId) const final {
31 MOZ_ASSERT_UNREACHABLE(
32 "The CUPS API requires us to always get the margin when fetching the "
33 "paper list so there should be no need to query it separately");
34 return {};
37 nsPrinterCUPS() = delete;
39 nsPrinterCUPS(const mozilla::CommonPaperInfoArray* aArray,
40 const nsCUPSShim& aShim, nsString aDisplayName,
41 cups_dest_t* aPrinter)
42 : nsPrinterBase(aArray),
43 mShim(aShim),
44 mDisplayName(std::move(aDisplayName)),
45 mPrinter(aPrinter),
46 mPrinterInfoMutex("nsPrinterCUPS::mPrinterInfoMutex") {}
48 static void ForEachExtraMonochromeSetting(
49 mozilla::FunctionRef<void(const nsACString&, const nsACString&)>);
51 private:
52 struct CUPSPrinterInfo {
53 cups_dinfo_t* mPrinterInfo = nullptr;
54 uint64_t mCUPSMajor = 0;
55 uint64_t mCUPSMinor = 0;
56 uint64_t mCUPSPatch = 0;
58 // Whether we have attempted to fetch mPrinterInfo with CUPS_HTTP_DEFAULT.
59 bool mTriedInitWithDefault = false;
60 // Whether we have attempted to fetch mPrinterInfo with a connection.
61 bool mTriedInitWithConnection = false;
62 CUPSPrinterInfo() = default;
63 CUPSPrinterInfo(const CUPSPrinterInfo&) = delete;
64 CUPSPrinterInfo(CUPSPrinterInfo&&) = delete;
67 using PrinterInfoMutex =
68 mozilla::DataMutexBase<CUPSPrinterInfo, mozilla::RecursiveMutex>;
70 using PrinterInfoLock = PrinterInfoMutex::AutoLock;
72 ~nsPrinterCUPS();
74 /**
75 * Retrieves the localized name for a given media (paper).
76 * Returns nullptr if the name cannot be localized.
78 const char* LocalizeMediaName(http_t& aConnection, cups_size_t& aMedia) const;
80 void GetPrinterName(nsAString& aName) const;
82 // Little util for getting support flags using the direct CUPS names.
83 bool Supports(const char* aOption, const char* aValue) const;
85 // Returns support value if CUPS meets the minimum version, otherwise returns
86 // |aDefault|
87 bool IsCUPSVersionAtLeast(uint64_t aCUPSMajor, uint64_t aCUPSMinor,
88 uint64_t aCUPSPatch) const;
90 class Connection {
91 public:
92 http_t* GetConnection(cups_dest_t* aDest);
94 inline explicit Connection(const nsCUPSShim& aShim) : mShim(aShim) {}
95 Connection() = delete;
96 ~Connection();
98 protected:
99 const nsCUPSShim& mShim;
100 http_t* mConnection = CUPS_HTTP_DEFAULT;
101 bool mWasInited = false;
104 PrintSettingsInitializer DefaultSettings(Connection& aConnection) const;
105 nsTArray<mozilla::PaperInfo> PaperList(Connection& aConnection) const;
107 * Attempts to populate the CUPSPrinterInfo object.
108 * This usually works with the CUPS default connection,
109 * but has been known to require an established connection
110 * on older versions of Ubuntu (18 and below).
112 PrinterInfoLock TryEnsurePrinterInfo(
113 http_t* const aConnection = CUPS_HTTP_DEFAULT) const;
115 const nsCUPSShim& mShim;
116 nsString mDisplayName;
117 cups_dest_t* mPrinter;
118 mutable PrinterInfoMutex mPrinterInfoMutex;
121 // There's no standard setting in Core Printing for monochrome. Or rather,
122 // there is (PMSetColorMode) but it does nothing. Similarly, the relevant gtk
123 // setting only works on Windows, yay.
125 // So on CUPS the right setting to use depends on the print driver. So we set /
126 // look for a variety of driver-specific keys that are known to work across
127 // printers.
129 // We set all the known settings, because the alternative to that is parsing ppd
130 // files from the printer and find the relevant known choices that can apply,
131 // and that is a lot more complex, similarly sketchy (requires the same amount
132 // of driver-specific knowledge), and requires using deprecated CUPS APIs.
133 #define CUPS_EACH_MONOCHROME_PRINTER_SETTING(macro_) \
134 macro_("ColorModel", "Gray") /* Generic */ \
135 macro_("BRMonoColor", "Mono") /* Brother */ \
136 macro_("BRPrintQuality", "Black") /* Brother */ \
137 macro_("CNIJGrayScale", "1") /* Canon */ \
138 macro_("INK", "MONO") /* Epson */ \
139 macro_("HPColorMode", "GrayscalePrint") /* HP */ \
140 macro_("ColorMode", "Mono") /* Samsung */ \
141 macro_("PrintoutMode", "Normal.Gray") /* Foomatic */ \
142 macro_("ProcessColorModel", "Mono") /* Samsung */ \
143 macro_("ARCMode", "CMBW") /* Sharp */ \
144 macro_("XRXColor", "BW") /* Xerox */ \
145 macro_("XROutputColor", "PrintAsGrayscale") /* Xerox, bug 1676191#c32 */ \
146 macro_("SelectColor", "Grayscale") /* Konica Minolta */ \
147 macro_("OKControl", "Gray") /* Oki */ \
148 macro_("BLW", "TrueM") /* Lexmark */ \
149 macro_("EPRendering", "None") /* Epson */
151 #endif /* nsPrinterCUPS_h___ */