michael@0: /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ michael@0: /* This Source Code Form is subject to the terms of the Mozilla Public michael@0: * License, v. 2.0. If a copy of the MPL was not distributed with this michael@0: * file, You can obtain one at http://mozilla.org/MPL/2.0/. */ michael@0: michael@0: #ifdef MOZ_LOGGING michael@0: #define FORCE_PR_LOG 1 /* Allow logging in the release build */ michael@0: #endif /* MOZ_LOGGING */ michael@0: #include "prlog.h" michael@0: michael@0: #include "plstr.h" michael@0: michael@0: #include "nsDeviceContextSpecG.h" michael@0: michael@0: #include "prenv.h" /* for PR_GetEnv */ michael@0: michael@0: #include "nsPrintfCString.h" michael@0: #include "nsReadableUtils.h" michael@0: #include "nsStringEnumerator.h" michael@0: #include "nsIServiceManager.h" michael@0: michael@0: #include "nsPSPrinters.h" michael@0: #include "nsPaperPS.h" /* Paper size list */ michael@0: michael@0: #include "nsPrintSettingsGTK.h" michael@0: michael@0: #include "nsIFileStreams.h" michael@0: #include "nsIFile.h" michael@0: #include "nsTArray.h" michael@0: michael@0: #include "mozilla/Preferences.h" michael@0: michael@0: #include michael@0: #include michael@0: #include michael@0: michael@0: using namespace mozilla; michael@0: michael@0: #ifdef PR_LOGGING michael@0: static PRLogModuleInfo * michael@0: GetDeviceContextSpecGTKLog() michael@0: { michael@0: static PRLogModuleInfo *sLog; michael@0: if (!sLog) michael@0: sLog = PR_NewLogModule("DeviceContextSpecGTK"); michael@0: return sLog; michael@0: } michael@0: #endif /* PR_LOGGING */ michael@0: /* Macro to make lines shorter */ michael@0: #define DO_PR_DEBUG_LOG(x) PR_LOG(GetDeviceContextSpecGTKLog(), PR_LOG_DEBUG, x) michael@0: michael@0: //---------------------------------------------------------------------------------- michael@0: // The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecGTK michael@0: // The PrinterEnumerator creates the printer info michael@0: // but the nsDeviceContextSpecGTK cleans it up michael@0: // If it gets created (via the Page Setup Dialog) but the user never prints anything michael@0: // then it will never be delete, so this class takes care of that. michael@0: class GlobalPrinters { michael@0: public: michael@0: static GlobalPrinters* GetInstance() { return &mGlobalPrinters; } michael@0: ~GlobalPrinters() { FreeGlobalPrinters(); } michael@0: michael@0: void FreeGlobalPrinters(); michael@0: nsresult InitializeGlobalPrinters(); michael@0: michael@0: bool PrintersAreAllocated() { return mGlobalPrinterList != nullptr; } michael@0: uint32_t GetNumPrinters() michael@0: { return mGlobalPrinterList ? mGlobalPrinterList->Length() : 0; } michael@0: nsString* GetStringAt(int32_t aInx) { return &mGlobalPrinterList->ElementAt(aInx); } michael@0: void GetDefaultPrinterName(char16_t **aDefaultPrinterName); michael@0: michael@0: protected: michael@0: GlobalPrinters() {} michael@0: michael@0: static GlobalPrinters mGlobalPrinters; michael@0: static nsTArray* mGlobalPrinterList; michael@0: }; michael@0: michael@0: //--------------- michael@0: // static members michael@0: GlobalPrinters GlobalPrinters::mGlobalPrinters; michael@0: nsTArray* GlobalPrinters::mGlobalPrinterList = nullptr; michael@0: //--------------- michael@0: michael@0: nsDeviceContextSpecGTK::nsDeviceContextSpecGTK() michael@0: : mPrintJob(nullptr) michael@0: , mGtkPrinter(nullptr) michael@0: , mGtkPrintSettings(nullptr) michael@0: , mGtkPageSetup(nullptr) michael@0: { michael@0: DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n")); michael@0: } michael@0: michael@0: nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK() michael@0: { michael@0: DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()\n")); michael@0: michael@0: if (mGtkPageSetup) { michael@0: g_object_unref(mGtkPageSetup); michael@0: } michael@0: michael@0: if (mGtkPrintSettings) { michael@0: g_object_unref(mGtkPrintSettings); michael@0: } michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(nsDeviceContextSpecGTK, michael@0: nsIDeviceContextSpec) michael@0: michael@0: #include "gfxPDFSurface.h" michael@0: #include "gfxPSSurface.h" michael@0: NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurface) michael@0: { michael@0: *aSurface = nullptr; michael@0: michael@0: const char *path; michael@0: GetPath(&path); michael@0: michael@0: double width, height; michael@0: mPrintSettings->GetEffectivePageSize(&width, &height); michael@0: michael@0: // convert twips to points michael@0: width /= TWIPS_PER_POINT_FLOAT; michael@0: height /= TWIPS_PER_POINT_FLOAT; michael@0: michael@0: DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", path, width, height)); michael@0: nsresult rv; michael@0: michael@0: // Spool file. Use Glib's temporary file function since we're michael@0: // already dependent on the gtk software stack. michael@0: gchar *buf; michael@0: gint fd = g_file_open_tmp("XXXXXX.tmp", &buf, nullptr); michael@0: if (-1 == fd) michael@0: return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; michael@0: close(fd); michael@0: michael@0: rv = NS_NewNativeLocalFile(nsDependentCString(buf), false, michael@0: getter_AddRefs(mSpoolFile)); michael@0: if (NS_FAILED(rv)) { michael@0: unlink(buf); michael@0: return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; michael@0: } michael@0: michael@0: mSpoolName = buf; michael@0: g_free(buf); michael@0: michael@0: mSpoolFile->SetPermissions(0600); michael@0: michael@0: nsCOMPtr stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1"); michael@0: rv = stream->Init(mSpoolFile, -1, -1, 0); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: int16_t format; michael@0: mPrintSettings->GetOutputFormat(&format); michael@0: michael@0: nsRefPtr surface; michael@0: gfxSize surfaceSize(width, height); michael@0: michael@0: // Determine the real format with some GTK magic michael@0: if (format == nsIPrintSettings::kOutputFormatNative) { michael@0: if (mIsPPreview) { michael@0: // There is nothing to detect on Print Preview, use PS. michael@0: format = nsIPrintSettings::kOutputFormatPS; michael@0: } else { michael@0: const gchar* fmtGTK = gtk_print_settings_get(mGtkPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT); michael@0: if (!fmtGTK && GTK_IS_PRINTER(mGtkPrinter)) { michael@0: // Likely not print-to-file, check printer's capabilities michael@0: michael@0: // Prior to gtk 2.24, gtk_printer_accepts_pdf() and michael@0: // gtk_printer_accepts_ps() always returned true regardless of the michael@0: // printer's capability. michael@0: if (gtk_major_version > 2 || michael@0: (gtk_major_version == 2 && gtk_minor_version >= 24)) { michael@0: format = michael@0: gtk_printer_accepts_pdf(mGtkPrinter) ? michael@0: static_cast(nsIPrintSettings::kOutputFormatPDF) : michael@0: static_cast(nsIPrintSettings::kOutputFormatPS); michael@0: } else { michael@0: format = nsIPrintSettings::kOutputFormatPS; michael@0: } michael@0: michael@0: } else if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) { michael@0: format = nsIPrintSettings::kOutputFormatPDF; michael@0: } else { michael@0: format = nsIPrintSettings::kOutputFormatPS; michael@0: } michael@0: } michael@0: } michael@0: michael@0: if (format == nsIPrintSettings::kOutputFormatPDF) { michael@0: surface = new gfxPDFSurface(stream, surfaceSize); michael@0: } else { michael@0: int32_t orientation; michael@0: mPrintSettings->GetOrientation(&orientation); michael@0: if (nsIPrintSettings::kPortraitOrientation == orientation) { michael@0: surface = new gfxPSSurface(stream, surfaceSize, gfxPSSurface::PORTRAIT); michael@0: } else { michael@0: surface = new gfxPSSurface(stream, surfaceSize, gfxPSSurface::LANDSCAPE); michael@0: } michael@0: } michael@0: michael@0: if (!surface) michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: michael@0: surface.swap(*aSurface); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: /** ------------------------------------------------------- michael@0: * Initialize the nsDeviceContextSpecGTK michael@0: * @update dc 2/15/98 michael@0: * @update syd 3/2/99 michael@0: */ michael@0: NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIWidget *aWidget, michael@0: nsIPrintSettings* aPS, michael@0: bool aIsPrintPreview) michael@0: { michael@0: DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::Init(aPS=%p)\n", aPS)); michael@0: michael@0: if (gtk_major_version < 2 || michael@0: (gtk_major_version == 2 && gtk_minor_version < 10)) michael@0: return NS_ERROR_NOT_AVAILABLE; // I'm so sorry bz michael@0: michael@0: mPrintSettings = aPS; michael@0: mIsPPreview = aIsPrintPreview; michael@0: michael@0: // This is only set by embedders michael@0: bool toFile; michael@0: aPS->GetPrintToFile(&toFile); michael@0: michael@0: mToPrinter = !toFile && !aIsPrintPreview; michael@0: michael@0: nsCOMPtr printSettingsGTK(do_QueryInterface(aPS)); michael@0: if (!printSettingsGTK) michael@0: return NS_ERROR_NO_INTERFACE; michael@0: michael@0: mGtkPrinter = printSettingsGTK->GetGtkPrinter(); michael@0: mGtkPrintSettings = printSettingsGTK->GetGtkPrintSettings(); michael@0: mGtkPageSetup = printSettingsGTK->GetGtkPageSetup(); michael@0: michael@0: // This is a horrible workaround for some printer driver bugs that treat custom page sizes different michael@0: // to standard ones. If our paper object matches one of a standard one, use a standard paper size michael@0: // object instead. See bug 414314 for more info. michael@0: GtkPaperSize* geckosHackishPaperSize = gtk_page_setup_get_paper_size(mGtkPageSetup); michael@0: GtkPaperSize* standardGtkPaperSize = gtk_paper_size_new(gtk_paper_size_get_name(geckosHackishPaperSize)); michael@0: michael@0: mGtkPageSetup = gtk_page_setup_copy(mGtkPageSetup); michael@0: mGtkPrintSettings = gtk_print_settings_copy(mGtkPrintSettings); michael@0: michael@0: GtkPaperSize* properPaperSize; michael@0: if (gtk_paper_size_is_equal(geckosHackishPaperSize, standardGtkPaperSize)) { michael@0: properPaperSize = standardGtkPaperSize; michael@0: } else { michael@0: properPaperSize = geckosHackishPaperSize; michael@0: } michael@0: gtk_print_settings_set_paper_size(mGtkPrintSettings, properPaperSize); michael@0: gtk_page_setup_set_paper_size_and_default_margins(mGtkPageSetup, properPaperSize); michael@0: gtk_paper_size_free(standardGtkPaperSize); michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecGTK::GetPath(const char **aPath) michael@0: { michael@0: *aPath = mPath; michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* static !! */ michael@0: nsresult nsDeviceContextSpecGTK::GetPrintMethod(const char *aPrinter, PrintMethod &aMethod) michael@0: { michael@0: aMethod = pmPostScript; michael@0: return NS_OK; michael@0: } michael@0: michael@0: static void michael@0: #if (MOZ_WIDGET_GTK == 3) michael@0: print_callback(GtkPrintJob *aJob, gpointer aData, const GError *aError) { michael@0: #else michael@0: print_callback(GtkPrintJob *aJob, gpointer aData, GError *aError) { michael@0: #endif michael@0: g_object_unref(aJob); michael@0: ((nsIFile*) aData)->Remove(false); michael@0: } michael@0: michael@0: static void michael@0: ns_release_macro(gpointer aData) { michael@0: nsIFile* spoolFile = (nsIFile*) aData; michael@0: NS_RELEASE(spoolFile); michael@0: } michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecGTK::BeginDocument(const nsAString& aTitle, char16_t * aPrintToFileName, michael@0: int32_t aStartPage, int32_t aEndPage) michael@0: { michael@0: if (mToPrinter) { michael@0: if (!GTK_IS_PRINTER(mGtkPrinter)) michael@0: return NS_ERROR_FAILURE; michael@0: michael@0: mPrintJob = gtk_print_job_new(NS_ConvertUTF16toUTF8(aTitle).get(), mGtkPrinter, michael@0: mGtkPrintSettings, mGtkPageSetup); michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsDeviceContextSpecGTK::EndDocument() michael@0: { michael@0: if (mToPrinter) { michael@0: if (!mPrintJob) michael@0: return NS_OK; // The operation was aborted. michael@0: michael@0: if (!gtk_print_job_set_source_file(mPrintJob, mSpoolName.get(), nullptr)) michael@0: return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE; michael@0: michael@0: NS_ADDREF(mSpoolFile.get()); michael@0: gtk_print_job_send(mPrintJob, print_callback, mSpoolFile, ns_release_macro); michael@0: } else { michael@0: // Handle print-to-file ourselves for the benefit of embedders michael@0: nsXPIDLString targetPath; michael@0: nsCOMPtr destFile; michael@0: mPrintSettings->GetToFileName(getter_Copies(targetPath)); michael@0: michael@0: nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(targetPath), michael@0: false, getter_AddRefs(destFile)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsAutoString destLeafName; michael@0: rv = destFile->GetLeafName(destLeafName); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: nsCOMPtr destDir; michael@0: rv = destFile->GetParent(getter_AddRefs(destDir)); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: rv = mSpoolFile->MoveTo(destDir, destLeafName); michael@0: NS_ENSURE_SUCCESS(rv, rv); michael@0: michael@0: // This is the standard way to get the UNIX umask. Ugh. michael@0: mode_t mask = umask(0); michael@0: umask(mask); michael@0: // If you're not familiar with umasks, they contain the bits of what NOT to set in the permissions michael@0: // (thats because files and directories have different numbers of bits for their permissions) michael@0: destFile->SetPermissions(0666 & ~(mask)); michael@0: } michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* Get prefs for printer michael@0: * Search order: michael@0: * - Get prefs per printer name and module name michael@0: * - Get prefs per printer name michael@0: * - Get prefs per module name michael@0: * - Get prefs michael@0: */ michael@0: static michael@0: nsresult CopyPrinterCharPref(const char *modulename, const char *printername, michael@0: const char *prefname, nsCString &return_buf) michael@0: { michael@0: DO_PR_DEBUG_LOG(("CopyPrinterCharPref('%s', '%s', '%s')\n", modulename, printername, prefname)); michael@0: michael@0: nsresult rv = NS_ERROR_FAILURE; michael@0: michael@0: if (printername && modulename) { michael@0: /* Get prefs per printer name and module name */ michael@0: nsPrintfCString name("print.%s.printer_%s.%s", modulename, printername, prefname); michael@0: DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); michael@0: rv = Preferences::GetCString(name.get(), &return_buf); michael@0: } michael@0: michael@0: if (NS_FAILED(rv)) { michael@0: if (printername) { michael@0: /* Get prefs per printer name */ michael@0: nsPrintfCString name("print.printer_%s.%s", printername, prefname); michael@0: DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); michael@0: rv = Preferences::GetCString(name.get(), &return_buf); michael@0: } michael@0: michael@0: if (NS_FAILED(rv)) { michael@0: if (modulename) { michael@0: /* Get prefs per module name */ michael@0: nsPrintfCString name("print.%s.%s", modulename, prefname); michael@0: DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); michael@0: rv = Preferences::GetCString(name.get(), &return_buf); michael@0: } michael@0: michael@0: if (NS_FAILED(rv)) { michael@0: /* Get prefs */ michael@0: nsPrintfCString name("print.%s", prefname); michael@0: DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); michael@0: rv = Preferences::GetCString(name.get(), &return_buf); michael@0: } michael@0: } michael@0: } michael@0: michael@0: #ifdef PR_LOG michael@0: if (NS_SUCCEEDED(rv)) { michael@0: DO_PR_DEBUG_LOG(("CopyPrinterCharPref returning '%s'.\n", return_buf.get())); michael@0: } michael@0: else michael@0: { michael@0: DO_PR_DEBUG_LOG(("CopyPrinterCharPref failure.\n")); michael@0: } michael@0: #endif /* PR_LOG */ michael@0: michael@0: return rv; michael@0: } michael@0: michael@0: // Printer Enumerator michael@0: nsPrinterEnumeratorGTK::nsPrinterEnumeratorGTK() michael@0: { michael@0: } michael@0: michael@0: NS_IMPL_ISUPPORTS(nsPrinterEnumeratorGTK, nsIPrinterEnumerator) michael@0: michael@0: NS_IMETHODIMP nsPrinterEnumeratorGTK::GetPrinterNameList(nsIStringEnumerator **aPrinterNameList) michael@0: { michael@0: NS_ENSURE_ARG_POINTER(aPrinterNameList); michael@0: *aPrinterNameList = nullptr; michael@0: michael@0: nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); michael@0: if (NS_FAILED(rv)) { michael@0: return rv; michael@0: } michael@0: michael@0: uint32_t numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters(); michael@0: nsTArray *printers = new nsTArray(numPrinters); michael@0: if (!printers) { michael@0: GlobalPrinters::GetInstance()->FreeGlobalPrinters(); michael@0: return NS_ERROR_OUT_OF_MEMORY; michael@0: } michael@0: michael@0: uint32_t count = 0; michael@0: while( count < numPrinters ) michael@0: { michael@0: printers->AppendElement(*GlobalPrinters::GetInstance()->GetStringAt(count++)); michael@0: } michael@0: GlobalPrinters::GetInstance()->FreeGlobalPrinters(); michael@0: michael@0: return NS_NewAdoptingStringEnumerator(aPrinterNameList, printers); michael@0: } michael@0: michael@0: /* readonly attribute wstring defaultPrinterName; */ michael@0: NS_IMETHODIMP nsPrinterEnumeratorGTK::GetDefaultPrinterName(char16_t **aDefaultPrinterName) michael@0: { michael@0: DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::GetDefaultPrinterName()\n")); michael@0: NS_ENSURE_ARG_POINTER(aDefaultPrinterName); michael@0: michael@0: GlobalPrinters::GetInstance()->GetDefaultPrinterName(aDefaultPrinterName); michael@0: michael@0: DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", NS_ConvertUTF16toUTF8(*aDefaultPrinterName).get())); michael@0: return NS_OK; michael@0: } michael@0: michael@0: /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */ michael@0: NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const char16_t *aPrinterName, nsIPrintSettings *aPrintSettings) michael@0: { michael@0: DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter()")); michael@0: nsresult rv; michael@0: michael@0: NS_ENSURE_ARG_POINTER(aPrinterName); michael@0: NS_ENSURE_ARG_POINTER(aPrintSettings); michael@0: michael@0: NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE); michael@0: NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE); michael@0: michael@0: nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */ michael@0: printerName; /* "Stripped" name of printer */ michael@0: fullPrinterName.Assign(NS_ConvertUTF16toUTF8(aPrinterName)); michael@0: printerName.Assign(NS_ConvertUTF16toUTF8(aPrinterName)); michael@0: DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get())); michael@0: michael@0: PrintMethod type = pmInvalid; michael@0: rv = nsDeviceContextSpecGTK::GetPrintMethod(printerName, type); michael@0: if (NS_FAILED(rv)) michael@0: return rv; michael@0: michael@0: /* "Demangle" postscript printer name */ michael@0: if (type == pmPostScript) { michael@0: /* Strip the printing method name from the printer, michael@0: * e.g. turn "PostScript/foobar" to "foobar" */ michael@0: int32_t slash = printerName.FindChar('/'); michael@0: if (kNotFound != slash) michael@0: printerName.Cut(0, slash + 1); michael@0: } michael@0: michael@0: /* Set filename */ michael@0: nsAutoCString filename; michael@0: if (NS_FAILED(CopyPrinterCharPref(nullptr, printerName, "filename", filename))) { michael@0: const char *path; michael@0: michael@0: if (!(path = PR_GetEnv("PWD"))) michael@0: path = PR_GetEnv("HOME"); michael@0: michael@0: if (path) michael@0: filename = nsPrintfCString("%s/mozilla.pdf", path); michael@0: else michael@0: filename.AssignLiteral("mozilla.pdf"); michael@0: } michael@0: DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get())); michael@0: aPrintSettings->SetToFileName(NS_ConvertUTF8toUTF16(filename).get()); michael@0: michael@0: aPrintSettings->SetIsInitializedFromPrinter(true); michael@0: michael@0: if (type == pmPostScript) { michael@0: DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n")); michael@0: michael@0: nsAutoCString orientation; michael@0: if (NS_SUCCEEDED(CopyPrinterCharPref("postscript", printerName, michael@0: "orientation", orientation))) { michael@0: if (orientation.LowerCaseEqualsLiteral("portrait")) { michael@0: DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n")); michael@0: aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation); michael@0: } michael@0: else if (orientation.LowerCaseEqualsLiteral("landscape")) { michael@0: DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n")); michael@0: aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation); michael@0: } michael@0: else { michael@0: DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get())); michael@0: } michael@0: } michael@0: michael@0: /* PostScript module does not support changing the plex mode... */ michael@0: DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", "default")); michael@0: aPrintSettings->SetPlexName(MOZ_UTF16("default")); michael@0: michael@0: /* PostScript module does not support changing the resolution mode... */ michael@0: DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default")); michael@0: aPrintSettings->SetResolutionName(MOZ_UTF16("default")); michael@0: michael@0: /* PostScript module does not support changing the colorspace... */ michael@0: DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default")); michael@0: aPrintSettings->SetColorspace(MOZ_UTF16("default")); michael@0: michael@0: nsAutoCString papername; michael@0: if (NS_SUCCEEDED(CopyPrinterCharPref("postscript", printerName, michael@0: "paper_size", papername))) { michael@0: nsPaperSizePS paper; michael@0: michael@0: if (paper.Find(papername.get())) { michael@0: DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n", michael@0: paper.Name(), paper.Width_mm(), paper.Height_mm())); michael@0: aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters); michael@0: aPrintSettings->SetPaperWidth(paper.Width_mm()); michael@0: aPrintSettings->SetPaperHeight(paper.Height_mm()); michael@0: aPrintSettings->SetPaperName(NS_ConvertASCIItoUTF16(paper.Name()).get()); michael@0: } michael@0: else { michael@0: DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get())); michael@0: } michael@0: } michael@0: michael@0: bool hasSpoolerCmd = (nsPSPrinterList::kTypePS == michael@0: nsPSPrinterList::GetPrinterType(fullPrinterName)); michael@0: michael@0: if (hasSpoolerCmd) { michael@0: nsAutoCString command; michael@0: if (NS_SUCCEEDED(CopyPrinterCharPref("postscript", michael@0: printerName, "print_command", command))) { michael@0: DO_PR_DEBUG_LOG(("setting default print command to '%s'\n", michael@0: command.get())); michael@0: aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUTF16(command).get()); michael@0: } michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: return NS_ERROR_UNEXPECTED; michael@0: } michael@0: michael@0: NS_IMETHODIMP nsPrinterEnumeratorGTK::DisplayPropertiesDlg(const char16_t *aPrinter, nsIPrintSettings *aPrintSettings) michael@0: { michael@0: return NS_OK; michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: nsresult GlobalPrinters::InitializeGlobalPrinters () michael@0: { michael@0: if (PrintersAreAllocated()) { michael@0: return NS_OK; michael@0: } michael@0: michael@0: mGlobalPrinterList = new nsTArray(); michael@0: michael@0: nsPSPrinterList psMgr; michael@0: if (psMgr.Enabled()) { michael@0: /* Get the list of PostScript-module printers */ michael@0: // XXX: this function is the only user of GetPrinterList michael@0: // So it may be interesting to convert the nsCStrings michael@0: // in this function, we would save one loop here michael@0: nsTArray printerList; michael@0: psMgr.GetPrinterList(printerList); michael@0: for (uint32_t i = 0; i < printerList.Length(); i++) michael@0: { michael@0: mGlobalPrinterList->AppendElement(NS_ConvertUTF8toUTF16(printerList[i])); michael@0: } michael@0: } michael@0: michael@0: /* If there are no printers available after all checks, return an error */ michael@0: if (!mGlobalPrinterList->Length()) michael@0: { michael@0: /* Make sure we do not cache an empty printer list */ michael@0: FreeGlobalPrinters(); michael@0: michael@0: return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE; michael@0: } michael@0: michael@0: return NS_OK; michael@0: } michael@0: michael@0: //---------------------------------------------------------------------- michael@0: void GlobalPrinters::FreeGlobalPrinters() michael@0: { michael@0: if (mGlobalPrinterList) { michael@0: delete mGlobalPrinterList; michael@0: mGlobalPrinterList = nullptr; michael@0: } michael@0: } michael@0: michael@0: void michael@0: GlobalPrinters::GetDefaultPrinterName(char16_t **aDefaultPrinterName) michael@0: { michael@0: *aDefaultPrinterName = nullptr; michael@0: michael@0: bool allocate = !GlobalPrinters::GetInstance()->PrintersAreAllocated(); michael@0: michael@0: if (allocate) { michael@0: nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); michael@0: if (NS_FAILED(rv)) { michael@0: return; michael@0: } michael@0: } michael@0: NS_ASSERTION(GlobalPrinters::GetInstance()->PrintersAreAllocated(), "no GlobalPrinters"); michael@0: michael@0: if (GlobalPrinters::GetInstance()->GetNumPrinters() == 0) michael@0: return; michael@0: michael@0: *aDefaultPrinterName = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(0)); michael@0: michael@0: if (allocate) { michael@0: GlobalPrinters::GetInstance()->FreeGlobalPrinters(); michael@0: } michael@0: } michael@0: