Bug 1656587 - Retrieve Default Printer Name Using CUPS r=AlaskanEmily

Differential Revision: https://phabricator.services.mozilla.com/D85628
This commit is contained in:
Erik Nordin 2020-08-06 17:26:04 +00:00
parent c366c291b9
commit dc5ce69107
6 changed files with 72 additions and 40 deletions

View File

@ -22,7 +22,8 @@ void CUPSPrinterList::Initialize() {
cups_dest_t* CUPSPrinterList::FindPrinterByName(const char* aName) {
MOZ_ASSERT(aName);
return mShim.cupsGetDest(aName, NULL, mNumPrinters, mPrinters);
return mShim.cupsGetDest(aName, /* instance */ nullptr, mNumPrinters,
mPrinters);
}
cups_dest_t* CUPSPrinterList::GetPrinter(int i) {
@ -31,4 +32,10 @@ cups_dest_t* CUPSPrinterList::GetPrinter(int i) {
return mPrinters + i;
}
cups_dest_t* CUPSPrinterList::GetDefaultPrinter() {
// Passing in nullptr for the name will return the default, if any.
return mShim.cupsGetNamedDest(CUPS_HTTP_DEFAULT, /* name */ nullptr,
/* instance */ nullptr);
}
} // namespace mozilla

View File

@ -32,6 +32,7 @@ class CUPSPrinterList {
cups_dest_t* FindPrinterByName(const char* name);
int NumPrinters() const { return mNumPrinters; }
/**
* @brief Gets a printer by index.
*
@ -39,6 +40,13 @@ class CUPSPrinterList {
*/
cups_dest_t* GetPrinter(int i);
/**
* @brief Gets the system default printer.
*
* This does NOT copy the printer's data.
*/
cups_dest_t* GetDefaultPrinter();
private:
const nsCUPSShim& mShim;
cups_dest_t* mPrinters = nullptr;

View File

@ -50,21 +50,53 @@ static nsCUPSShim sCupsShim;
//----------------------------------------------------------------------
// nsPrinterListX
/**
* Retrieves the display name of a printer.
*/
static nsresult GetDisplayNameForPrinter(cups_dest_t& aDest, nsAString& aName) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
// CUPS does not appear to have a native call to retrieve a display name for
// a printer, so we need to use cocoa to find a display name for the printer.
PMPrinter corePrinter = PMPrinterCreateFromPrinterID(
static_cast<CFStringRef>([NSString stringWithUTF8String:aDest.name]));
if (!corePrinter) {
return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
}
CFStringRef printerName = PMPrinterGetName(corePrinter);
nsCocoaUtils::GetStringForNSString(static_cast<NSString*>(printerName), aName);
PMRelease(corePrinter);
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
NS_IMPL_ISUPPORTS(nsPrinterListX, nsIPrinterList);
NS_IMETHODIMP
nsPrinterListX::GetSystemDefaultPrinterName(nsAString& aName) {
NS_OBJC_BEGIN_TRY_ABORT_BLOCK_NSRESULT;
aName.Truncate();
NSArray<NSString*>* printerNames = [NSPrinter printerNames];
if ([printerNames count] > 0) {
NSString* name = [printerNames objectAtIndex:0];
nsCocoaUtils::GetStringForNSString(name, aName);
return NS_OK;
if (!sCupsShim.IsInitialized()) {
if (!sCupsShim.Init()) {
return NS_ERROR_FAILURE;
}
}
return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
mozilla::CUPSPrinterList cupsPrinterList(sCupsShim);
cupsPrinterList.Initialize();
cups_dest_t* const dest = cupsPrinterList.GetDefaultPrinter();
if (!dest) {
return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
}
GetDisplayNameForPrinter(*dest, aName);
return NS_OK;
NS_OBJC_END_TRY_ABORT_BLOCK_NSRESULT;
}
@ -79,30 +111,18 @@ nsPrinterListX::GetPrinters(nsTArray<RefPtr<nsIPrinter>>& aPrinters) {
}
}
mozilla::CUPSPrinterList cupsPrinterList{sCupsShim};
mozilla::CUPSPrinterList cupsPrinterList(sCupsShim);
cupsPrinterList.Initialize();
aPrinters.SetCapacity(cupsPrinterList.NumPrinters());
for (int i = 0; i < cupsPrinterList.NumPrinters(); i++) {
cups_dest_t* const dest = cupsPrinterList.GetPrinter(i);
RefPtr<nsPrinterCUPS> cupsPrinter = nsPrinterCUPS::Create(sCupsShim, dest);
// CUPS does not appear to have a native call to retrieve a display name for
// a printer, so we need to use cocoa to find a display name for the printer.
PMPrinter corePrinter = PMPrinterCreateFromPrinterID(
static_cast<CFStringRef>([NSString stringWithUTF8String:dest->name]));
if (!corePrinter) {
continue;
}
CFStringRef printerName = PMPrinterGetName(corePrinter);
nsAutoString displayName;
nsCocoaUtils::GetStringForNSString(static_cast<NSString*>(printerName), displayName);
cupsPrinter->SetDisplayName(displayName);
nsString displayName;
GetDisplayNameForPrinter(*dest, displayName);
RefPtr<nsPrinterCUPS> cupsPrinter = nsPrinterCUPS::Create(sCupsShim, dest, displayName);
aPrinters.AppendElement(cupsPrinter);
PMRelease(corePrinter);
}
return NS_OK;

View File

@ -46,6 +46,7 @@ class nsCUPSShim {
X(cupsGetDestMediaByIndex) \
X(cupsGetDest) \
X(cupsGetDests) \
X(cupsGetNamedDest) \
X(cupsLocalizeDestMedia) \
X(cupsPrintFile) \
X(cupsTempFd) \

View File

@ -9,8 +9,9 @@
using namespace mozilla;
nsPrinterCUPS::nsPrinterCUPS(const nsCUPSShim& aShim, cups_dest_t* aPrinter)
: mShim(aShim) {
nsPrinterCUPS::nsPrinterCUPS(const nsCUPSShim& aShim, cups_dest_t* aPrinter,
const nsAString& aDisplayName)
: mDisplayName(aDisplayName), mShim(aShim) {
MOZ_ASSERT(aPrinter);
MOZ_ASSERT(mShim.IsInitialized());
DebugOnly<const int> numCopied = aShim.cupsCopyDest(aPrinter, 0, &mPrinter);
@ -30,9 +31,10 @@ nsPrinterCUPS::~nsPrinterCUPS() {
}
// static
already_AddRefed<nsPrinterCUPS> nsPrinterCUPS::Create(const nsCUPSShim& aShim,
cups_dest_t* aPrinter) {
return do_AddRef(new nsPrinterCUPS(aShim, aPrinter));
already_AddRefed<nsPrinterCUPS> nsPrinterCUPS::Create(
const nsCUPSShim& aShim, cups_dest_t* aPrinter,
const nsAString& aDisplayName) {
return do_AddRef(new nsPrinterCUPS(aShim, aPrinter, aDisplayName));
}
NS_IMETHODIMP

View File

@ -31,19 +31,13 @@ class nsPrinterCUPS final : public nsPrinterBase {
/**
* @p aPrinter must not be null.
*/
static already_AddRefed<nsPrinterCUPS> Create(const nsCUPSShim& aShim,
cups_dest_t* aPrinter);
/**
* @brief Set the display name for the printer.
*
* If a display name is not set, the PWG Standardized name will be used
* https://ftp.pwg.org/pub/pwg/candidates/cs-pwgmsn20-20130328-5101.1.pdf
*/
void SetDisplayName(const nsAString& aName) { mDisplayName = aName; }
static already_AddRefed<nsPrinterCUPS> Create(
const nsCUPSShim& aShim, cups_dest_t* aPrinter,
const nsAString& aDisplayname = EmptyString());
private:
nsPrinterCUPS(const nsCUPSShim& aShim, cups_dest_t* aPrinter);
nsPrinterCUPS(const nsCUPSShim& aShim, cups_dest_t* aPrinter,
const nsAString& aDisplayName = EmptyString());
~nsPrinterCUPS();