Back to index

lightning-sunbird  0.9+nobinonly
nsDeviceContextSpecG.cpp
Go to the documentation of this file.
00001 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
00002 /* ***** BEGIN LICENSE BLOCK *****
00003  * Version: MPL 1.1/GPL 2.0/LGPL 2.1
00004  *
00005  * The contents of this file are subject to the Mozilla Public License Version
00006  * 1.1 (the "License"); you may not use this file except in compliance with
00007  * the License. You may obtain a copy of the License at
00008  * http://www.mozilla.org/MPL/
00009  *
00010  * Software distributed under the License is distributed on an "AS IS" basis,
00011  * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
00012  * for the specific language governing rights and limitations under the
00013  * License.
00014  *
00015  * The Original Code is mozilla.org code.
00016  *
00017  * The Initial Developer of the Original Code is
00018  * Netscape Communications Corporation.
00019  * Portions created by the Initial Developer are Copyright (C) 1998
00020  * the Initial Developer. All Rights Reserved.
00021  *
00022  * Contributor(s):
00023  *   Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
00024  *   Ken Herron <kherron+mozilla@fmailbox.com>
00025  *   Julien Lafon <julien.lafon@gmail.com>
00026  *
00027  * Alternatively, the contents of this file may be used under the terms of
00028  * either of the GNU General Public License Version 2 or later (the "GPL"),
00029  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00030  * in which case the provisions of the GPL or the LGPL are applicable instead
00031  * of those above. If you wish to allow use of your version of this file only
00032  * under the terms of either the GPL or the LGPL, and not to allow others to
00033  * use your version of this file under the terms of the MPL, indicate your
00034  * decision by deleting the provisions above and replace them with the notice
00035  * and other provisions required by the GPL or the LGPL. If you do not delete
00036  * the provisions above, a recipient may use your version of this file under
00037  * the terms of any one of the MPL, the GPL or the LGPL.
00038  *
00039  * ***** END LICENSE BLOCK ***** */
00040  
00041 /* Store per-printer features in temp. prefs vars that the
00042  * print dialog can pick them up... */
00043 #define SET_PRINTER_FEATURES_VIA_PREFS 1 
00044 #define PRINTERFEATURES_PREF "print.tmp.printerfeatures"
00045 
00046 #ifdef MOZ_LOGGING
00047 #define FORCE_PR_LOG 1 /* Allow logging in the release build */
00048 #endif /* MOZ_LOGGING */
00049 #include "prlog.h"
00050 
00051 #include "plstr.h"
00052 
00053 #include "nsDeviceContextSpecG.h"
00054 
00055 #include "nsIPref.h"
00056 #include "prenv.h" /* for PR_GetEnv */
00057 
00058 #include "nsPrintfCString.h"
00059 #include "nsReadableUtils.h"
00060 #include "nsIServiceManager.h" 
00061 
00062 #ifdef USE_XPRINT
00063 #include "xprintutil.h"
00064 #endif /* USE_XPRINT */
00065 
00066 #ifdef USE_POSTSCRIPT
00067 #include "nsPSPrinters.h"
00068 #include "nsPaperPS.h"  /* Paper size list */
00069 #endif /* USE_POSTSCRIPT */
00070 
00071 /* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */
00072 #define MAKE_PR_BOOL(val) ((val)?(PR_TRUE):(PR_FALSE))
00073 
00074 #ifdef PR_LOGGING 
00075 static PRLogModuleInfo *DeviceContextSpecGTKLM = PR_NewLogModule("DeviceContextSpecGTK");
00076 #endif /* PR_LOGGING */
00077 /* Macro to make lines shorter */
00078 #define DO_PR_DEBUG_LOG(x) PR_LOG(DeviceContextSpecGTKLM, PR_LOG_DEBUG, x)
00079 
00080 //----------------------------------------------------------------------------------
00081 // The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecGTK
00082 // The PrinterEnumerator creates the printer info
00083 // but the nsDeviceContextSpecGTK cleans it up
00084 // If it gets created (via the Page Setup Dialog) but the user never prints anything
00085 // then it will never be delete, so this class takes care of that.
00086 class GlobalPrinters {
00087 public:
00088   static GlobalPrinters* GetInstance()   { return &mGlobalPrinters; }
00089   ~GlobalPrinters()                      { FreeGlobalPrinters(); }
00090 
00091   void      FreeGlobalPrinters();
00092   nsresult  InitializeGlobalPrinters();
00093 
00094   PRBool    PrintersAreAllocated()       { return mGlobalPrinterList != nsnull; }
00095   PRInt32   GetNumPrinters()
00096     { return mGlobalPrinterList ? mGlobalPrinterList->Count() : 0; }
00097   nsString* GetStringAt(PRInt32 aInx)    { return mGlobalPrinterList->StringAt(aInx); }
00098   void      GetDefaultPrinterName(PRUnichar **aDefaultPrinterName);
00099 
00100 protected:
00101   GlobalPrinters() {}
00102 
00103   static GlobalPrinters mGlobalPrinters;
00104   static nsStringArray* mGlobalPrinterList;
00105 };
00106 
00107 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00108 /* "Prototype" for the new nsPrinterFeatures service */
00109 class nsPrinterFeatures {
00110 public:
00111   nsPrinterFeatures( const char *printername );
00112   ~nsPrinterFeatures() {};
00113 
00114   /* Does this printer allow to set/change the paper size ? */
00115   void SetCanChangePaperSize( PRBool aCanSetPaperSize );
00116   /* Does this Mozilla print module allow set/change the paper size ? */
00117   void SetSupportsPaperSizeChange( PRBool aSupportsPaperSizeChange );
00118   /* Set number of paper size records and the records itself */
00119   void SetNumPaperSizeRecords( PRInt32 aCount );
00120   void SetPaperRecord( PRInt32 aIndex, const char *aName, PRInt32 aWidthMM, PRInt32 aHeightMM, PRBool aIsInch );
00121 
00122   /* Does this printer allow to set/change the content orientation ? */
00123   void SetCanChangeOrientation( PRBool aCanSetOrientation );
00124   /* Does this Mozilla print module allow set/change the content orientation ? */
00125   void SetSupportsOrientationChange( PRBool aSupportsOrientationChange );
00126   /* Set number of orientation records and the records itself */
00127   void SetNumOrientationRecords( PRInt32 aCount );
00128   void SetOrientationRecord( PRInt32 aIndex, const char *aName );
00129 
00130   /* Does this printer allow to set/change the plex mode ? */
00131   void SetCanChangePlex( PRBool aCanSetPlex );
00132   /* Does this Mozilla print module allow set/change the plex mode ? */
00133   void SetSupportsPlexChange( PRBool aSupportsPlexChange );
00134   /* Set number of plex records and the records itself */
00135   void SetNumPlexRecords( PRInt32 aCount );
00136   void SetPlexRecord( PRInt32 aIndex, const char *aName );
00137 
00138   /* Does this printer allow to set/change the resolution name ? */
00139   void SetCanChangeResolutionName( PRBool aCanSetResolutionName );
00140   /* Does this Mozilla print module allow set/change the resolution name ? */
00141   void SetSupportsResolutionNameChange( PRBool aSupportsResolutionChange );
00142   /* Set number of resolution records and the records itself */
00143   void SetNumResolutionNameRecords( PRInt32 aCount );
00144   void SetResolutionNameRecord( PRInt32 aIndex, const char *aName );
00145 
00146   /* Does this printer allow to set/change the colorspace ? */
00147   void SetCanChangeColorspace( PRBool aCanSetColorspace );
00148   /* Does this Mozilla print module allow set/change the colorspace ? */
00149   void SetSupportsColorspaceChange( PRBool aSupportsColorspace );
00150   /* Set number of colorspace records and the records itself */
00151   void SetNumColorspaceRecords( PRInt32 aCount );
00152   void SetColorspaceRecord( PRInt32 aIndex, const char *aName );
00153 
00154   /* Does this device allow to set/change the usage of the internal grayscale mode ? */
00155   void SetCanChangePrintInColor( PRBool aCanSetPrintInColor );
00156   /* Does this printer allow to set/change the usage of the internal grayscale mode ? */
00157   void SetSupportsPrintInColorChange( PRBool aSupportPrintInColorChange );
00158 
00159   /* Does this device allow to set/change the usage of font download to the printer? */
00160   void SetCanChangeDownloadFonts( PRBool aCanSetDownloadFonts );
00161   /* Does this printer allow to set/change the usage of font download to the printer? */
00162   void SetSupportsDownloadFontsChange( PRBool aSupportDownloadFontsChange );
00163 
00164   /* Does this device allow to set/change the job title ? */
00165   void SetCanChangeJobTitle( PRBool aCanSetJobTitle );
00166   /* Does this printer allow to set/change the job title ? */
00167   void SetSupportsJobTitleChange( PRBool aSupportJobTitleChange );
00168     
00169   /* Does this device allow to set/change the spooler command ? */
00170   void SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand );
00171   /* Does this printer allow to set/change the spooler command ? */
00172   void SetSupportsSpoolerCommandChange( PRBool aSupportSpoolerCommandChange );
00173   
00174   /* Does this device allow to set/change number of copies for an document ? */
00175   void SetCanChangeNumCopies( PRBool aCanSetNumCopies );
00176 
00177   /* Does this device allow multiple devicecontext instances to be used in
00178    * parallel (e.g. print while the device is already in use by print-preview
00179    * or printing while another print job is in progress) ? */
00180   void SetMultipleConcurrentDeviceContextsSupported( PRBool aCanUseMultipleInstances );
00181   
00182 private:
00183   /* private helper methods */
00184   void SetBoolValue( const char *tagname, PRBool value );
00185   void SetIntValue(  const char *tagname, PRInt32 value );
00186   void SetCharValue(  const char *tagname, const char *value );
00187 
00188   nsXPIDLCString    mPrinterName;
00189   nsCOMPtr<nsIPref> mPrefs;
00190 };
00191 
00192 void nsPrinterFeatures::SetBoolValue( const char *tagname, PRBool value )
00193 {
00194   mPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value);
00195 }
00196 
00197 void nsPrinterFeatures::SetIntValue(  const char *tagname, PRInt32 value )
00198 {
00199   mPrefs->SetIntPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value);
00200 }
00201 
00202 void nsPrinterFeatures::SetCharValue(  const char *tagname, const char *value )
00203 {
00204   mPrefs->SetCharPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value);
00205 }
00206 
00207 nsPrinterFeatures::nsPrinterFeatures( const char *printername )
00208 {
00209   DO_PR_DEBUG_LOG(("nsPrinterFeatures::nsPrinterFeatures('%s')\n", printername));
00210   mPrinterName.Assign(printername);
00211   mPrefs = do_GetService(NS_PREF_CONTRACTID);
00212  
00213   SetBoolValue("has_special_printerfeatures", PR_TRUE);
00214 }
00215 
00216 void nsPrinterFeatures::SetCanChangePaperSize( PRBool aCanSetPaperSize )
00217 {
00218   SetBoolValue("can_change_paper_size", aCanSetPaperSize);
00219 }
00220 
00221 void nsPrinterFeatures::SetSupportsPaperSizeChange( PRBool aSupportsPaperSizeChange )
00222 {
00223   SetBoolValue("supports_paper_size_change", aSupportsPaperSizeChange);
00224 }
00225 
00226 /* Set number of paper size records and the records itself */
00227 void nsPrinterFeatures::SetNumPaperSizeRecords( PRInt32 aCount )
00228 {
00229   SetIntValue("paper.count", aCount);          
00230 }
00231 
00232 void nsPrinterFeatures::SetPaperRecord(PRInt32 aIndex, const char *aPaperName, PRInt32 aWidthMM, PRInt32 aHeightMM, PRBool aIsInch)
00233 {
00234   SetCharValue(nsPrintfCString(256, "paper.%d.name",      aIndex).get(), aPaperName);
00235   SetIntValue( nsPrintfCString(256, "paper.%d.width_mm",  aIndex).get(), aWidthMM);
00236   SetIntValue( nsPrintfCString(256, "paper.%d.height_mm", aIndex).get(), aHeightMM);
00237   SetBoolValue(nsPrintfCString(256, "paper.%d.is_inch",   aIndex).get(), aIsInch);
00238 }
00239 
00240 void nsPrinterFeatures::SetCanChangeOrientation( PRBool aCanSetOrientation )
00241 {
00242   SetBoolValue("can_change_orientation", aCanSetOrientation);
00243 }
00244 
00245 void nsPrinterFeatures::SetSupportsOrientationChange( PRBool aSupportsOrientationChange )
00246 {
00247   SetBoolValue("supports_orientation_change", aSupportsOrientationChange);
00248 }
00249 
00250 void nsPrinterFeatures::SetNumOrientationRecords( PRInt32 aCount )
00251 {
00252   SetIntValue("orientation.count", aCount);          
00253 }
00254 
00255 void nsPrinterFeatures::SetOrientationRecord( PRInt32 aIndex, const char *aOrientationName )
00256 {
00257   SetCharValue(nsPrintfCString(256, "orientation.%d.name", aIndex).get(), aOrientationName);
00258 }
00259 
00260 void nsPrinterFeatures::SetCanChangePlex( PRBool aCanSetPlex )
00261 {
00262   SetBoolValue("can_change_plex", aCanSetPlex);
00263 }
00264 
00265 void nsPrinterFeatures::SetSupportsPlexChange( PRBool aSupportsPlexChange )
00266 {
00267   SetBoolValue("supports_plex_change", aSupportsPlexChange);
00268 }
00269 
00270 void nsPrinterFeatures::SetNumPlexRecords( PRInt32 aCount )
00271 {
00272   SetIntValue("plex.count", aCount);          
00273 }
00274 
00275 void nsPrinterFeatures::SetPlexRecord( PRInt32 aIndex, const char *aPlexName )
00276 {
00277   SetCharValue(nsPrintfCString(256, "plex.%d.name", aIndex).get(), aPlexName);
00278 }
00279 
00280 void nsPrinterFeatures::SetCanChangeResolutionName( PRBool aCanSetResolutionName )
00281 {
00282   SetBoolValue("can_change_resolution", aCanSetResolutionName);
00283 }
00284 
00285 void nsPrinterFeatures::SetSupportsResolutionNameChange( PRBool aSupportsResolutionNameChange )
00286 {
00287   SetBoolValue("supports_resolution_change", aSupportsResolutionNameChange);
00288 }
00289 
00290 void nsPrinterFeatures::SetNumResolutionNameRecords( PRInt32 aCount )
00291 {
00292   SetIntValue("resolution.count", aCount);          
00293 }
00294 
00295 void nsPrinterFeatures::SetResolutionNameRecord( PRInt32 aIndex, const char *aResolutionName )
00296 {
00297   SetCharValue(nsPrintfCString(256, "resolution.%d.name", aIndex).get(), aResolutionName);
00298 }
00299 
00300 void nsPrinterFeatures::SetCanChangeColorspace( PRBool aCanSetColorspace )
00301 {
00302   SetBoolValue("can_change_colorspace", aCanSetColorspace);
00303 }
00304 
00305 void nsPrinterFeatures::SetSupportsColorspaceChange( PRBool aSupportsColorspaceChange )
00306 {
00307   SetBoolValue("supports_colorspace_change", aSupportsColorspaceChange);
00308 }
00309 
00310 void nsPrinterFeatures::SetNumColorspaceRecords( PRInt32 aCount )
00311 {
00312   SetIntValue("colorspace.count", aCount);          
00313 }
00314 
00315 void nsPrinterFeatures::SetColorspaceRecord( PRInt32 aIndex, const char *aColorspace )
00316 {
00317   SetCharValue(nsPrintfCString(256, "colorspace.%d.name", aIndex).get(), aColorspace);
00318 }
00319 
00320 void nsPrinterFeatures::SetCanChangeDownloadFonts( PRBool aCanSetDownloadFonts )
00321 {
00322   SetBoolValue("can_change_downloadfonts", aCanSetDownloadFonts);
00323 }
00324 
00325 void nsPrinterFeatures::SetSupportsDownloadFontsChange( PRBool aSupportDownloadFontsChange )
00326 {
00327   SetBoolValue("supports_downloadfonts_change", aSupportDownloadFontsChange);
00328 }
00329 
00330 void nsPrinterFeatures::SetCanChangePrintInColor( PRBool aCanSetPrintInColor )
00331 {
00332   SetBoolValue("can_change_printincolor", aCanSetPrintInColor);
00333 }
00334 
00335 void nsPrinterFeatures::SetSupportsPrintInColorChange( PRBool aSupportPrintInColorChange )
00336 {
00337   SetBoolValue("supports_printincolor_change", aSupportPrintInColorChange);
00338 }
00339 
00340 void nsPrinterFeatures::SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand )
00341 {
00342   SetBoolValue("can_change_spoolercommand", aCanSetSpoolerCommand);
00343 }
00344 
00345 void nsPrinterFeatures::SetSupportsSpoolerCommandChange( PRBool aSupportSpoolerCommandChange )
00346 {
00347   SetBoolValue("supports_spoolercommand_change", aSupportSpoolerCommandChange);
00348 }
00349 
00350 void nsPrinterFeatures::SetCanChangeJobTitle( PRBool aCanSetJobTitle )
00351 {
00352   SetBoolValue("can_change_jobtitle", aCanSetJobTitle);
00353 }
00354 
00355 void nsPrinterFeatures::SetSupportsJobTitleChange( PRBool aSupportsJobTitle )
00356 {
00357   SetBoolValue("supports_jobtitle_change", aSupportsJobTitle);
00358 }
00359 
00360 void nsPrinterFeatures::SetCanChangeNumCopies( PRBool aCanSetNumCopies )
00361 {
00362   SetBoolValue("can_change_num_copies", aCanSetNumCopies);
00363 }
00364 
00365 void nsPrinterFeatures::SetMultipleConcurrentDeviceContextsSupported( PRBool aCanUseMultipleInstances )
00366 {
00367   SetBoolValue("can_use_multiple_devicecontexts_concurrently", aCanUseMultipleInstances);
00368 }
00369 
00370 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
00371 
00372 //---------------
00373 // static members
00374 GlobalPrinters GlobalPrinters::mGlobalPrinters;
00375 nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull;
00376 //---------------
00377 
00378 nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()
00379 {
00380   DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n"));
00381 }
00382 
00383 nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()
00384 {
00385   DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()\n"));
00386 }
00387 
00388 /* Use both PostScript and Xprint module */
00389 #if defined(USE_XPRINT) && defined(USE_POSTSCRIPT)
00390 NS_IMPL_ISUPPORTS3(nsDeviceContextSpecGTK,
00391                    nsIDeviceContextSpec,
00392                    nsIDeviceContextSpecPS,
00393                    nsIDeviceContextSpecXp)
00394 /* Use only PostScript module */
00395 #elif !defined(USE_XPRINT) && defined(USE_POSTSCRIPT)
00396 NS_IMPL_ISUPPORTS2(nsDeviceContextSpecGTK,
00397                    nsIDeviceContextSpec,
00398                    nsIDeviceContextSpecPS)
00399 /* Use only Xprint module module */
00400 #elif defined(USE_XPRINT) && !defined(USE_POSTSCRIPT)
00401 NS_IMPL_ISUPPORTS2(nsDeviceContextSpecGTK,
00402                    nsIDeviceContextSpec,
00403                    nsIDeviceContextSpecXp)
00404 /* Both Xprint and PostScript module are missing */
00405 #elif !defined(USE_XPRINT) && !defined(USE_POSTSCRIPT)
00406 NS_IMPL_ISUPPORTS1(nsDeviceContextSpecGTK,
00407                    nsIDeviceContextSpec)
00408 #else
00409 #error "This should not happen"
00410 #endif
00411 
00428 NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings *aPS,
00429         PRBool aIsPrintPreview)
00430 {
00431   DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::Init(aPS=%p)\n", aPS));
00432   nsresult rv = NS_ERROR_FAILURE;
00433 
00434   mPrintSettings = aPS;
00435 
00436   // if there is a current selection then enable the "Selection" radio button
00437   rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
00438   if (NS_FAILED(rv)) {
00439     return rv;
00440   }
00441 
00442   GlobalPrinters::GetInstance()->FreeGlobalPrinters();
00443 
00444   if (aPS) {
00445     PRBool     reversed       = PR_FALSE;
00446     PRBool     color          = PR_FALSE;
00447     PRBool     tofile         = PR_FALSE;
00448     PRInt16    printRange     = nsIPrintSettings::kRangeAllPages;
00449     PRInt32    orientation    = NS_PORTRAIT;
00450     PRInt32    fromPage       = 1;
00451     PRInt32    toPage         = 1;
00452     PRUnichar *command        = nsnull;
00453     PRInt32    copies         = 1;
00454     PRUnichar *printer        = nsnull;
00455     PRUnichar *papername      = nsnull;
00456     PRUnichar *plexname       = nsnull;
00457     PRUnichar *resolutionname = nsnull;
00458     PRUnichar *colorspace     = nsnull;
00459     PRBool     downloadfonts  = PR_TRUE;
00460     PRUnichar *printfile      = nsnull;
00461     double     dleft          = 0.5;
00462     double     dright         = 0.5;
00463     double     dtop           = 0.5;
00464     double     dbottom        = 0.5; 
00465 
00466     aPS->GetPrinterName(&printer);
00467     aPS->GetPrintReversed(&reversed);
00468     aPS->GetPrintInColor(&color);
00469     aPS->GetPaperName(&papername);
00470     aPS->GetResolutionName(&resolutionname);
00471     aPS->GetColorspace(&colorspace);
00472     aPS->GetDownloadFonts(&downloadfonts);
00473     aPS->GetPlexName(&plexname);
00474     aPS->GetOrientation(&orientation);
00475     aPS->GetPrintCommand(&command);
00476     aPS->GetPrintRange(&printRange);
00477     aPS->GetToFileName(&printfile);
00478     aPS->GetPrintToFile(&tofile);
00479     aPS->GetStartPageRange(&fromPage);
00480     aPS->GetEndPageRange(&toPage);
00481     aPS->GetNumCopies(&copies);
00482     aPS->GetMarginTop(&dtop);
00483     aPS->GetMarginLeft(&dleft);
00484     aPS->GetMarginBottom(&dbottom);
00485     aPS->GetMarginRight(&dright);
00486 
00487     if (printfile)
00488       PL_strncpyz(mPath,      NS_ConvertUCS2toUTF8(printfile).get(), sizeof(mPath));
00489     if (command)
00490       PL_strncpyz(mCommand,   NS_ConvertUCS2toUTF8(command).get(),   sizeof(mCommand));  
00491     if (printer) 
00492       PL_strncpyz(mPrinter,   NS_ConvertUCS2toUTF8(printer).get(),   sizeof(mPrinter));        
00493     if (papername) 
00494       PL_strncpyz(mPaperName, NS_ConvertUCS2toUTF8(papername).get(), sizeof(mPaperName));  
00495     if (plexname) 
00496       PL_strncpyz(mPlexName,  NS_ConvertUCS2toUTF8(plexname).get(),  sizeof(mPlexName));  
00497     if (resolutionname) 
00498       PL_strncpyz(mResolutionName, NS_ConvertUCS2toUTF8(resolutionname).get(), sizeof(mResolutionName));  
00499     if (colorspace) 
00500       PL_strncpyz(mColorspace, NS_ConvertUCS2toUTF8(colorspace).get(), sizeof(mColorspace));  
00501 
00502     DO_PR_DEBUG_LOG(("margins:   %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright));
00503     DO_PR_DEBUG_LOG(("printRange %d\n",   printRange));
00504     DO_PR_DEBUG_LOG(("fromPage   %d\n",   fromPage));
00505     DO_PR_DEBUG_LOG(("toPage     %d\n",   toPage));
00506     DO_PR_DEBUG_LOG(("tofile     %d\n",   tofile));
00507     DO_PR_DEBUG_LOG(("printfile  '%s'\n", printfile? NS_ConvertUCS2toUTF8(printfile).get():"<NULL>"));
00508     DO_PR_DEBUG_LOG(("command    '%s'\n", command? NS_ConvertUCS2toUTF8(command).get():"<NULL>"));
00509     DO_PR_DEBUG_LOG(("printer    '%s'\n", printer? NS_ConvertUCS2toUTF8(printer).get():"<NULL>"));
00510     DO_PR_DEBUG_LOG(("papername  '%s'\n", papername? NS_ConvertUCS2toUTF8(papername).get():"<NULL>"));
00511     DO_PR_DEBUG_LOG(("plexname   '%s'\n", plexname? NS_ConvertUCS2toUTF8(plexname).get():"<NULL>"));
00512     DO_PR_DEBUG_LOG(("resolution '%s'\n", resolutionname? NS_ConvertUCS2toUTF8(resolutionname).get():"<NULL>"));
00513     DO_PR_DEBUG_LOG(("colorspace '%s'\n", colorspace? NS_ConvertUCS2toUTF8(colorspace).get():"<NULL>"));
00514 
00515     mTop         = dtop;
00516     mBottom      = dbottom;
00517     mLeft        = dleft;
00518     mRight       = dright;
00519     mFpf         = !reversed;
00520     mDownloadFonts = downloadfonts;
00521     mGrayscale   = !color;
00522     mOrientation = orientation;
00523     mToPrinter   = !tofile;
00524     mCopies      = copies;
00525     mIsPPreview  = aIsPrintPreview;
00526     mCancel      = PR_FALSE;
00527   }
00528 
00529   return rv;
00530 }
00531 
00532 NS_IMETHODIMP nsDeviceContextSpecGTK::GetToPrinter(PRBool &aToPrinter)
00533 {
00534   aToPrinter = mToPrinter;
00535   return NS_OK;
00536 }
00537 
00538 NS_IMETHODIMP nsDeviceContextSpecGTK::GetIsPrintPreview(PRBool &aIsPPreview)
00539 {
00540   aIsPPreview = mIsPPreview;
00541   return NS_OK;
00542 }
00543 
00544 NS_IMETHODIMP nsDeviceContextSpecGTK::GetPrinterName ( const char **aPrinter )
00545 {
00546    *aPrinter = mPrinter;
00547    return NS_OK;
00548 }
00549 
00550 NS_IMETHODIMP nsDeviceContextSpecGTK::GetCopies ( int &aCopies )
00551 {
00552    aCopies = mCopies;
00553    return NS_OK;
00554 }
00555 
00556 NS_IMETHODIMP nsDeviceContextSpecGTK::GetFirstPageFirst(PRBool &aFpf)      
00557 {
00558   aFpf = mFpf;
00559   return NS_OK;
00560 }
00561 
00562 NS_IMETHODIMP nsDeviceContextSpecGTK::GetGrayscale(PRBool &aGrayscale)      
00563 {
00564   aGrayscale = mGrayscale;
00565   return NS_OK;
00566 }
00567 
00568 NS_IMETHODIMP nsDeviceContextSpecGTK::GetLandscape(PRBool &aLandscape)
00569 {
00570   aLandscape = (mOrientation == NS_LANDSCAPE);
00571   return NS_OK;
00572 }
00573 
00574 NS_IMETHODIMP nsDeviceContextSpecGTK::GetTopMargin(float &aValue)      
00575 {
00576   aValue = mTop;
00577   return NS_OK;
00578 }
00579 
00580 NS_IMETHODIMP nsDeviceContextSpecGTK::GetBottomMargin(float &aValue)      
00581 {
00582   aValue = mBottom;
00583   return NS_OK;
00584 }
00585 
00586 NS_IMETHODIMP nsDeviceContextSpecGTK::GetRightMargin(float &aValue)      
00587 {
00588   aValue = mRight;
00589   return NS_OK;
00590 }
00591 
00592 NS_IMETHODIMP nsDeviceContextSpecGTK::GetLeftMargin(float &aValue)      
00593 {
00594   aValue = mLeft;
00595   return NS_OK;
00596 }
00597 
00598 NS_IMETHODIMP nsDeviceContextSpecGTK::GetCommand(const char **aCommand)      
00599 {
00600   *aCommand = mCommand;
00601   return NS_OK;
00602 }
00603 
00604 NS_IMETHODIMP nsDeviceContextSpecGTK::GetPath(const char **aPath)      
00605 {
00606   *aPath = mPath;
00607   return NS_OK;
00608 }
00609 
00610 NS_IMETHODIMP nsDeviceContextSpecGTK::GetUserCancelled(PRBool &aCancel)     
00611 {
00612   aCancel = mCancel;
00613   return NS_OK;
00614 }
00615 
00616 NS_IMETHODIMP nsDeviceContextSpecGTK::GetPaperName( const char **aPaperName )
00617 {
00618   *aPaperName = mPaperName;
00619   return NS_OK;
00620 }
00621 
00622 NS_IMETHODIMP nsDeviceContextSpecGTK::GetPlexName( const char **aPlexName )
00623 {
00624   *aPlexName = mPlexName;
00625   return NS_OK;
00626 }
00627 
00628 NS_IMETHODIMP nsDeviceContextSpecGTK::GetResolutionName( const char **aResolutionName )
00629 {
00630   *aResolutionName = mResolutionName;
00631   return NS_OK;
00632 }
00633 
00634 NS_IMETHODIMP nsDeviceContextSpecGTK::GetColorspace( const char **aColorspace )
00635 {
00636   *aColorspace = mColorspace;
00637   return NS_OK;
00638 }
00639 
00640 NS_IMETHODIMP nsDeviceContextSpecGTK::GetDownloadFonts(PRBool &aDownloadFonts)      
00641 {
00642   aDownloadFonts = mDownloadFonts;
00643   return NS_OK;
00644 }
00645 
00646 NS_IMETHODIMP nsDeviceContextSpecGTK::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight)
00647 {
00648   return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight);
00649 }
00650 
00651 NS_IMETHODIMP nsDeviceContextSpecGTK::GetPrintMethod(PrintMethod &aMethod)
00652 {
00653   return GetPrintMethod(mPrinter, aMethod);
00654 }
00655 
00656 /* static !! */
00657 nsresult nsDeviceContextSpecGTK::GetPrintMethod(const char *aPrinter, PrintMethod &aMethod)
00658 {
00659 #if defined(USE_POSTSCRIPT) && defined(USE_XPRINT)
00660   if (nsPSPrinterList::kTypeUnknown ==
00661       nsPSPrinterList::GetPrinterType(nsDependentCString(aPrinter)))
00662     aMethod = pmXprint;
00663   else
00664     aMethod = pmPostScript;
00665   return NS_OK;
00666 #elif defined(USE_XPRINT)
00667   aMethod = pmXprint;
00668   return NS_OK;
00669 #elif defined(USE_POSTSCRIPT)
00670   aMethod = pmPostScript;
00671   return NS_OK;
00672 #else
00673   return NS_ERROR_UNEXPECTED;
00674 #endif
00675 }
00676 
00677 NS_IMETHODIMP nsDeviceContextSpecGTK::ClosePrintManager()
00678 {
00679   return NS_OK;
00680 }
00681 
00682 /* Get prefs for printer
00683  * Search order:
00684  * - Get prefs per printer name and module name
00685  * - Get prefs per printer name
00686  * - Get prefs per module name
00687  * - Get prefs
00688  */
00689 static
00690 nsresult CopyPrinterCharPref(nsIPref *pref, const char *modulename, const char *printername, const char *prefname, char **return_buf)
00691 {
00692   DO_PR_DEBUG_LOG(("CopyPrinterCharPref('%s', '%s', '%s')\n", modulename, printername, prefname));
00693 
00694   NS_ENSURE_ARG_POINTER(return_buf);
00695 
00696   nsXPIDLCString name;
00697   nsresult rv = NS_ERROR_FAILURE;
00698  
00699   if (printername && modulename) {
00700     /* Get prefs per printer name and module name */
00701     name = nsPrintfCString(512, "print.%s.printer_%s.%s", modulename, printername, prefname);
00702     DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
00703     rv = pref->CopyCharPref(name, return_buf);
00704   }
00705   
00706   if (NS_FAILED(rv)) { 
00707     if (printername) {
00708       /* Get prefs per printer name */
00709       name = nsPrintfCString(512, "print.printer_%s.%s", printername, prefname);
00710       DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
00711       rv = pref->CopyCharPref(name, return_buf);
00712     }
00713 
00714     if (NS_FAILED(rv)) {
00715       if (modulename) {
00716         /* Get prefs per module name */
00717         name = nsPrintfCString(512, "print.%s.%s", modulename, prefname);
00718         DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
00719         rv = pref->CopyCharPref(name, return_buf);
00720       }
00721       
00722       if (NS_FAILED(rv)) {
00723         /* Get prefs */
00724         name = nsPrintfCString(512, "print.%s", prefname);
00725         DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
00726         rv = pref->CopyCharPref(name, return_buf);
00727       }
00728     }
00729   }
00730 
00731 #ifdef PR_LOG  
00732   if (NS_SUCCEEDED(rv)) {
00733     DO_PR_DEBUG_LOG(("CopyPrinterCharPref returning '%s'.\n", *return_buf));
00734   }
00735   else
00736   {
00737     DO_PR_DEBUG_LOG(("CopyPrinterCharPref failure.\n"));
00738   }
00739 #endif /* PR_LOG */
00740 
00741   return rv;
00742 }
00743 
00744 //  Printer Enumerator
00745 nsPrinterEnumeratorGTK::nsPrinterEnumeratorGTK()
00746 {
00747 }
00748 
00749 NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorGTK, nsIPrinterEnumerator)
00750 
00751 NS_IMETHODIMP nsPrinterEnumeratorGTK::EnumeratePrinters(PRUint32* aCount, PRUnichar*** aResult)
00752 {
00753   NS_ENSURE_ARG(aCount);
00754   NS_ENSURE_ARG_POINTER(aResult);
00755 
00756   if (aCount) 
00757     *aCount = 0;
00758   else 
00759     return NS_ERROR_NULL_POINTER;
00760   
00761   if (aResult) 
00762     *aResult = nsnull;
00763   else 
00764     return NS_ERROR_NULL_POINTER;
00765   
00766   nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
00767   if (NS_FAILED(rv)) {
00768     return rv;
00769   }
00770 
00771   PRInt32 numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters();
00772 
00773   PRUnichar** array = (PRUnichar**) nsMemory::Alloc(numPrinters * sizeof(PRUnichar*));
00774   if (!array && numPrinters > 0) {
00775     GlobalPrinters::GetInstance()->FreeGlobalPrinters();
00776     return NS_ERROR_OUT_OF_MEMORY;
00777   }
00778   
00779   int count = 0;
00780   while( count < numPrinters )
00781   {
00782     PRUnichar *str = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(count));
00783 
00784     if (!str) {
00785       for (int i = count - 1; i >= 0; i--) 
00786         nsMemory::Free(array[i]);
00787       
00788       nsMemory::Free(array);
00789 
00790       GlobalPrinters::GetInstance()->FreeGlobalPrinters();
00791       return NS_ERROR_OUT_OF_MEMORY;
00792     }
00793     array[count++] = str;
00794     
00795   }
00796   *aCount = count;
00797   *aResult = array;
00798   GlobalPrinters::GetInstance()->FreeGlobalPrinters();
00799 
00800   return NS_OK;
00801 }
00802 
00803 /* readonly attribute wstring defaultPrinterName; */
00804 NS_IMETHODIMP nsPrinterEnumeratorGTK::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName)
00805 {
00806   DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::GetDefaultPrinterName()\n"));
00807   NS_ENSURE_ARG_POINTER(aDefaultPrinterName);
00808 
00809   GlobalPrinters::GetInstance()->GetDefaultPrinterName(aDefaultPrinterName);
00810 
00811   DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", NS_ConvertUCS2toUTF8(*aDefaultPrinterName).get()));
00812   return NS_OK;
00813 }
00814 
00815 /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */
00816 NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings)
00817 {
00818   DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter()"));
00819   nsresult rv;
00820 
00821   NS_ENSURE_ARG_POINTER(aPrinterName);
00822   NS_ENSURE_ARG_POINTER(aPrintSettings);
00823   
00824   NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE);
00825   NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE);
00826 
00827   nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
00828   if (NS_FAILED(rv))
00829     return rv;
00830 
00831   nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */ 
00832                  printerName;     /* "Stripped" name of printer */
00833   fullPrinterName.Assign(NS_ConvertUCS2toUTF8(aPrinterName));
00834   printerName.Assign(NS_ConvertUCS2toUTF8(aPrinterName));
00835   DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get()));
00836   
00837   PrintMethod type = pmInvalid;
00838   rv = nsDeviceContextSpecGTK::GetPrintMethod(printerName, type);
00839   if (NS_FAILED(rv))
00840     return rv;
00841 
00842 #ifdef USE_POSTSCRIPT
00843   /* "Demangle" postscript printer name */
00844   if (type == pmPostScript) {
00845     /* Strip the printing method name from the printer,
00846      * e.g. turn "PostScript/foobar" to "foobar" */
00847     PRInt32 slash = printerName.FindChar('/');
00848     if (kNotFound != slash)
00849       printerName.Cut(0, slash + 1);
00850   }
00851 #endif /* USE_POSTSCRIPT */
00852 
00853 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00854   /* Defaults to FALSE */
00855   pPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.has_special_printerfeatures", fullPrinterName.get()).get(), PR_FALSE);
00856 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
00857 
00858   
00859   /* Set filename */
00860   nsXPIDLCString filename;
00861   if (NS_FAILED(CopyPrinterCharPref(pPrefs, nsnull, printerName, "filename", getter_Copies(filename)))) {
00862     const char *path;
00863   
00864     if (!(path = PR_GetEnv("PWD")))
00865       path = PR_GetEnv("HOME");
00866   
00867     if (path)
00868       filename = nsPrintfCString(PATH_MAX, "%s/mozilla.ps", path);
00869     else
00870       filename.Assign("mozilla.ps");  
00871   }  
00872   DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get()));
00873   aPrintSettings->SetToFileName(NS_ConvertUTF8toUCS2(filename).get());
00874 
00875   aPrintSettings->SetIsInitializedFromPrinter(PR_TRUE);
00876 
00877 #ifdef USE_XPRINT
00878   if (type == pmXprint) {
00879     DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for Xprint printer\n"));
00880 
00881     /* Setup the capabilties list of Mozilla's Xprint print module */
00882 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00883     nsPrinterFeatures printerFeatures(fullPrinterName);
00884 
00885     printerFeatures.SetSupportsPaperSizeChange(PR_TRUE);
00886     printerFeatures.SetSupportsOrientationChange(PR_TRUE);
00887     printerFeatures.SetSupportsPlexChange(PR_TRUE);
00888     printerFeatures.SetSupportsResolutionNameChange(PR_TRUE);
00889     printerFeatures.SetSupportsColorspaceChange(PR_TRUE);
00890     printerFeatures.SetSupportsJobTitleChange(PR_TRUE);
00891     printerFeatures.SetSupportsSpoolerCommandChange(PR_FALSE); /* won't work by design and very good reasons! */
00892 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ 
00893     
00894     /* Setup the capabilties list of this specific printer */
00895 
00896     Display   *pdpy;
00897     XPContext  pcontext;
00898     if (XpuGetPrinter(printerName, &pdpy, &pcontext) != 1)
00899       return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND;
00900       
00901     XpuSupportedFlags supported_doc_attrs = XpuGetSupportedDocAttributes(pdpy, pcontext);
00902 
00903     /* Setup orientation stuff */
00904     XpuOrientationList  olist;
00905     int                 ocount;
00906     XpuOrientationRec  *default_orientation;
00907 
00908     /* Setup plex stuff */
00909     XpuPlexList         plexlist;
00910     int                 plexcount;
00911     XpuPlexRec         *default_plex;
00912 
00913 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00914     PRBool canSetOrientation = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_CONTENT_ORIENTATION);
00915     printerFeatures.SetCanChangeOrientation(canSetOrientation);
00916 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
00917       
00918     /* Get list of supported orientations */
00919     olist = XpuGetOrientationList(pdpy, pcontext, &ocount);
00920     if (olist) {
00921       default_orientation = &olist[0]; /* First entry is the default one */
00922     
00923       if (!PL_strcasecmp(default_orientation->orientation, "portrait")) {
00924         DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n"));
00925         aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
00926       }
00927       else if (!PL_strcasecmp(default_orientation->orientation, "landscape")) {
00928         DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n"));
00929         aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);
00930       }  
00931       else {
00932         DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", default_orientation->orientation));
00933       }
00934 
00935 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00936       int i;
00937       for( i = 0 ; i < ocount ; i++ )
00938       {
00939         XpuOrientationRec *curr = &olist[i];
00940         printerFeatures.SetOrientationRecord(i, curr->orientation);
00941       }
00942       printerFeatures.SetNumOrientationRecords(ocount);
00943 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
00944    
00945       XpuFreeOrientationList(olist);
00946     }  
00947 
00948 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00949     PRBool canSetPlexMode = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_PLEX);
00950     printerFeatures.SetCanChangePlex(canSetPlexMode);
00951 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
00952 
00953     /* Get list of supported plex modes */
00954     plexlist = XpuGetPlexList(pdpy, pcontext, &plexcount);
00955     if (plexlist) {
00956       default_plex = &plexlist[0]; /* First entry is the default one */
00957     
00958       DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", default_plex->plex));
00959       aPrintSettings->SetPlexName(NS_ConvertUTF8toUCS2(default_plex->plex).get());
00960 
00961 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00962       int i;
00963       for( i = 0 ; i < plexcount ; i++ )
00964       {
00965         XpuPlexRec *curr = &plexlist[i];
00966         printerFeatures.SetPlexRecord(i, curr->plex);
00967       }
00968       printerFeatures.SetNumPlexRecords(plexcount);
00969 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
00970    
00971       XpuFreePlexList(plexlist);
00972     }  
00973 
00974     /* Setup Number of Copies */
00975 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00976     PRBool canSetNumCopies = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_COPY_COUNT);
00977     printerFeatures.SetCanChangeNumCopies(canSetNumCopies);
00978 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
00979     long numCopies;
00980     if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "copy-count", &numCopies) != 1 )
00981     {
00982       /* Fallback on failure */
00983       numCopies = 1;
00984     }
00985     aPrintSettings->SetNumCopies(numCopies);
00986 
00987     /* Setup paper size stuff */
00988     XpuMediumSourceSizeList mlist;
00989     int                     mcount;
00990     XpuMediumSourceSizeRec *default_medium;
00991     
00992 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
00993     PRBool canSetPaperSize = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM);
00994     printerFeatures.SetCanChangePaperSize(canSetPaperSize);
00995 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
00996     
00997     mlist = XpuGetMediumSourceSizeList(pdpy, pcontext, &mcount);
00998     if (mlist) {
00999       nsXPIDLCString papername;
01000 
01001       default_medium = &mlist[0]; /* First entry is the default one */
01002       double total_width  = default_medium->ma1 + default_medium->ma2,
01003              total_height = default_medium->ma3 + default_medium->ma4;
01004 
01005       /* Either "paper" or "tray/paper" */
01006       papername.Truncate();
01007       if (default_medium->tray_name) {
01008         papername.Append(default_medium->tray_name);
01009         papername.Append("/");
01010       }
01011       papername.Append(default_medium->medium_name);
01012  
01013       DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g/%g mm)\n", papername.get(), total_width, total_height));
01014       aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined);
01015       aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
01016       aPrintSettings->SetPaperWidth(total_width);
01017       aPrintSettings->SetPaperHeight(total_height);
01018       aPrintSettings->SetPaperName(NS_ConvertUTF8toUCS2(papername).get());     
01019 
01020 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01021       int i;
01022       for( i = 0 ; i < mcount ; i++ )
01023       {
01024         XpuMediumSourceSizeRec *curr = &mlist[i];
01025         double total_width  = curr->ma1 + curr->ma2,
01026                total_height = curr->ma3 + curr->ma4;
01027 
01028         papername.Truncate();
01029         if (curr->tray_name) {
01030           papername.Append(curr->tray_name);
01031           papername.Append("/");
01032         }
01033         papername.Append(curr->medium_name);
01034 
01035         printerFeatures.SetPaperRecord(i, papername, PRInt32(total_width), PRInt32(total_height), PR_FALSE);
01036       }
01037       printerFeatures.SetNumPaperSizeRecords(mcount);
01038 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01039 
01040       XpuFreeMediumSourceSizeList(mlist);
01041     }
01042 
01043     /* Setup resolution/quality stuff */
01044     XpuResolutionList rlist;
01045     int               rcount;
01046     XpuResolutionRec *default_resolution;
01047     
01048 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01049     PRBool canSetResolutionName = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_DEFAULT_PRINTER_RESOLUTION);
01050     printerFeatures.SetCanChangeResolutionName(canSetResolutionName);
01051 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01052     
01053     rlist = XpuGetResolutionList(pdpy, pcontext, &rcount);
01054     if (rlist) {
01055       default_resolution = &rlist[0]; /* First entry is the default one */
01056     
01057       DO_PR_DEBUG_LOG(("setting default resolution to '%s'/%ldx%ld\n",
01058                        default_resolution->name,
01059                        default_resolution->x_dpi,
01060                        default_resolution->y_dpi));
01061       aPrintSettings->SetResolutionName(NS_ConvertUTF8toUCS2(default_resolution->name).get());
01062 
01063 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01064       int i;
01065       for( i = 0 ; i < rcount ; i++ )
01066       {
01067         XpuResolutionRec *curr = &rlist[i];
01068         printerFeatures.SetResolutionNameRecord(i, curr->name);
01069       }
01070       printerFeatures.SetNumResolutionNameRecords(rcount);
01071 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01072    
01073       XpuFreeResolutionList(rlist);
01074     }
01075 
01076     /* We still support the old print-in-color boolean */
01077     printerFeatures.SetSupportsPrintInColorChange(PR_TRUE);
01078     printerFeatures.SetCanChangePrintInColor(PR_TRUE);
01079 
01080     /* Setup colorspace stuff */
01081     XpuColorspaceList cslist;
01082     int               cscount;
01083     XpuColorspaceRec *default_colorspace;
01084     
01085 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01086     printerFeatures.SetCanChangeColorspace(PR_TRUE);
01087 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01088     
01089     cslist = XpuGetColorspaceList(pdpy, pcontext, &cscount);
01090     if (cslist) {
01091       default_colorspace = &cslist[0]; /* First entry is the default one */
01092     
01093       DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", default_colorspace->name));
01094       aPrintSettings->SetColorspace(NS_ConvertUTF8toUCS2(default_colorspace->name).get());
01095 
01096 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01097       int i;
01098       for( i = 0 ; i < cscount ; i++ )
01099       {
01100         XpuColorspaceRec *curr = &cslist[i];
01101         printerFeatures.SetColorspaceRecord(i, curr->name);
01102       }
01103       printerFeatures.SetNumColorspaceRecords(cscount);
01104 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01105    
01106       XpuFreeColorspaceList(cslist);
01107     }
01108 
01109     /* Fonts */
01110     PRBool canSetListFontsMode = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_LISTFONTS_MODES);
01111     printerFeatures.SetCanChangeDownloadFonts(canSetListFontsMode);
01112     printerFeatures.SetSupportsDownloadFontsChange(PR_TRUE);
01113 
01114     Bool downloadFonts = XpuGetEnableFontDownload(pdpy, pcontext);
01115     aPrintSettings->SetDownloadFonts(downloadFonts);
01116 
01117 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01118     /* Xprint does not allow the client to set a spooler command. 
01119      * Job spooling is the job of the server side (=Xprt) */
01120     printerFeatures.SetCanChangeSpoolerCommand(PR_FALSE);
01121 
01122     /* Check whether printer/driver allow changes of the job name */
01123     PRBool canSetJobName = MAKE_PR_BOOL(XpuGetSupportedJobAttributes(pdpy, pcontext) & XPUATTRIBUTESUPPORTED_JOB_NAME);
01124     printerFeatures.SetCanChangeJobTitle(canSetJobName);
01125 
01126     /* Mozilla's Xprint support allows multiple nsIDeviceContext instances
01127      * be used in parallel */
01128     printerFeatures.SetMultipleConcurrentDeviceContextsSupported(PR_TRUE);
01129 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01130 
01131     XpuClosePrinterDisplay(pdpy, pcontext);
01132     
01133     return NS_OK;    
01134   }
01135   else
01136 #endif /* USE_XPRINT */
01137 
01138 #ifdef USE_POSTSCRIPT
01139   if (type == pmPostScript) {
01140     DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n"));
01141 
01142 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01143     nsPrinterFeatures printerFeatures(fullPrinterName);
01144 
01145     printerFeatures.SetSupportsPaperSizeChange(PR_TRUE);
01146     printerFeatures.SetSupportsOrientationChange(PR_TRUE);
01147     printerFeatures.SetSupportsPlexChange(PR_FALSE);
01148     printerFeatures.SetSupportsResolutionNameChange(PR_FALSE);
01149     printerFeatures.SetSupportsColorspaceChange(PR_FALSE);
01150 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ 
01151       
01152 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01153     printerFeatures.SetCanChangeOrientation(PR_TRUE);
01154 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01155 
01156     nsXPIDLCString orientation;
01157     if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "orientation", getter_Copies(orientation)))) {
01158       if (!PL_strcasecmp(orientation, "portrait")) {
01159         DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n"));
01160         aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
01161       }
01162       else if (!PL_strcasecmp(orientation, "landscape")) {
01163         DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n"));
01164         aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);  
01165       }
01166       else {
01167         DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get()));
01168       }
01169     }
01170 
01171 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01172     printerFeatures.SetOrientationRecord(0, "portrait");
01173     printerFeatures.SetOrientationRecord(1, "landscape");
01174     printerFeatures.SetNumOrientationRecords(2);
01175 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01176 
01177     /* PostScript module does not support changing the plex mode... */
01178 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01179     printerFeatures.SetCanChangePlex(PR_FALSE);
01180 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01181     DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", "default"));
01182     aPrintSettings->SetPlexName(NS_LITERAL_STRING("default").get());
01183 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01184     printerFeatures.SetPlexRecord(0, "default");
01185     printerFeatures.SetNumPlexRecords(1);
01186 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01187 
01188     /* PostScript module does not support changing the resolution mode... */
01189 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01190     printerFeatures.SetCanChangeResolutionName(PR_FALSE);
01191 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01192     DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default"));
01193     aPrintSettings->SetResolutionName(NS_LITERAL_STRING("default").get());
01194 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01195     printerFeatures.SetResolutionNameRecord(0, "default");
01196     printerFeatures.SetNumResolutionNameRecords(1);
01197 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01198 
01199     /* PostScript module does not support changing the colorspace... */
01200 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01201     printerFeatures.SetCanChangeColorspace(PR_FALSE);
01202 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01203     DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default"));
01204     aPrintSettings->SetColorspace(NS_LITERAL_STRING("default").get());
01205 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01206     printerFeatures.SetColorspaceRecord(0, "default");
01207     printerFeatures.SetNumColorspaceRecords(1);
01208 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */   
01209 
01210 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01211     printerFeatures.SetCanChangePaperSize(PR_TRUE);
01212 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01213     nsXPIDLCString papername;
01214     if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) {
01215       nsPaperSizePS paper;
01216 
01217       if (paper.Find(papername)) {
01218         DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
01219               paper.Name(), paper.Width_mm(), paper.Height_mm()));
01220         aPrintSettings->SetPaperSizeUnit(paper.IsMetric() ?
01221             (int)nsIPrintSettings::kPaperSizeMillimeters :
01222             (int)nsIPrintSettings::kPaperSizeInches);
01223         aPrintSettings->SetPaperWidth(paper.Width_mm());
01224         aPrintSettings->SetPaperHeight(paper.Height_mm());
01225         aPrintSettings->SetPaperName(NS_ConvertASCIItoUCS2(paper.Name()).get());
01226       }
01227       else {
01228         DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
01229       }
01230 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01231       paper.First();
01232       int count = 0;
01233       while (!paper.AtEnd())
01234       {
01235         printerFeatures.SetPaperRecord(count++, paper.Name(),
01236             (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric());
01237         paper.Next();
01238       }
01239       printerFeatures.SetNumPaperSizeRecords(count);
01240 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01241     }
01242 
01243     PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
01244         nsPSPrinterList::GetPrinterType(fullPrinterName));
01245 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01246     printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd);
01247     printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd);
01248 
01249     /* Postscript module does not pass the job title to lpr */
01250     printerFeatures.SetSupportsJobTitleChange(PR_FALSE);
01251     printerFeatures.SetCanChangeJobTitle(PR_FALSE);
01252     /* Postscript module has no control over builtin fonts yet */
01253     printerFeatures.SetSupportsDownloadFontsChange(PR_FALSE);
01254     printerFeatures.SetCanChangeDownloadFonts(PR_FALSE);
01255     /* Postscript module does not support multiple colorspaces
01256      * so it has to use the old way */
01257     printerFeatures.SetSupportsPrintInColorChange(PR_TRUE);
01258     printerFeatures.SetCanChangePrintInColor(PR_TRUE);
01259 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01260 
01261     if (hasSpoolerCmd) {
01262       nsXPIDLCString command;
01263       if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript",
01264             printerName, "print_command", getter_Copies(command)))) {
01265         DO_PR_DEBUG_LOG(("setting default print command to '%s'\n",
01266             command.get()));
01267         aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUCS2(command).get());
01268       }
01269     }
01270     
01271 #ifdef SET_PRINTER_FEATURES_VIA_PREFS
01272     printerFeatures.SetCanChangeNumCopies(PR_TRUE);   
01273 #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
01274 
01275     return NS_OK;    
01276   }
01277 #endif /* USE_POSTSCRIPT */
01278 
01279   return NS_ERROR_UNEXPECTED;
01280 }
01281 
01282 NS_IMETHODIMP nsPrinterEnumeratorGTK::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings *aPrintSettings)
01283 {
01284   return NS_OK;
01285 }
01286 
01287 
01288 //----------------------------------------------------------------------
01289 //String array enumeration callback to append a printer to the global
01290 //printer list.
01291 static PRBool
01292 GlobalPrinterEnumFunc(nsCString& aName, void *aData)
01293 {
01294   nsStringArray *a = (nsStringArray *)aData;
01295   a->AppendString(NS_ConvertUTF8toUTF16(aName));
01296   return PR_TRUE;
01297 }
01298 
01299 //----------------------------------------------------------------------
01300 nsresult GlobalPrinters::InitializeGlobalPrinters ()
01301 {
01302   if (PrintersAreAllocated()) {
01303     return NS_OK;
01304   }
01305 
01306   mGlobalPrinterList = new nsStringArray();
01307   if (!mGlobalPrinterList) 
01308     return NS_ERROR_OUT_OF_MEMORY;
01309 
01310   nsresult rv;
01311   nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
01312   if (NS_FAILED(rv))
01313     return rv;
01314       
01315 #ifdef USE_XPRINT   
01316   int printerCount;
01317   XPPrinterList plist = XpuGetPrinterList(nsnull, &printerCount);
01318   
01319   if (plist)
01320   {  
01321     int i;
01322     for( i = 0 ; i < printerCount ; i++ )
01323     {
01324       /* Add name to our list of printers... */
01325       mGlobalPrinterList->AppendString(nsString(NS_ConvertUTF8toUCS2(plist[i].name)));
01326 
01327       /* ... and store the description text for this printer */
01328       pPrefs->SetCharPref(nsPrintfCString(256, "print.printer_%s.printer_description", plist[i].name).get(), plist[i].desc);      
01329     }
01330     
01331     XpuFreePrinterList(plist);
01332   }
01333 #endif /* USE_XPRINT */
01334 
01335 #ifdef USE_POSTSCRIPT
01336   nsPSPrinterList psMgr;
01337   if (NS_SUCCEEDED(psMgr.Init()) && psMgr.Enabled()) {
01338     /* Get the list of PostScript-module printers */
01339     nsCStringArray printerList;
01340     psMgr.GetPrinterList(printerList);
01341     printerList.EnumerateForwards(GlobalPrinterEnumFunc, mGlobalPrinterList);
01342   }
01343 #endif /* USE_POSTSCRIPT */  
01344       
01345   /* If there are no printers available after all checks, return an error */
01346   if (!mGlobalPrinterList->Count())
01347   {
01348     /* Make sure we do not cache an empty printer list */
01349     FreeGlobalPrinters();
01350 
01351 #ifdef USE_XPRINT
01352     /* Check if there are actually any Xprint servers available */
01353     if (!XpuXprintServersAvailable()) {
01354       return NS_ERROR_GFX_PRINTER_XPRINT_NO_XPRINT_SERVERS_FOUND;
01355     }
01356 #endif /* USE_XPRINT */
01357 
01358     return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
01359   }
01360 
01361   return NS_OK;
01362 }
01363 
01364 //----------------------------------------------------------------------
01365 void GlobalPrinters::FreeGlobalPrinters()
01366 {
01367   if (mGlobalPrinterList) {
01368     delete mGlobalPrinterList;
01369     mGlobalPrinterList = nsnull;
01370   }  
01371 }
01372 
01373 void 
01374 GlobalPrinters::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName)
01375 {
01376   *aDefaultPrinterName = nsnull;
01377   
01378   PRBool allocate = (GlobalPrinters::GetInstance()->PrintersAreAllocated() == PR_FALSE);
01379   
01380   if (allocate) {
01381     nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
01382     if (NS_FAILED(rv)) {
01383       return;
01384     }
01385   }
01386   NS_ASSERTION(GlobalPrinters::GetInstance()->PrintersAreAllocated(), "no GlobalPrinters");
01387 
01388   if (GlobalPrinters::GetInstance()->GetNumPrinters() == 0)
01389     return;
01390   
01391   *aDefaultPrinterName = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(0));
01392 
01393   if (allocate) {  
01394     GlobalPrinters::GetInstance()->FreeGlobalPrinters();
01395   }  
01396 }
01397