widget/gtk/nsDeviceContextSpecG.cpp

Wed, 31 Dec 2014 06:09:35 +0100

author
Michael Schloh von Bennewitz <michael@schloh.com>
date
Wed, 31 Dec 2014 06:09:35 +0100
changeset 0
6474c204b198
permissions
-rw-r--r--

Cloned upstream origin tor-browser at tor-browser-31.3.0esr-4.5-1-build1
revision ID fc1c9ff7c1b2defdbc039f12214767608f46423f for hacking purpose.

     1 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 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 #ifdef MOZ_LOGGING
     7 #define FORCE_PR_LOG 1 /* Allow logging in the release build */
     8 #endif /* MOZ_LOGGING */
     9 #include "prlog.h"
    11 #include "plstr.h"
    13 #include "nsDeviceContextSpecG.h"
    15 #include "prenv.h" /* for PR_GetEnv */
    17 #include "nsPrintfCString.h"
    18 #include "nsReadableUtils.h"
    19 #include "nsStringEnumerator.h"
    20 #include "nsIServiceManager.h" 
    22 #include "nsPSPrinters.h"
    23 #include "nsPaperPS.h"  /* Paper size list */
    25 #include "nsPrintSettingsGTK.h"
    27 #include "nsIFileStreams.h"
    28 #include "nsIFile.h"
    29 #include "nsTArray.h"
    31 #include "mozilla/Preferences.h"
    33 #include <unistd.h>
    34 #include <sys/types.h>
    35 #include <sys/stat.h>
    37 using namespace mozilla;
    39 #ifdef PR_LOGGING 
    40 static PRLogModuleInfo *
    41 GetDeviceContextSpecGTKLog()
    42 {
    43   static PRLogModuleInfo *sLog;
    44   if (!sLog)
    45     sLog = PR_NewLogModule("DeviceContextSpecGTK");
    46   return sLog;
    47 }
    48 #endif /* PR_LOGGING */
    49 /* Macro to make lines shorter */
    50 #define DO_PR_DEBUG_LOG(x) PR_LOG(GetDeviceContextSpecGTKLog(), PR_LOG_DEBUG, x)
    52 //----------------------------------------------------------------------------------
    53 // The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecGTK
    54 // The PrinterEnumerator creates the printer info
    55 // but the nsDeviceContextSpecGTK cleans it up
    56 // If it gets created (via the Page Setup Dialog) but the user never prints anything
    57 // then it will never be delete, so this class takes care of that.
    58 class GlobalPrinters {
    59 public:
    60   static GlobalPrinters* GetInstance()   { return &mGlobalPrinters; }
    61   ~GlobalPrinters()                      { FreeGlobalPrinters(); }
    63   void      FreeGlobalPrinters();
    64   nsresult  InitializeGlobalPrinters();
    66   bool      PrintersAreAllocated()       { return mGlobalPrinterList != nullptr; }
    67   uint32_t  GetNumPrinters()
    68     { return mGlobalPrinterList ? mGlobalPrinterList->Length() : 0; }
    69   nsString* GetStringAt(int32_t aInx)    { return &mGlobalPrinterList->ElementAt(aInx); }
    70   void      GetDefaultPrinterName(char16_t **aDefaultPrinterName);
    72 protected:
    73   GlobalPrinters() {}
    75   static GlobalPrinters mGlobalPrinters;
    76   static nsTArray<nsString>* mGlobalPrinterList;
    77 };
    79 //---------------
    80 // static members
    81 GlobalPrinters GlobalPrinters::mGlobalPrinters;
    82 nsTArray<nsString>* GlobalPrinters::mGlobalPrinterList = nullptr;
    83 //---------------
    85 nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()
    86   : mPrintJob(nullptr)
    87   , mGtkPrinter(nullptr)
    88   , mGtkPrintSettings(nullptr)
    89   , mGtkPageSetup(nullptr)
    90 {
    91   DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n"));
    92 }
    94 nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()
    95 {
    96   DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()\n"));
    98   if (mGtkPageSetup) {
    99     g_object_unref(mGtkPageSetup);
   100   }
   102   if (mGtkPrintSettings) {
   103     g_object_unref(mGtkPrintSettings);
   104   }
   105 }
   107 NS_IMPL_ISUPPORTS(nsDeviceContextSpecGTK,
   108                   nsIDeviceContextSpec)
   110 #include "gfxPDFSurface.h"
   111 #include "gfxPSSurface.h"
   112 NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurface)
   113 {
   114   *aSurface = nullptr;
   116   const char *path;
   117   GetPath(&path);
   119   double width, height;
   120   mPrintSettings->GetEffectivePageSize(&width, &height);
   122   // convert twips to points
   123   width  /= TWIPS_PER_POINT_FLOAT;
   124   height /= TWIPS_PER_POINT_FLOAT;
   126   DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", path, width, height));
   127   nsresult rv;
   129   // Spool file. Use Glib's temporary file function since we're
   130   // already dependent on the gtk software stack.
   131   gchar *buf;
   132   gint fd = g_file_open_tmp("XXXXXX.tmp", &buf, nullptr);
   133   if (-1 == fd)
   134     return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
   135   close(fd);
   137   rv = NS_NewNativeLocalFile(nsDependentCString(buf), false,
   138                              getter_AddRefs(mSpoolFile));
   139   if (NS_FAILED(rv)) {
   140     unlink(buf);
   141     return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
   142   }
   144   mSpoolName = buf;
   145   g_free(buf);
   147   mSpoolFile->SetPermissions(0600);
   149   nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1");
   150   rv = stream->Init(mSpoolFile, -1, -1, 0);
   151   if (NS_FAILED(rv))
   152     return rv;
   154   int16_t format;
   155   mPrintSettings->GetOutputFormat(&format);
   157   nsRefPtr<gfxASurface> surface;
   158   gfxSize surfaceSize(width, height);
   160   // Determine the real format with some GTK magic
   161   if (format == nsIPrintSettings::kOutputFormatNative) {
   162     if (mIsPPreview) {
   163       // There is nothing to detect on Print Preview, use PS.
   164       format = nsIPrintSettings::kOutputFormatPS;
   165     } else {
   166       const gchar* fmtGTK = gtk_print_settings_get(mGtkPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
   167       if (!fmtGTK && GTK_IS_PRINTER(mGtkPrinter)) {
   168         // Likely not print-to-file, check printer's capabilities
   170         // Prior to gtk 2.24, gtk_printer_accepts_pdf() and
   171         // gtk_printer_accepts_ps() always returned true regardless of the
   172         // printer's capability.
   173         if (gtk_major_version > 2 ||
   174             (gtk_major_version == 2 && gtk_minor_version >= 24)) {
   175           format =
   176             gtk_printer_accepts_pdf(mGtkPrinter) ?
   177             static_cast<int16_t>(nsIPrintSettings::kOutputFormatPDF) :
   178             static_cast<int16_t>(nsIPrintSettings::kOutputFormatPS);
   179         } else {
   180           format = nsIPrintSettings::kOutputFormatPS;
   181         }
   183       } else if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) {
   184         format = nsIPrintSettings::kOutputFormatPDF;
   185       } else {
   186         format = nsIPrintSettings::kOutputFormatPS;
   187       }
   188     }
   189   }
   191   if (format == nsIPrintSettings::kOutputFormatPDF) {
   192     surface = new gfxPDFSurface(stream, surfaceSize);
   193   } else {
   194     int32_t orientation;
   195     mPrintSettings->GetOrientation(&orientation);
   196     if (nsIPrintSettings::kPortraitOrientation == orientation) {
   197       surface = new gfxPSSurface(stream, surfaceSize, gfxPSSurface::PORTRAIT);
   198     } else {
   199       surface = new gfxPSSurface(stream, surfaceSize, gfxPSSurface::LANDSCAPE);
   200     }
   201   }
   203   if (!surface)
   204     return NS_ERROR_OUT_OF_MEMORY;
   206   surface.swap(*aSurface);
   208   return NS_OK;
   209 }
   211 /** -------------------------------------------------------
   212  *  Initialize the nsDeviceContextSpecGTK
   213  *  @update   dc 2/15/98
   214  *  @update   syd 3/2/99
   215  */
   216 NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIWidget *aWidget,
   217                                            nsIPrintSettings* aPS,
   218                                            bool aIsPrintPreview)
   219 {
   220   DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::Init(aPS=%p)\n", aPS));
   222   if (gtk_major_version < 2 ||
   223       (gtk_major_version == 2 && gtk_minor_version < 10))
   224     return NS_ERROR_NOT_AVAILABLE;  // I'm so sorry bz
   226   mPrintSettings = aPS;
   227   mIsPPreview = aIsPrintPreview;
   229   // This is only set by embedders
   230   bool toFile;
   231   aPS->GetPrintToFile(&toFile);
   233   mToPrinter = !toFile && !aIsPrintPreview;
   235   nsCOMPtr<nsPrintSettingsGTK> printSettingsGTK(do_QueryInterface(aPS));
   236   if (!printSettingsGTK)
   237     return NS_ERROR_NO_INTERFACE;
   239   mGtkPrinter = printSettingsGTK->GetGtkPrinter();
   240   mGtkPrintSettings = printSettingsGTK->GetGtkPrintSettings();
   241   mGtkPageSetup = printSettingsGTK->GetGtkPageSetup();
   243   // This is a horrible workaround for some printer driver bugs that treat custom page sizes different
   244   // to standard ones. If our paper object matches one of a standard one, use a standard paper size
   245   // object instead. See bug 414314 for more info.
   246   GtkPaperSize* geckosHackishPaperSize = gtk_page_setup_get_paper_size(mGtkPageSetup);
   247   GtkPaperSize* standardGtkPaperSize = gtk_paper_size_new(gtk_paper_size_get_name(geckosHackishPaperSize));
   249   mGtkPageSetup = gtk_page_setup_copy(mGtkPageSetup);
   250   mGtkPrintSettings = gtk_print_settings_copy(mGtkPrintSettings);
   252   GtkPaperSize* properPaperSize;
   253   if (gtk_paper_size_is_equal(geckosHackishPaperSize, standardGtkPaperSize)) {
   254     properPaperSize = standardGtkPaperSize;
   255   } else {
   256     properPaperSize = geckosHackishPaperSize;
   257   }
   258   gtk_print_settings_set_paper_size(mGtkPrintSettings, properPaperSize);
   259   gtk_page_setup_set_paper_size_and_default_margins(mGtkPageSetup, properPaperSize);
   260   gtk_paper_size_free(standardGtkPaperSize);
   262   return NS_OK;
   263 }
   265 NS_IMETHODIMP nsDeviceContextSpecGTK::GetPath(const char **aPath)      
   266 {
   267   *aPath = mPath;
   268   return NS_OK;
   269 }
   271 /* static !! */
   272 nsresult nsDeviceContextSpecGTK::GetPrintMethod(const char *aPrinter, PrintMethod &aMethod)
   273 {
   274   aMethod = pmPostScript;
   275   return NS_OK;
   276 }
   278 static void
   279 #if (MOZ_WIDGET_GTK == 3)
   280 print_callback(GtkPrintJob *aJob, gpointer aData, const GError *aError) {
   281 #else
   282 print_callback(GtkPrintJob *aJob, gpointer aData, GError *aError) {
   283 #endif
   284   g_object_unref(aJob);
   285   ((nsIFile*) aData)->Remove(false);
   286 }
   288 static void
   289 ns_release_macro(gpointer aData) {
   290   nsIFile* spoolFile = (nsIFile*) aData;
   291   NS_RELEASE(spoolFile);
   292 }
   294 NS_IMETHODIMP nsDeviceContextSpecGTK::BeginDocument(const nsAString& aTitle, char16_t * aPrintToFileName,
   295                                                     int32_t aStartPage, int32_t aEndPage)
   296 {
   297   if (mToPrinter) {
   298     if (!GTK_IS_PRINTER(mGtkPrinter))
   299       return NS_ERROR_FAILURE;
   301     mPrintJob = gtk_print_job_new(NS_ConvertUTF16toUTF8(aTitle).get(), mGtkPrinter,
   302                                   mGtkPrintSettings, mGtkPageSetup);
   303   }
   305   return NS_OK;
   306 }
   308 NS_IMETHODIMP nsDeviceContextSpecGTK::EndDocument()
   309 {
   310   if (mToPrinter) {
   311     if (!mPrintJob)
   312       return NS_OK; // The operation was aborted.
   314     if (!gtk_print_job_set_source_file(mPrintJob, mSpoolName.get(), nullptr))
   315       return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
   317     NS_ADDREF(mSpoolFile.get());
   318     gtk_print_job_send(mPrintJob, print_callback, mSpoolFile, ns_release_macro);
   319   } else {
   320     // Handle print-to-file ourselves for the benefit of embedders
   321     nsXPIDLString targetPath;
   322     nsCOMPtr<nsIFile> destFile;
   323     mPrintSettings->GetToFileName(getter_Copies(targetPath));
   325     nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(targetPath),
   326                                         false, getter_AddRefs(destFile));
   327     NS_ENSURE_SUCCESS(rv, rv);
   329     nsAutoString destLeafName;
   330     rv = destFile->GetLeafName(destLeafName);
   331     NS_ENSURE_SUCCESS(rv, rv);
   333     nsCOMPtr<nsIFile> destDir;
   334     rv = destFile->GetParent(getter_AddRefs(destDir));
   335     NS_ENSURE_SUCCESS(rv, rv);
   337     rv = mSpoolFile->MoveTo(destDir, destLeafName);
   338     NS_ENSURE_SUCCESS(rv, rv);
   340     // This is the standard way to get the UNIX umask. Ugh.
   341     mode_t mask = umask(0);
   342     umask(mask);
   343     // If you're not familiar with umasks, they contain the bits of what NOT to set in the permissions
   344     // (thats because files and directories have different numbers of bits for their permissions)
   345     destFile->SetPermissions(0666 & ~(mask));
   346   }
   347   return NS_OK;
   348 }
   350 /* Get prefs for printer
   351  * Search order:
   352  * - Get prefs per printer name and module name
   353  * - Get prefs per printer name
   354  * - Get prefs per module name
   355  * - Get prefs
   356  */
   357 static
   358 nsresult CopyPrinterCharPref(const char *modulename, const char *printername,
   359                              const char *prefname, nsCString &return_buf)
   360 {
   361   DO_PR_DEBUG_LOG(("CopyPrinterCharPref('%s', '%s', '%s')\n", modulename, printername, prefname));
   363   nsresult rv = NS_ERROR_FAILURE;
   365   if (printername && modulename) {
   366     /* Get prefs per printer name and module name */
   367     nsPrintfCString name("print.%s.printer_%s.%s", modulename, printername, prefname);
   368     DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
   369     rv = Preferences::GetCString(name.get(), &return_buf);
   370   }
   372   if (NS_FAILED(rv)) { 
   373     if (printername) {
   374       /* Get prefs per printer name */
   375       nsPrintfCString name("print.printer_%s.%s", printername, prefname);
   376       DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
   377       rv = Preferences::GetCString(name.get(), &return_buf);
   378     }
   380     if (NS_FAILED(rv)) {
   381       if (modulename) {
   382         /* Get prefs per module name */
   383         nsPrintfCString name("print.%s.%s", modulename, prefname);
   384         DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
   385         rv = Preferences::GetCString(name.get(), &return_buf);
   386       }
   388       if (NS_FAILED(rv)) {
   389         /* Get prefs */
   390         nsPrintfCString name("print.%s", prefname);
   391         DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
   392         rv = Preferences::GetCString(name.get(), &return_buf);
   393       }
   394     }
   395   }
   397 #ifdef PR_LOG  
   398   if (NS_SUCCEEDED(rv)) {
   399     DO_PR_DEBUG_LOG(("CopyPrinterCharPref returning '%s'.\n", return_buf.get()));
   400   }
   401   else
   402   {
   403     DO_PR_DEBUG_LOG(("CopyPrinterCharPref failure.\n"));
   404   }
   405 #endif /* PR_LOG */
   407   return rv;
   408 }
   410 //  Printer Enumerator
   411 nsPrinterEnumeratorGTK::nsPrinterEnumeratorGTK()
   412 {
   413 }
   415 NS_IMPL_ISUPPORTS(nsPrinterEnumeratorGTK, nsIPrinterEnumerator)
   417 NS_IMETHODIMP nsPrinterEnumeratorGTK::GetPrinterNameList(nsIStringEnumerator **aPrinterNameList)
   418 {
   419   NS_ENSURE_ARG_POINTER(aPrinterNameList);
   420   *aPrinterNameList = nullptr;
   422   nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
   423   if (NS_FAILED(rv)) {
   424     return rv;
   425   }
   427   uint32_t numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters();
   428   nsTArray<nsString> *printers = new nsTArray<nsString>(numPrinters);
   429   if (!printers) {
   430     GlobalPrinters::GetInstance()->FreeGlobalPrinters();
   431     return NS_ERROR_OUT_OF_MEMORY;
   432   }
   434   uint32_t count = 0;
   435   while( count < numPrinters )
   436   {
   437     printers->AppendElement(*GlobalPrinters::GetInstance()->GetStringAt(count++));
   438   }
   439   GlobalPrinters::GetInstance()->FreeGlobalPrinters();
   441   return NS_NewAdoptingStringEnumerator(aPrinterNameList, printers);
   442 }
   444 /* readonly attribute wstring defaultPrinterName; */
   445 NS_IMETHODIMP nsPrinterEnumeratorGTK::GetDefaultPrinterName(char16_t **aDefaultPrinterName)
   446 {
   447   DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::GetDefaultPrinterName()\n"));
   448   NS_ENSURE_ARG_POINTER(aDefaultPrinterName);
   450   GlobalPrinters::GetInstance()->GetDefaultPrinterName(aDefaultPrinterName);
   452   DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", NS_ConvertUTF16toUTF8(*aDefaultPrinterName).get()));
   453   return NS_OK;
   454 }
   456 /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */
   457 NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const char16_t *aPrinterName, nsIPrintSettings *aPrintSettings)
   458 {
   459   DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter()"));
   460   nsresult rv;
   462   NS_ENSURE_ARG_POINTER(aPrinterName);
   463   NS_ENSURE_ARG_POINTER(aPrintSettings);
   465   NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE);
   466   NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE);
   468   nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */ 
   469                  printerName;     /* "Stripped" name of printer */
   470   fullPrinterName.Assign(NS_ConvertUTF16toUTF8(aPrinterName));
   471   printerName.Assign(NS_ConvertUTF16toUTF8(aPrinterName));
   472   DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get()));
   474   PrintMethod type = pmInvalid;
   475   rv = nsDeviceContextSpecGTK::GetPrintMethod(printerName, type);
   476   if (NS_FAILED(rv))
   477     return rv;
   479   /* "Demangle" postscript printer name */
   480   if (type == pmPostScript) {
   481     /* Strip the printing method name from the printer,
   482      * e.g. turn "PostScript/foobar" to "foobar" */
   483     int32_t slash = printerName.FindChar('/');
   484     if (kNotFound != slash)
   485       printerName.Cut(0, slash + 1);
   486   }
   488   /* Set filename */
   489   nsAutoCString filename;
   490   if (NS_FAILED(CopyPrinterCharPref(nullptr, printerName, "filename", filename))) {
   491     const char *path;
   493     if (!(path = PR_GetEnv("PWD")))
   494       path = PR_GetEnv("HOME");
   496     if (path)
   497       filename = nsPrintfCString("%s/mozilla.pdf", path);
   498     else
   499       filename.AssignLiteral("mozilla.pdf");
   500   }  
   501   DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get()));
   502   aPrintSettings->SetToFileName(NS_ConvertUTF8toUTF16(filename).get());
   504   aPrintSettings->SetIsInitializedFromPrinter(true);
   506   if (type == pmPostScript) {
   507     DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n"));
   509     nsAutoCString orientation;
   510     if (NS_SUCCEEDED(CopyPrinterCharPref("postscript", printerName,
   511                                          "orientation", orientation))) {
   512       if (orientation.LowerCaseEqualsLiteral("portrait")) {
   513         DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n"));
   514         aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
   515       }
   516       else if (orientation.LowerCaseEqualsLiteral("landscape")) {
   517         DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n"));
   518         aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);  
   519       }
   520       else {
   521         DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get()));
   522       }
   523     }
   525     /* PostScript module does not support changing the plex mode... */
   526     DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", "default"));
   527     aPrintSettings->SetPlexName(MOZ_UTF16("default"));
   529     /* PostScript module does not support changing the resolution mode... */
   530     DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default"));
   531     aPrintSettings->SetResolutionName(MOZ_UTF16("default"));
   533     /* PostScript module does not support changing the colorspace... */
   534     DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default"));
   535     aPrintSettings->SetColorspace(MOZ_UTF16("default"));
   537     nsAutoCString papername;
   538     if (NS_SUCCEEDED(CopyPrinterCharPref("postscript", printerName,
   539                                          "paper_size", papername))) {
   540       nsPaperSizePS paper;
   542       if (paper.Find(papername.get())) {
   543         DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
   544               paper.Name(), paper.Width_mm(), paper.Height_mm()));
   545 	aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
   546         aPrintSettings->SetPaperWidth(paper.Width_mm());
   547         aPrintSettings->SetPaperHeight(paper.Height_mm());
   548         aPrintSettings->SetPaperName(NS_ConvertASCIItoUTF16(paper.Name()).get());
   549       }
   550       else {
   551         DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
   552       }
   553     }
   555     bool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
   556         nsPSPrinterList::GetPrinterType(fullPrinterName));
   558     if (hasSpoolerCmd) {
   559       nsAutoCString command;
   560       if (NS_SUCCEEDED(CopyPrinterCharPref("postscript",
   561             printerName, "print_command", command))) {
   562         DO_PR_DEBUG_LOG(("setting default print command to '%s'\n",
   563             command.get()));
   564         aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUTF16(command).get());
   565       }
   566     }
   568     return NS_OK;    
   569   }
   571   return NS_ERROR_UNEXPECTED;
   572 }
   574 NS_IMETHODIMP nsPrinterEnumeratorGTK::DisplayPropertiesDlg(const char16_t *aPrinter, nsIPrintSettings *aPrintSettings)
   575 {
   576   return NS_OK;
   577 }
   579 //----------------------------------------------------------------------
   580 nsresult GlobalPrinters::InitializeGlobalPrinters ()
   581 {
   582   if (PrintersAreAllocated()) {
   583     return NS_OK;
   584   }
   586   mGlobalPrinterList = new nsTArray<nsString>();
   588   nsPSPrinterList psMgr;
   589   if (psMgr.Enabled()) {
   590     /* Get the list of PostScript-module printers */
   591     // XXX: this function is the only user of GetPrinterList
   592     // So it may be interesting to convert the nsCStrings
   593     // in this function, we would save one loop here
   594     nsTArray<nsCString> printerList;
   595     psMgr.GetPrinterList(printerList);
   596     for (uint32_t i = 0; i < printerList.Length(); i++)
   597     {
   598       mGlobalPrinterList->AppendElement(NS_ConvertUTF8toUTF16(printerList[i]));
   599     }
   600   }
   602   /* If there are no printers available after all checks, return an error */
   603   if (!mGlobalPrinterList->Length())
   604   {
   605     /* Make sure we do not cache an empty printer list */
   606     FreeGlobalPrinters();
   608     return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
   609   }
   611   return NS_OK;
   612 }
   614 //----------------------------------------------------------------------
   615 void GlobalPrinters::FreeGlobalPrinters()
   616 {
   617   if (mGlobalPrinterList) {
   618     delete mGlobalPrinterList;
   619     mGlobalPrinterList = nullptr;
   620   }  
   621 }
   623 void 
   624 GlobalPrinters::GetDefaultPrinterName(char16_t **aDefaultPrinterName)
   625 {
   626   *aDefaultPrinterName = nullptr;
   628   bool allocate = !GlobalPrinters::GetInstance()->PrintersAreAllocated();
   630   if (allocate) {
   631     nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
   632     if (NS_FAILED(rv)) {
   633       return;
   634     }
   635   }
   636   NS_ASSERTION(GlobalPrinters::GetInstance()->PrintersAreAllocated(), "no GlobalPrinters");
   638   if (GlobalPrinters::GetInstance()->GetNumPrinters() == 0)
   639     return;
   641   *aDefaultPrinterName = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(0));
   643   if (allocate) {  
   644     GlobalPrinters::GetInstance()->FreeGlobalPrinters();
   645   }  
   646 }

mercurial