Bug 1654678 Part 4 - Make GTK printer enumeration use the unified CUPS code r=jwatt,emilio

Differential Revision: https://phabricator.services.mozilla.com/D85502
This commit is contained in:
Emily McDonough 2020-08-05 22:15:18 +00:00
Родитель b3f73b88e1
Коммит 51464aefa0
6 изменённых файлов: 77 добавлений и 182 удалений

Просмотреть файл

@ -5,36 +5,21 @@
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
#include "nscore.h"
#include "nsCUPSShim.h"
#include "nsPSPrinters.h"
#include "PSPrinters.h"
#include "nsReadableUtils.h" // StringBeginsWith()
#include "nsCUPSShim.h"
#include "mozilla/Preferences.h"
#include "prlink.h"
#include "prenv.h"
#include "plstr.h"
using namespace mozilla;
#define NS_CUPS_PRINTER "CUPS/"
#define NS_CUPS_PRINTER_LEN (sizeof(NS_CUPS_PRINTER) - 1)
/* dummy printer name for the gfx/src/ps driver */
#define NS_POSTSCRIPT_DRIVER_NAME "PostScript/"
nsCUPSShim gCupsShim;
nsPSPrinterList::nsPSPrinterList() {
// Should we try cups?
if (Preferences::GetBool("print.postscript.cups.enabled", true) &&
!gCupsShim.IsInitialized()) {
gCupsShim.Init();
}
}
namespace mozilla {
/* Check whether the PostScript module has been disabled at runtime */
bool nsPSPrinterList::Enabled() {
bool PSPrinters::Enabled() {
const char* val = PR_GetEnv("MOZILLA_POSTSCRIPT_ENABLED");
if (val && (val[0] == '0' || !PL_strcasecmp(val, "false"))) return false;
@ -43,32 +28,9 @@ bool nsPSPrinterList::Enabled() {
}
/* Fetch a list of printers handled by the PostsScript module */
void nsPSPrinterList::GetPrinterList(nsTArray<nsCString>& aList) {
void PSPrinters::GetPrinterList(nsTArray<nsCString>& aList) {
aList.Clear();
// Query CUPS for a printer list. The default printer goes to the
// head of the output list; others are appended.
if (gCupsShim.IsInitialized()) {
cups_dest_t* dests;
int num_dests = (gCupsShim.mCupsGetDests)(&dests);
if (num_dests) {
for (int i = 0; i < num_dests; i++) {
nsAutoCString fullName(NS_CUPS_PRINTER);
fullName.Append(dests[i].name);
if (dests[i].instance != nullptr) {
fullName.Append('/');
fullName.Append(dests[i].instance);
}
if (dests[i].is_default)
aList.InsertElementAt(0, fullName);
else
aList.AppendElement(fullName);
}
}
(gCupsShim.mCupsFreeDests)(num_dests, dests);
}
// Build the "classic" list of printers -- those accessed by running
// an opaque command. This list always contains a printer named "default".
// In addition, we look for either an environment variable
@ -98,13 +60,8 @@ void nsPSPrinterList::GetPrinterList(nsTArray<nsCString>& aList) {
}
/* Identify the printer type */
nsPSPrinterList::PrinterType nsPSPrinterList::GetPrinterType(
const nsACString& aName) {
if (StringBeginsWith(aName, nsLiteralCString(NS_POSTSCRIPT_DRIVER_NAME))) {
return kTypePS;
}
if (StringBeginsWith(aName, nsLiteralCString(NS_CUPS_PRINTER))) {
return kTypeCUPS;
}
return kTypeUnknown;
bool PSPrinters::IsPSPrinter(const nsACString& aName) {
return StringBeginsWith(aName, nsLiteralCString(NS_POSTSCRIPT_DRIVER_NAME));
}
} // namespace mozilla

Просмотреть файл

@ -4,22 +4,25 @@
* 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 nsPSPrinters_h___
#define nsPSPrinters_h___
#ifndef PSPrinters_h___
#define PSPrinters_h___
#include "nsString.h"
#include "nsTArray.h"
class nsPSPrinterList {
namespace mozilla {
class PSPrinters {
PSPrinters() = delete;
public:
nsPSPrinterList();
/**
* Is the PostScript module enabled or disabled?
* @return true if enabled,
* false if not.
*/
bool Enabled();
static bool Enabled();
/**
* Obtain a list of printers (print destinations) supported by the
@ -33,21 +36,17 @@ class nsPSPrinterList {
* There should always be at least one entry. The
* first entry is the default print destination.
*/
void GetPrinterList(nsTArray<nsCString>& aList);
enum PrinterType {
kTypeUnknown, // Not actually handled by the PS module
kTypePS, // Generic postscript module printer
kTypeCUPS // CUPS printer
};
static void GetPrinterList(nsTArray<nsCString>& aList);
/**
* Identify a printer's type from its name.
* Identify if a printer is a PS printer from its name.
* @param aName The printer's full name as a UTF8 string, including
* the <type> portion as described for GetPrinterList().
* @return The PrinterType value for this name.
*/
static PrinterType GetPrinterType(const nsACString& aName);
static bool IsPSPrinter(const nsACString& aName);
};
#endif /* nsPSPrinters_h___ */
} // namespace mozilla
#endif /* PSPrinters_h___ */

Просмотреть файл

@ -81,7 +81,7 @@ if CONFIG['NS_PRINTING']:
'nsPrintDialogGTK.cpp',
'nsPrintSettingsGTK.cpp',
'nsPrintSettingsServiceGTK.cpp',
'nsPSPrinters.cpp',
'PSPrinters.cpp',
]
if CONFIG['MOZ_X11']:

Просмотреть файл

@ -19,9 +19,12 @@
#include "nsReadableUtils.h"
#include "nsThreadUtils.h"
#include "CUPSPrinterList.h"
#include "nsCUPSShim.h"
#include "nsPaper.h"
#include "nsPrinter.h"
#include "nsPSPrinters.h"
#include "nsPrinterCUPS.h"
#include "PSPrinters.h"
#include "nsPrintSettingsGTK.h"
@ -48,41 +51,7 @@ using mozilla::gfx::PrintTargetPS;
static LazyLogModule sDeviceContextSpecGTKLog("DeviceContextSpecGTK");
//----------------------------------------------------------------------------------
// The printer data is shared between the PrinterList and the
// nsDeviceContextSpecGTK The PrinterList creates the printer info but the
// nsDeviceContextSpecGTK cleans it up If it gets created (via the Page Setup
// Dialog) but the user never prints anything then it will never be delete, so
// this class takes care of that.
class GlobalPrinters {
public:
static GlobalPrinters* GetInstance() { return &mGlobalPrinters; }
~GlobalPrinters() { FreeGlobalPrinters(); }
void FreeGlobalPrinters();
nsresult InitializeGlobalPrinters();
bool PrintersAreAllocated() { return mGlobalPrinterList != nullptr; }
uint32_t GetNumPrinters() {
return mGlobalPrinterList ? mGlobalPrinterList->Length() : 0;
}
nsString* GetStringAt(int32_t aInx) {
return &mGlobalPrinterList->ElementAt(aInx);
}
void GetSystemDefaultPrinterName(nsAString& aName);
protected:
GlobalPrinters() = default;
static GlobalPrinters mGlobalPrinters;
static nsTArray<nsString>* mGlobalPrinterList;
};
//---------------
// static members
GlobalPrinters GlobalPrinters::mGlobalPrinters;
nsTArray<nsString>* GlobalPrinters::mGlobalPrinterList = nullptr;
//---------------
static nsCUPSShim sCupsShim;
nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()
: mGtkPrintSettings(nullptr), mGtkPageSetup(nullptr) {}
@ -356,27 +325,58 @@ NS_IMPL_ISUPPORTS(nsPrinterListGTK, nsIPrinterList)
NS_IMETHODIMP
nsPrinterListGTK::GetPrinters(nsTArray<RefPtr<nsIPrinter>>& aPrinters) {
nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
if (NS_FAILED(rv)) {
return rv;
}
uint32_t numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters();
for (uint32_t i = 0; i < numPrinters; ++i) {
nsString* name = GlobalPrinters::GetInstance()->GetStringAt(i);
if (RefPtr<nsPrinter> printer = nsPrinter::Create(*name)) {
aPrinters.AppendElement(printer);
if (!sCupsShim.IsInitialized()) {
if (!sCupsShim.Init()) {
return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
}
}
// Build the CUPS printer list.
mozilla::CUPSPrinterList cupsPrinterList{sCupsShim};
cupsPrinterList.Initialize();
// Add one, since there will be at least one extra PS printer to add.
aPrinters.SetCapacity(cupsPrinterList.NumPrinters() + 1);
for (int i = 0; i < cupsPrinterList.NumPrinters(); i++) {
cups_dest_t* const dest = cupsPrinterList.GetPrinter(i);
aPrinters.AppendElement(nsPrinterCUPS::Create(sCupsShim, dest));
}
// TODO: We will be removing all this PS Printer code in bug 1657164
// Add the PS printer list
if (PSPrinters::Enabled()) {
nsTArray<nsCString> printerList;
PSPrinters::GetPrinterList(printerList);
for (nsCString& printer : printerList) {
aPrinters.AppendElement(
nsPrinter::Create(NS_ConvertUTF8toUTF16(printer)));
}
}
GlobalPrinters::GetInstance()->FreeGlobalPrinters();
return NS_OK;
}
NS_IMETHODIMP
nsPrinterListGTK::GetSystemDefaultPrinterName(nsAString& aName) {
GlobalPrinters::GetInstance()->GetSystemDefaultPrinterName(aName);
return NS_OK;
if (!sCupsShim.IsInitialized()) {
if (!sCupsShim.Init()) {
return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
}
}
mozilla::CUPSPrinterList cupsPrinterList{sCupsShim};
cupsPrinterList.Initialize();
// TODO: Once the CUPSPrinterList has default printer support, use that.
if (cupsPrinterList.NumPrinters() != 0) {
CopyUTF8toUTF16(
mozilla::MakeStringSpan(cupsPrinterList.GetPrinter(0)->name), aName);
return NS_OK;
}
// TODO: We will be removing all this PS Printer code in bug 1657164
// No CUPS printers, report PS printers instead.
nsTArray<nsCString> printerList;
PSPrinters::GetPrinterList(printerList);
if (!printerList.IsEmpty()) {
CopyUTF8toUTF16(printerList[0], aName);
return NS_OK;
}
// No CUPS or PS printers.
return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
}
NS_IMETHODIMP
@ -408,65 +408,3 @@ nsPrinterListGTK::InitPrintSettingsFromPrinter(
return NS_OK;
}
//----------------------------------------------------------------------
nsresult GlobalPrinters::InitializeGlobalPrinters() {
if (PrintersAreAllocated()) {
return NS_OK;
}
mGlobalPrinterList = new nsTArray<nsString>();
nsPSPrinterList psMgr;
if (psMgr.Enabled()) {
/* Get the list of PostScript-module printers */
// XXX: this function is the only user of GetPrinterList
// So it may be interesting to convert the nsCStrings
// in this function, we would save one loop here
nsTArray<nsCString> printerList;
psMgr.GetPrinterList(printerList);
for (uint32_t i = 0; i < printerList.Length(); i++) {
mGlobalPrinterList->AppendElement(NS_ConvertUTF8toUTF16(printerList[i]));
}
}
/* If there are no printers available after all checks, return an error */
if (!mGlobalPrinterList->Length()) {
/* Make sure we do not cache an empty printer list */
FreeGlobalPrinters();
return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
}
return NS_OK;
}
//----------------------------------------------------------------------
void GlobalPrinters::FreeGlobalPrinters() {
if (mGlobalPrinterList) {
delete mGlobalPrinterList;
mGlobalPrinterList = nullptr;
}
}
void GlobalPrinters::GetSystemDefaultPrinterName(nsAString& aName) {
aName.Truncate();
bool allocate = !GlobalPrinters::GetInstance()->PrintersAreAllocated();
if (allocate) {
nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
if (NS_FAILED(rv)) {
return;
}
}
NS_ASSERTION(GlobalPrinters::GetInstance()->PrintersAreAllocated(),
"no GlobalPrinters");
if (GlobalPrinters::GetInstance()->GetNumPrinters() == 0) return;
aName = *GlobalPrinters::GetInstance()->GetStringAt(0);
if (allocate) {
GlobalPrinters::GetInstance()->FreeGlobalPrinters();
}
}

Просмотреть файл

@ -6,6 +6,8 @@
#ifndef nsDeviceContextSpecGTK_h___
#define nsDeviceContextSpecGTK_h___
struct JSContext;
#include "nsIDeviceContextSpec.h"
#include "nsIPrinterList.h"
#include "nsIPrintSettings.h"

Просмотреть файл

@ -244,17 +244,16 @@ if CONFIG['MOZ_XUL'] and CONFIG['NS_PRINTING']:
'nsPrintSettingsService.cpp',
]
# These will be unified for all CUPS platforms by Bug 1654678
if toolkit == 'cocoa':
if toolkit in ('cocoa', 'gtk'):
UNIFIED_SOURCES += [
'CUPSPrinterList.cpp',
'nsCUPSShim.cpp',
'nsPrinterCUPS.cpp',
]
# GTK still uses nsPrinter for PS printers.
if toolkit == 'gtk':
UNIFIED_SOURCES += [
'nsCUPSShim.cpp',
'nsPrinter.cpp',
]