2020-07-29 21:02:21 +03:00
|
|
|
/* -*- Mode: C++; c-basic-offset: 2; indent-tabs-mode: nil; tab-width: 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 "nsPrinterCUPS.h"
|
2020-09-10 02:56:13 +03:00
|
|
|
|
|
|
|
#include "mozilla/GkRustUtils.h"
|
2020-10-23 14:58:42 +03:00
|
|
|
#include "mozilla/StaticPrefs_print.h"
|
2020-09-30 21:37:50 +03:00
|
|
|
#include "nsTHashtable.h"
|
2020-08-05 04:24:49 +03:00
|
|
|
#include "nsPaper.h"
|
|
|
|
#include "nsPrinterBase.h"
|
2020-08-20 09:11:08 +03:00
|
|
|
#include "nsPrintSettingsImpl.h"
|
2020-08-14 23:41:59 +03:00
|
|
|
#include "plstr.h"
|
2020-08-05 14:26:13 +03:00
|
|
|
|
2020-09-07 21:58:48 +03:00
|
|
|
using namespace mozilla;
|
|
|
|
|
2020-09-10 02:56:13 +03:00
|
|
|
// Requested attributes for IPP requests, just the CUPS version now.
|
|
|
|
static constexpr Array<const char* const, 1> requestedAttributes{
|
|
|
|
"cups-version"};
|
|
|
|
|
2020-10-14 00:52:04 +03:00
|
|
|
static constexpr double kPointsPerHundredthMillimeter = 72.0 / 2540.0;
|
|
|
|
|
|
|
|
static PaperInfo MakePaperInfo(const nsAString& aName,
|
|
|
|
const cups_size_t& aMedia) {
|
|
|
|
// XXX Do we actually have the guarantee that this is utf-8?
|
2020-09-17 23:05:08 +03:00
|
|
|
NS_ConvertUTF8toUTF16 paperId(aMedia.media); // internal paper name/ID
|
2020-08-20 09:11:08 +03:00
|
|
|
return PaperInfo(
|
2020-10-14 00:52:04 +03:00
|
|
|
paperId, aName,
|
2020-08-20 09:11:08 +03:00
|
|
|
{aMedia.width * kPointsPerHundredthMillimeter,
|
|
|
|
aMedia.length * kPointsPerHundredthMillimeter},
|
2020-09-07 21:58:48 +03:00
|
|
|
Some(gfx::MarginDouble{aMedia.top * kPointsPerHundredthMillimeter,
|
|
|
|
aMedia.right * kPointsPerHundredthMillimeter,
|
|
|
|
aMedia.bottom * kPointsPerHundredthMillimeter,
|
|
|
|
aMedia.left * kPointsPerHundredthMillimeter}));
|
2020-08-20 09:11:08 +03:00
|
|
|
}
|
|
|
|
|
2020-09-10 02:56:13 +03:00
|
|
|
// Fetches the CUPS version for the print server controlling the printer. This
|
|
|
|
// will only modify the output arguments if the fetch succeeds.
|
|
|
|
static void FetchCUPSVersionForPrinter(const nsCUPSShim& aShim,
|
|
|
|
const cups_dest_t* const aDest,
|
|
|
|
uint64_t& aOutMajor, uint64_t& aOutMinor,
|
|
|
|
uint64_t& aOutPatch) {
|
|
|
|
// Make an IPP request to the server for the printer.
|
|
|
|
const char* const uri = aShim.cupsGetOption(
|
|
|
|
"printer-uri-supported", aDest->num_options, aDest->options);
|
|
|
|
if (!uri) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
ipp_t* const ippRequest = aShim.ippNewRequest(IPP_OP_GET_PRINTER_ATTRIBUTES);
|
|
|
|
|
|
|
|
// Set the URI we want to use.
|
|
|
|
aShim.ippAddString(ippRequest, IPP_TAG_OPERATION, IPP_TAG_URI, "printer-uri",
|
|
|
|
nullptr, uri);
|
|
|
|
|
|
|
|
// Set the attributes to request.
|
|
|
|
aShim.ippAddStrings(ippRequest, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
|
|
|
|
"requested-attributes", requestedAttributes.Length,
|
|
|
|
nullptr, &(requestedAttributes[0]));
|
|
|
|
|
|
|
|
// Use the default HTTP connection to query the CUPS server itself to get
|
|
|
|
// the CUPS version.
|
|
|
|
// Note that cupsDoRequest will delete the request whether it succeeds or
|
|
|
|
// fails, so we should not use ippDelete on it.
|
|
|
|
if (ipp_t* const ippResponse =
|
|
|
|
aShim.cupsDoRequest(CUPS_HTTP_DEFAULT, ippRequest, "/")) {
|
|
|
|
ipp_attribute_t* const versionAttrib =
|
|
|
|
aShim.ippFindAttribute(ippResponse, "cups-version", IPP_TAG_TEXT);
|
|
|
|
if (versionAttrib && aShim.ippGetCount(versionAttrib) == 1) {
|
|
|
|
const char* versionString = aShim.ippGetString(versionAttrib, 0, nullptr);
|
|
|
|
MOZ_ASSERT(versionString);
|
|
|
|
// On error, GkRustUtils::ParseSemVer will not modify its arguments.
|
|
|
|
GkRustUtils::ParseSemVer(
|
|
|
|
nsDependentCSubstring{MakeStringSpan(versionString)}, aOutMajor,
|
|
|
|
aOutMinor, aOutPatch);
|
|
|
|
}
|
|
|
|
aShim.ippDelete(ippResponse);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2020-07-29 21:02:21 +03:00
|
|
|
nsPrinterCUPS::~nsPrinterCUPS() {
|
2020-09-10 02:51:59 +03:00
|
|
|
auto printerInfoLock = mPrinterInfoMutex.Lock();
|
2020-09-10 02:56:13 +03:00
|
|
|
if (printerInfoLock->mPrinterInfo) {
|
|
|
|
mShim.cupsFreeDestInfo(printerInfoLock->mPrinterInfo);
|
2020-07-29 21:02:21 +03:00
|
|
|
}
|
|
|
|
if (mPrinter) {
|
2020-08-06 20:01:21 +03:00
|
|
|
mShim.cupsFreeDests(1, mPrinter);
|
2020-08-05 04:24:49 +03:00
|
|
|
mPrinter = nullptr;
|
2020-07-29 21:02:21 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrinterCUPS::GetName(nsAString& aName) {
|
2020-08-20 09:11:08 +03:00
|
|
|
GetPrinterName(aName);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2020-09-16 00:23:27 +03:00
|
|
|
NS_IMETHODIMP
|
|
|
|
nsPrinterCUPS::GetSystemName(nsAString& aName) {
|
|
|
|
CopyUTF8toUTF16(MakeStringSpan(mPrinter->name), aName);
|
|
|
|
return NS_OK;
|
|
|
|
}
|
|
|
|
|
2020-08-20 09:11:08 +03:00
|
|
|
void nsPrinterCUPS::GetPrinterName(nsAString& aName) const {
|
2020-08-06 04:42:13 +03:00
|
|
|
if (mDisplayName.IsEmpty()) {
|
2020-08-10 22:22:27 +03:00
|
|
|
aName.Truncate();
|
|
|
|
CopyUTF8toUTF16(MakeStringSpan(mPrinter->name), aName);
|
2020-08-06 04:42:13 +03:00
|
|
|
} else {
|
|
|
|
aName = mDisplayName;
|
|
|
|
}
|
2020-08-20 09:11:08 +03:00
|
|
|
}
|
|
|
|
|
|
|
|
const char* nsPrinterCUPS::LocalizeMediaName(http_t& aConnection,
|
|
|
|
cups_size_t& aMedia) const {
|
|
|
|
// The returned string is owned by mPrinterInfo.
|
|
|
|
// https://www.cups.org/doc/cupspm.html#cupsLocalizeDestMedia
|
2021-03-29 13:08:44 +03:00
|
|
|
if (!mShim.cupsLocalizeDestMedia) {
|
|
|
|
return aMedia.media;
|
|
|
|
}
|
2020-11-13 22:58:25 +03:00
|
|
|
auto printerInfoLock = TryEnsurePrinterInfo();
|
2020-09-10 02:56:13 +03:00
|
|
|
cups_dinfo_t* const printerInfo = printerInfoLock->mPrinterInfo;
|
2020-09-10 02:51:59 +03:00
|
|
|
return mShim.cupsLocalizeDestMedia(&aConnection, mPrinter, printerInfo,
|
2020-08-20 09:11:08 +03:00
|
|
|
CUPS_MEDIA_FLAGS_DEFAULT, &aMedia);
|
2020-07-29 21:02:21 +03:00
|
|
|
}
|
|
|
|
|
2020-08-04 15:06:37 +03:00
|
|
|
bool nsPrinterCUPS::SupportsDuplex() const {
|
|
|
|
return Supports(CUPS_SIDES, CUPS_SIDES_TWO_SIDED_PORTRAIT);
|
2020-07-29 21:02:21 +03:00
|
|
|
}
|
|
|
|
|
2020-09-07 21:58:48 +03:00
|
|
|
bool nsPrinterCUPS::SupportsMonochrome() const {
|
2020-10-23 14:58:42 +03:00
|
|
|
if (!SupportsColor()) {
|
|
|
|
return true;
|
|
|
|
}
|
2020-10-27 19:23:26 +03:00
|
|
|
return StaticPrefs::print_cups_monochrome_enabled();
|
2020-09-07 21:58:48 +03:00
|
|
|
}
|
|
|
|
|
2020-08-06 23:57:43 +03:00
|
|
|
bool nsPrinterCUPS::SupportsColor() const {
|
2020-11-11 22:00:00 +03:00
|
|
|
// CUPS 2.1 (particularly as used in Ubuntu 16) is known to have inaccurate
|
2020-09-03 02:49:08 +03:00
|
|
|
// results for CUPS_PRINT_COLOR_MODE.
|
|
|
|
// See https://bugzilla.mozilla.org/show_bug.cgi?id=1660658#c15
|
|
|
|
if (!IsCUPSVersionAtLeast(2, 2, 0)) {
|
2020-09-17 15:14:25 +03:00
|
|
|
return true; // See comment for PrintSettingsInitializer.mPrintInColor
|
2020-09-03 02:49:08 +03:00
|
|
|
}
|
2020-09-17 15:14:25 +03:00
|
|
|
return Supports(CUPS_PRINT_COLOR_MODE, CUPS_PRINT_COLOR_MODE_AUTO) ||
|
|
|
|
Supports(CUPS_PRINT_COLOR_MODE, CUPS_PRINT_COLOR_MODE_COLOR) ||
|
|
|
|
!Supports(CUPS_PRINT_COLOR_MODE, CUPS_PRINT_COLOR_MODE_MONOCHROME);
|
2020-08-06 23:57:43 +03:00
|
|
|
}
|
2020-08-03 14:45:35 +03:00
|
|
|
|
2020-08-14 23:41:59 +03:00
|
|
|
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;
|
|
|
|
}
|
|
|
|
|
2020-11-03 23:35:38 +03:00
|
|
|
nsPrinterBase::PrinterInfo nsPrinterCUPS::CreatePrinterInfo() const {
|
|
|
|
Connection connection{mShim};
|
|
|
|
return PrinterInfo{PaperList(connection), DefaultSettings(connection)};
|
|
|
|
}
|
|
|
|
|
2020-09-03 02:49:08 +03:00
|
|
|
bool nsPrinterCUPS::Supports(const char* aOption, const char* aValue) const {
|
2020-11-13 22:58:25 +03:00
|
|
|
auto printerInfoLock = TryEnsurePrinterInfo();
|
2020-09-10 02:56:13 +03:00
|
|
|
cups_dinfo_t* const printerInfo = printerInfoLock->mPrinterInfo;
|
2020-09-10 02:51:59 +03:00
|
|
|
return mShim.cupsCheckDestSupported(CUPS_HTTP_DEFAULT, mPrinter, printerInfo,
|
2020-09-03 02:49:08 +03:00
|
|
|
aOption, aValue);
|
|
|
|
}
|
|
|
|
|
|
|
|
bool nsPrinterCUPS::IsCUPSVersionAtLeast(uint64_t aCUPSMajor,
|
|
|
|
uint64_t aCUPSMinor,
|
|
|
|
uint64_t aCUPSPatch) const {
|
2020-11-13 22:58:25 +03:00
|
|
|
auto printerInfoLock = TryEnsurePrinterInfo();
|
2020-09-03 02:49:08 +03:00
|
|
|
// Compare major version.
|
2020-09-10 02:56:13 +03:00
|
|
|
if (printerInfoLock->mCUPSMajor > aCUPSMajor) {
|
2020-09-03 02:49:08 +03:00
|
|
|
return true;
|
|
|
|
}
|
2020-09-10 02:56:13 +03:00
|
|
|
if (printerInfoLock->mCUPSMajor < aCUPSMajor) {
|
2020-09-03 02:49:08 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compare minor version.
|
2020-09-10 02:56:13 +03:00
|
|
|
if (printerInfoLock->mCUPSMinor > aCUPSMinor) {
|
2020-09-03 02:49:08 +03:00
|
|
|
return true;
|
|
|
|
}
|
2020-09-10 02:56:13 +03:00
|
|
|
if (printerInfoLock->mCUPSMinor < aCUPSMinor) {
|
2020-09-03 02:49:08 +03:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
|
|
|
|
// Compare patch.
|
2020-09-10 02:56:13 +03:00
|
|
|
return aCUPSPatch <= printerInfoLock->mCUPSPatch;
|
2020-07-29 21:02:21 +03:00
|
|
|
}
|
2020-08-05 04:24:49 +03:00
|
|
|
|
2020-11-03 23:35:38 +03:00
|
|
|
http_t* nsPrinterCUPS::Connection::GetConnection(cups_dest_t* aDest) {
|
|
|
|
if (mWasInited) {
|
|
|
|
return mConnection;
|
|
|
|
}
|
|
|
|
mWasInited = true;
|
|
|
|
|
2020-08-05 04:24:49 +03:00
|
|
|
// blocking call
|
2020-11-03 23:35:38 +03:00
|
|
|
http_t* const connection = mShim.cupsConnectDest(aDest, CUPS_DEST_FLAGS_NONE,
|
|
|
|
/* timeout(ms) */ 5000,
|
|
|
|
/* cancel */ nullptr,
|
|
|
|
/* resource */ nullptr,
|
|
|
|
/* resourcesize */ 0,
|
|
|
|
/* callback */ nullptr,
|
|
|
|
/* user_data */ nullptr);
|
|
|
|
if (connection) {
|
|
|
|
mConnection = connection;
|
2020-09-25 01:01:43 +03:00
|
|
|
}
|
2020-11-03 23:35:38 +03:00
|
|
|
return mConnection;
|
|
|
|
}
|
|
|
|
|
|
|
|
nsPrinterCUPS::Connection::~Connection() {
|
|
|
|
if (mWasInited && mConnection) {
|
|
|
|
mShim.httpClose(mConnection);
|
|
|
|
}
|
|
|
|
}
|
2020-09-25 01:01:43 +03:00
|
|
|
|
2020-11-03 23:35:38 +03:00
|
|
|
PrintSettingsInitializer nsPrinterCUPS::DefaultSettings(
|
|
|
|
Connection& aConnection) const {
|
|
|
|
nsString printerName;
|
|
|
|
GetPrinterName(printerName);
|
2020-11-13 22:58:25 +03:00
|
|
|
auto printerInfoLock = TryEnsurePrinterInfo();
|
2020-11-03 23:35:38 +03:00
|
|
|
cups_dinfo_t* const printerInfo = printerInfoLock->mPrinterInfo;
|
|
|
|
|
|
|
|
cups_size_t media;
|
|
|
|
|
2021-03-29 13:08:44 +03:00
|
|
|
bool hasDefaultMedia = false;
|
2020-11-03 23:35:38 +03:00
|
|
|
// cupsGetDestMediaDefault appears to return more accurate defaults on macOS,
|
|
|
|
// and the IPP attribute appears to return more accurate defaults on Linux.
|
|
|
|
#ifdef XP_MACOSX
|
2021-03-29 13:08:44 +03:00
|
|
|
hasDefaultMedia =
|
2020-11-03 23:35:38 +03:00
|
|
|
mShim.cupsGetDestMediaDefault(CUPS_HTTP_DEFAULT, mPrinter, printerInfo,
|
|
|
|
CUPS_MEDIA_FLAGS_DEFAULT, &media);
|
|
|
|
#else
|
2021-03-29 13:08:44 +03:00
|
|
|
{
|
|
|
|
ipp_attribute_t* defaultMediaIPP =
|
|
|
|
mShim.cupsFindDestDefault
|
|
|
|
? mShim.cupsFindDestDefault(CUPS_HTTP_DEFAULT, mPrinter,
|
|
|
|
printerInfo, "media")
|
|
|
|
: nullptr;
|
|
|
|
|
|
|
|
const char* defaultMediaName =
|
|
|
|
defaultMediaIPP ? mShim.ippGetString(defaultMediaIPP, 0, nullptr)
|
|
|
|
: nullptr;
|
|
|
|
|
|
|
|
hasDefaultMedia = defaultMediaName &&
|
|
|
|
mShim.cupsGetDestMediaByName(
|
|
|
|
CUPS_HTTP_DEFAULT, mPrinter, printerInfo,
|
|
|
|
defaultMediaName, CUPS_MEDIA_FLAGS_DEFAULT, &media);
|
|
|
|
}
|
2020-11-03 23:35:38 +03:00
|
|
|
#endif
|
|
|
|
|
|
|
|
if (!hasDefaultMedia) {
|
|
|
|
return PrintSettingsInitializer{
|
|
|
|
std::move(printerName),
|
|
|
|
PaperInfo(),
|
|
|
|
SupportsColor(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
// Check if this is a localized fallback paper size, in which case we can
|
|
|
|
// avoid using the CUPS localization methods.
|
|
|
|
const gfx::SizeDouble sizeDouble{
|
|
|
|
media.width * kPointsPerHundredthMillimeter,
|
|
|
|
media.length * kPointsPerHundredthMillimeter};
|
|
|
|
if (const PaperInfo* const paperInfo = FindCommonPaperSize(sizeDouble)) {
|
|
|
|
return PrintSettingsInitializer{
|
|
|
|
std::move(printerName),
|
|
|
|
MakePaperInfo(paperInfo->mName, media),
|
|
|
|
SupportsColor(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
http_t* const connection = aConnection.GetConnection(mPrinter);
|
|
|
|
// XXX Do we actually have the guarantee that this is utf-8?
|
|
|
|
NS_ConvertUTF8toUTF16 localizedName{
|
|
|
|
connection ? LocalizeMediaName(*connection, media) : ""};
|
|
|
|
|
|
|
|
return PrintSettingsInitializer{
|
|
|
|
std::move(printerName),
|
|
|
|
MakePaperInfo(localizedName, media),
|
|
|
|
SupportsColor(),
|
|
|
|
};
|
|
|
|
}
|
|
|
|
|
|
|
|
nsTArray<mozilla::PaperInfo> nsPrinterCUPS::PaperList(
|
|
|
|
Connection& aConnection) const {
|
|
|
|
http_t* const connection = aConnection.GetConnection(mPrinter);
|
2020-11-13 22:58:25 +03:00
|
|
|
auto printerInfoLock = TryEnsurePrinterInfo(connection);
|
2020-09-25 01:01:43 +03:00
|
|
|
cups_dinfo_t* const printerInfo = printerInfoLock->mPrinterInfo;
|
|
|
|
|
|
|
|
if (!printerInfo) {
|
2020-08-05 04:24:49 +03:00
|
|
|
return {};
|
|
|
|
}
|
|
|
|
|
2021-03-29 13:08:44 +03:00
|
|
|
const int paperCount =
|
|
|
|
mShim.cupsGetDestMediaCount
|
|
|
|
? mShim.cupsGetDestMediaCount(connection, mPrinter, printerInfo,
|
|
|
|
CUPS_MEDIA_FLAGS_DEFAULT)
|
|
|
|
: 0;
|
2020-08-05 14:26:13 +03:00
|
|
|
nsTArray<PaperInfo> paperList;
|
2020-09-30 21:37:50 +03:00
|
|
|
nsTHashtable<nsCharPtrHashKey> paperSet(std::max(paperCount, 0));
|
|
|
|
|
2020-10-14 00:52:04 +03:00
|
|
|
paperList.SetCapacity(paperCount);
|
2020-08-05 04:24:49 +03:00
|
|
|
for (int i = 0; i < paperCount; ++i) {
|
2020-08-20 09:11:08 +03:00
|
|
|
cups_size_t media;
|
2020-10-14 00:52:04 +03:00
|
|
|
const int getInfoSucceeded = mShim.cupsGetDestMediaByIndex(
|
2020-09-25 01:01:43 +03:00
|
|
|
connection, mPrinter, printerInfo, i, CUPS_MEDIA_FLAGS_DEFAULT, &media);
|
2020-08-05 04:24:49 +03:00
|
|
|
|
2020-09-30 21:37:50 +03:00
|
|
|
if (!getInfoSucceeded || !paperSet.EnsureInserted(media.media)) {
|
2020-08-05 04:24:49 +03:00
|
|
|
continue;
|
|
|
|
}
|
2020-10-14 00:52:04 +03:00
|
|
|
// Check if this is a PWG paper size, in which case we can avoid using the
|
|
|
|
// CUPS localization methods.
|
|
|
|
const gfx::SizeDouble sizeDouble{
|
|
|
|
media.width * kPointsPerHundredthMillimeter,
|
|
|
|
media.length * kPointsPerHundredthMillimeter};
|
|
|
|
if (const PaperInfo* const paperInfo = FindCommonPaperSize(sizeDouble)) {
|
|
|
|
paperList.AppendElement(MakePaperInfo(paperInfo->mName, media));
|
|
|
|
} else {
|
|
|
|
const char* const mediaName =
|
|
|
|
connection ? LocalizeMediaName(*connection, media) : media.media;
|
|
|
|
paperList.AppendElement(
|
|
|
|
MakePaperInfo(NS_ConvertUTF8toUTF16(mediaName), media));
|
|
|
|
}
|
2020-09-25 01:01:43 +03:00
|
|
|
}
|
|
|
|
|
2020-08-05 04:24:49 +03:00
|
|
|
return paperList;
|
|
|
|
}
|
2020-09-10 02:56:13 +03:00
|
|
|
|
2020-11-13 22:58:25 +03:00
|
|
|
nsPrinterCUPS::PrinterInfoLock nsPrinterCUPS::TryEnsurePrinterInfo(
|
|
|
|
http_t* const aConnection) const {
|
|
|
|
PrinterInfoLock lock = mPrinterInfoMutex.Lock();
|
|
|
|
if (lock->mPrinterInfo ||
|
|
|
|
(aConnection == CUPS_HTTP_DEFAULT ? lock->mTriedInitWithDefault
|
|
|
|
: lock->mTriedInitWithConnection)) {
|
|
|
|
return lock;
|
2020-09-10 02:56:13 +03:00
|
|
|
}
|
|
|
|
|
2020-09-25 01:01:43 +03:00
|
|
|
if (aConnection == CUPS_HTTP_DEFAULT) {
|
2020-11-13 22:58:25 +03:00
|
|
|
lock->mTriedInitWithDefault = true;
|
2020-09-25 01:01:43 +03:00
|
|
|
} else {
|
2020-11-13 22:58:25 +03:00
|
|
|
lock->mTriedInitWithConnection = true;
|
2020-09-25 01:01:43 +03:00
|
|
|
}
|
2020-09-11 03:36:17 +03:00
|
|
|
|
|
|
|
// All CUPS calls that take the printer info do null-checks internally, so we
|
|
|
|
// can fetch this info and only worry about the result of the later CUPS
|
|
|
|
// functions.
|
2020-11-13 22:58:25 +03:00
|
|
|
lock->mPrinterInfo = mShim.cupsCopyDestInfo(aConnection, mPrinter);
|
2020-09-11 03:36:17 +03:00
|
|
|
|
|
|
|
// Even if we failed to fetch printer info, it is still possible we can talk
|
|
|
|
// to the print server and get its CUPS version.
|
2020-11-13 22:58:25 +03:00
|
|
|
FetchCUPSVersionForPrinter(mShim, mPrinter, lock->mCUPSMajor,
|
|
|
|
lock->mCUPSMinor, lock->mCUPSPatch);
|
|
|
|
return lock;
|
2020-09-10 02:56:13 +03:00
|
|
|
}
|
2020-11-11 22:00:00 +03:00
|
|
|
|
|
|
|
void nsPrinterCUPS::ForEachExtraMonochromeSetting(
|
|
|
|
FunctionRef<void(const nsACString&, const nsACString&)> aCallback) {
|
|
|
|
nsAutoCString pref;
|
|
|
|
Preferences::GetCString("print.cups.monochrome.extra_settings", pref);
|
|
|
|
if (pref.IsEmpty()) {
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
|
|
|
|
for (const auto& pair : pref.Split(',')) {
|
|
|
|
auto splitter = pair.Split(':');
|
|
|
|
auto end = splitter.end();
|
|
|
|
|
|
|
|
auto key = splitter.begin();
|
|
|
|
if (key == end) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
auto value = ++splitter.begin();
|
|
|
|
if (value == end) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
aCallback(*key, *value);
|
|
|
|
}
|
|
|
|
}
|