/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: MPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Mozilla Public License Version * 1.1 (the "License"); you may not use this file except in compliance with * the License. You may obtain a copy of the License at * http://www.mozilla.org/MPL/ * * Software distributed under the License is distributed on an "AS IS" basis, * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License * for the specific language governing rights and limitations under the * License. * * The Original Code is mozilla.org code. * * The Initial Developer of the Original Code is * Netscape Communications Corporation. * Portions created by the Initial Developer are Copyright (C) 1998 * the Initial Developer. All Rights Reserved. * * Contributor(s): * Roland Mainz * Ken Herron * Julien Lafon * * Alternatively, the contents of this file may be used under the terms of * either of the GNU General Public License Version 2 or later (the "GPL"), * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"), * in which case the provisions of the GPL or the LGPL are applicable instead * of those above. If you wish to allow use of your version of this file only * under the terms of either the GPL or the LGPL, and not to allow others to * use your version of this file under the terms of the MPL, indicate your * decision by deleting the provisions above and replace them with the notice * and other provisions required by the GPL or the LGPL. If you do not delete * the provisions above, a recipient may use your version of this file under * the terms of any one of the MPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ /* Store per-printer features in temp. prefs vars that the * print dialog can pick them up... */ #define SET_PRINTER_FEATURES_VIA_PREFS 1 #define PRINTERFEATURES_PREF "print.tmp.printerfeatures" #ifdef MOZ_LOGGING #define FORCE_PR_LOG 1 /* Allow logging in the release build */ #endif /* MOZ_LOGGING */ #include "prlog.h" #include "plstr.h" #include "nsDeviceContextSpecG.h" #include "nsIPref.h" #include "prenv.h" /* for PR_GetEnv */ #include "nsPrintfCString.h" #include "nsReadableUtils.h" #include "nsIServiceManager.h" #ifdef USE_XPRINT #include "xprintutil.h" #endif /* USE_XPRINT */ #ifdef USE_POSTSCRIPT #include "nsPSPrinters.h" #include "nsPaperPS.h" /* Paper size list */ #endif /* USE_POSTSCRIPT */ /* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */ #define MAKE_PR_BOOL(val) ((val)?(PR_TRUE):(PR_FALSE)) #ifdef PR_LOGGING static PRLogModuleInfo *DeviceContextSpecGTKLM = PR_NewLogModule("DeviceContextSpecGTK"); #endif /* PR_LOGGING */ /* Macro to make lines shorter */ #define DO_PR_DEBUG_LOG(x) PR_LOG(DeviceContextSpecGTKLM, PR_LOG_DEBUG, x) //---------------------------------------------------------------------------------- // The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecGTK // The PrinterEnumerator creates the printer info // but the nsDeviceContextSpecGTK cleans it up // If it gets created (via the Page Setup Dialog) but the user never prints anything // then it will never be delete, so this class takes care of that. class GlobalPrinters { public: static GlobalPrinters* GetInstance() { return &mGlobalPrinters; } ~GlobalPrinters() { FreeGlobalPrinters(); } void FreeGlobalPrinters(); nsresult InitializeGlobalPrinters(); PRBool PrintersAreAllocated() { return mGlobalPrinterList != nsnull; } PRInt32 GetNumPrinters() { return mGlobalPrinterList ? mGlobalPrinterList->Count() : 0; } nsString* GetStringAt(PRInt32 aInx) { return mGlobalPrinterList->StringAt(aInx); } void GetDefaultPrinterName(PRUnichar **aDefaultPrinterName); protected: GlobalPrinters() {} static GlobalPrinters mGlobalPrinters; static nsStringArray* mGlobalPrinterList; }; #ifdef SET_PRINTER_FEATURES_VIA_PREFS /* "Prototype" for the new nsPrinterFeatures service */ class nsPrinterFeatures { public: nsPrinterFeatures( const char *printername ); ~nsPrinterFeatures() {}; /* Does this printer allow to set/change the paper size ? */ void SetCanChangePaperSize( PRBool aCanSetPaperSize ); /* Does this Mozilla print module allow set/change the paper size ? */ void SetSupportsPaperSizeChange( PRBool aSupportsPaperSizeChange ); /* Set number of paper size records and the records itself */ void SetNumPaperSizeRecords( PRInt32 aCount ); void SetPaperRecord( PRInt32 aIndex, const char *aName, PRInt32 aWidthMM, PRInt32 aHeightMM, PRBool aIsInch ); /* Does this printer allow to set/change the content orientation ? */ void SetCanChangeOrientation( PRBool aCanSetOrientation ); /* Does this Mozilla print module allow set/change the content orientation ? */ void SetSupportsOrientationChange( PRBool aSupportsOrientationChange ); /* Set number of orientation records and the records itself */ void SetNumOrientationRecords( PRInt32 aCount ); void SetOrientationRecord( PRInt32 aIndex, const char *aName ); /* Does this printer allow to set/change the plex mode ? */ void SetCanChangePlex( PRBool aCanSetPlex ); /* Does this Mozilla print module allow set/change the plex mode ? */ void SetSupportsPlexChange( PRBool aSupportsPlexChange ); /* Set number of plex records and the records itself */ void SetNumPlexRecords( PRInt32 aCount ); void SetPlexRecord( PRInt32 aIndex, const char *aName ); /* Does this printer allow to set/change the resolution name ? */ void SetCanChangeResolutionName( PRBool aCanSetResolutionName ); /* Does this Mozilla print module allow set/change the resolution name ? */ void SetSupportsResolutionNameChange( PRBool aSupportsResolutionChange ); /* Set number of resolution records and the records itself */ void SetNumResolutionNameRecords( PRInt32 aCount ); void SetResolutionNameRecord( PRInt32 aIndex, const char *aName ); /* Does this printer allow to set/change the colorspace ? */ void SetCanChangeColorspace( PRBool aCanSetColorspace ); /* Does this Mozilla print module allow set/change the colorspace ? */ void SetSupportsColorspaceChange( PRBool aSupportsColorspace ); /* Set number of colorspace records and the records itself */ void SetNumColorspaceRecords( PRInt32 aCount ); void SetColorspaceRecord( PRInt32 aIndex, const char *aName ); /* Does this device allow to set/change the usage of the internal grayscale mode ? */ void SetCanChangePrintInColor( PRBool aCanSetPrintInColor ); /* Does this printer allow to set/change the usage of the internal grayscale mode ? */ void SetSupportsPrintInColorChange( PRBool aSupportPrintInColorChange ); /* Does this device allow to set/change the usage of font download to the printer? */ void SetCanChangeDownloadFonts( PRBool aCanSetDownloadFonts ); /* Does this printer allow to set/change the usage of font download to the printer? */ void SetSupportsDownloadFontsChange( PRBool aSupportDownloadFontsChange ); /* Does this device allow to set/change the job title ? */ void SetCanChangeJobTitle( PRBool aCanSetJobTitle ); /* Does this printer allow to set/change the job title ? */ void SetSupportsJobTitleChange( PRBool aSupportJobTitleChange ); /* Does this device allow to set/change the spooler command ? */ void SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand ); /* Does this printer allow to set/change the spooler command ? */ void SetSupportsSpoolerCommandChange( PRBool aSupportSpoolerCommandChange ); /* Does this device allow to set/change number of copies for an document ? */ void SetCanChangeNumCopies( PRBool aCanSetNumCopies ); /* Does this device allow multiple devicecontext instances to be used in * parallel (e.g. print while the device is already in use by print-preview * or printing while another print job is in progress) ? */ void SetMultipleConcurrentDeviceContextsSupported( PRBool aCanUseMultipleInstances ); private: /* private helper methods */ void SetBoolValue( const char *tagname, PRBool value ); void SetIntValue( const char *tagname, PRInt32 value ); void SetCharValue( const char *tagname, const char *value ); nsXPIDLCString mPrinterName; nsCOMPtr mPrefs; }; void nsPrinterFeatures::SetBoolValue( const char *tagname, PRBool value ) { mPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value); } void nsPrinterFeatures::SetIntValue( const char *tagname, PRInt32 value ) { mPrefs->SetIntPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value); } void nsPrinterFeatures::SetCharValue( const char *tagname, const char *value ) { mPrefs->SetCharPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value); } nsPrinterFeatures::nsPrinterFeatures( const char *printername ) { DO_PR_DEBUG_LOG(("nsPrinterFeatures::nsPrinterFeatures('%s')\n", printername)); mPrinterName.Assign(printername); mPrefs = do_GetService(NS_PREF_CONTRACTID); SetBoolValue("has_special_printerfeatures", PR_TRUE); } void nsPrinterFeatures::SetCanChangePaperSize( PRBool aCanSetPaperSize ) { SetBoolValue("can_change_paper_size", aCanSetPaperSize); } void nsPrinterFeatures::SetSupportsPaperSizeChange( PRBool aSupportsPaperSizeChange ) { SetBoolValue("supports_paper_size_change", aSupportsPaperSizeChange); } /* Set number of paper size records and the records itself */ void nsPrinterFeatures::SetNumPaperSizeRecords( PRInt32 aCount ) { SetIntValue("paper.count", aCount); } void nsPrinterFeatures::SetPaperRecord(PRInt32 aIndex, const char *aPaperName, PRInt32 aWidthMM, PRInt32 aHeightMM, PRBool aIsInch) { SetCharValue(nsPrintfCString(256, "paper.%d.name", aIndex).get(), aPaperName); SetIntValue( nsPrintfCString(256, "paper.%d.width_mm", aIndex).get(), aWidthMM); SetIntValue( nsPrintfCString(256, "paper.%d.height_mm", aIndex).get(), aHeightMM); SetBoolValue(nsPrintfCString(256, "paper.%d.is_inch", aIndex).get(), aIsInch); } void nsPrinterFeatures::SetCanChangeOrientation( PRBool aCanSetOrientation ) { SetBoolValue("can_change_orientation", aCanSetOrientation); } void nsPrinterFeatures::SetSupportsOrientationChange( PRBool aSupportsOrientationChange ) { SetBoolValue("supports_orientation_change", aSupportsOrientationChange); } void nsPrinterFeatures::SetNumOrientationRecords( PRInt32 aCount ) { SetIntValue("orientation.count", aCount); } void nsPrinterFeatures::SetOrientationRecord( PRInt32 aIndex, const char *aOrientationName ) { SetCharValue(nsPrintfCString(256, "orientation.%d.name", aIndex).get(), aOrientationName); } void nsPrinterFeatures::SetCanChangePlex( PRBool aCanSetPlex ) { SetBoolValue("can_change_plex", aCanSetPlex); } void nsPrinterFeatures::SetSupportsPlexChange( PRBool aSupportsPlexChange ) { SetBoolValue("supports_plex_change", aSupportsPlexChange); } void nsPrinterFeatures::SetNumPlexRecords( PRInt32 aCount ) { SetIntValue("plex.count", aCount); } void nsPrinterFeatures::SetPlexRecord( PRInt32 aIndex, const char *aPlexName ) { SetCharValue(nsPrintfCString(256, "plex.%d.name", aIndex).get(), aPlexName); } void nsPrinterFeatures::SetCanChangeResolutionName( PRBool aCanSetResolutionName ) { SetBoolValue("can_change_resolution", aCanSetResolutionName); } void nsPrinterFeatures::SetSupportsResolutionNameChange( PRBool aSupportsResolutionNameChange ) { SetBoolValue("supports_resolution_change", aSupportsResolutionNameChange); } void nsPrinterFeatures::SetNumResolutionNameRecords( PRInt32 aCount ) { SetIntValue("resolution.count", aCount); } void nsPrinterFeatures::SetResolutionNameRecord( PRInt32 aIndex, const char *aResolutionName ) { SetCharValue(nsPrintfCString(256, "resolution.%d.name", aIndex).get(), aResolutionName); } void nsPrinterFeatures::SetCanChangeColorspace( PRBool aCanSetColorspace ) { SetBoolValue("can_change_colorspace", aCanSetColorspace); } void nsPrinterFeatures::SetSupportsColorspaceChange( PRBool aSupportsColorspaceChange ) { SetBoolValue("supports_colorspace_change", aSupportsColorspaceChange); } void nsPrinterFeatures::SetNumColorspaceRecords( PRInt32 aCount ) { SetIntValue("colorspace.count", aCount); } void nsPrinterFeatures::SetColorspaceRecord( PRInt32 aIndex, const char *aColorspace ) { SetCharValue(nsPrintfCString(256, "colorspace.%d.name", aIndex).get(), aColorspace); } void nsPrinterFeatures::SetCanChangeDownloadFonts( PRBool aCanSetDownloadFonts ) { SetBoolValue("can_change_downloadfonts", aCanSetDownloadFonts); } void nsPrinterFeatures::SetSupportsDownloadFontsChange( PRBool aSupportDownloadFontsChange ) { SetBoolValue("supports_downloadfonts_change", aSupportDownloadFontsChange); } void nsPrinterFeatures::SetCanChangePrintInColor( PRBool aCanSetPrintInColor ) { SetBoolValue("can_change_printincolor", aCanSetPrintInColor); } void nsPrinterFeatures::SetSupportsPrintInColorChange( PRBool aSupportPrintInColorChange ) { SetBoolValue("supports_printincolor_change", aSupportPrintInColorChange); } void nsPrinterFeatures::SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand ) { SetBoolValue("can_change_spoolercommand", aCanSetSpoolerCommand); } void nsPrinterFeatures::SetSupportsSpoolerCommandChange( PRBool aSupportSpoolerCommandChange ) { SetBoolValue("supports_spoolercommand_change", aSupportSpoolerCommandChange); } void nsPrinterFeatures::SetCanChangeJobTitle( PRBool aCanSetJobTitle ) { SetBoolValue("can_change_jobtitle", aCanSetJobTitle); } void nsPrinterFeatures::SetSupportsJobTitleChange( PRBool aSupportsJobTitle ) { SetBoolValue("supports_jobtitle_change", aSupportsJobTitle); } void nsPrinterFeatures::SetCanChangeNumCopies( PRBool aCanSetNumCopies ) { SetBoolValue("can_change_num_copies", aCanSetNumCopies); } void nsPrinterFeatures::SetMultipleConcurrentDeviceContextsSupported( PRBool aCanUseMultipleInstances ) { SetBoolValue("can_use_multiple_devicecontexts_concurrently", aCanUseMultipleInstances); } #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ //--------------- // static members GlobalPrinters GlobalPrinters::mGlobalPrinters; nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull; //--------------- nsDeviceContextSpecGTK::nsDeviceContextSpecGTK() { DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n")); } nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK() { DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()\n")); } /* Use both PostScript and Xprint module */ #if defined(USE_XPRINT) && defined(USE_POSTSCRIPT) NS_IMPL_ISUPPORTS3(nsDeviceContextSpecGTK, nsIDeviceContextSpec, nsIDeviceContextSpecPS, nsIDeviceContextSpecXp) /* Use only PostScript module */ #elif !defined(USE_XPRINT) && defined(USE_POSTSCRIPT) NS_IMPL_ISUPPORTS2(nsDeviceContextSpecGTK, nsIDeviceContextSpec, nsIDeviceContextSpecPS) /* Use only Xprint module module */ #elif defined(USE_XPRINT) && !defined(USE_POSTSCRIPT) NS_IMPL_ISUPPORTS2(nsDeviceContextSpecGTK, nsIDeviceContextSpec, nsIDeviceContextSpecXp) /* Both Xprint and PostScript module are missing */ #elif !defined(USE_XPRINT) && !defined(USE_POSTSCRIPT) NS_IMPL_ISUPPORTS1(nsDeviceContextSpecGTK, nsIDeviceContextSpec) #else #error "This should not happen" #endif /** ------------------------------------------------------- * Initialize the nsDeviceContextSpecGTK * @update dc 2/15/98 * @update syd 3/2/99 * * gisburn: Please note that this function exists as 1:1 copy in other * toolkits including: * - GTK+-toolkit: * file: mozilla/gfx/src/gtk/nsDeviceContextSpecG.cpp * function: NS_IMETHODIMP nsDeviceContextSpecGTK::Init() * - Xlib-toolkit: * file: mozilla/gfx/src/xlib/nsDeviceContextSpecXlib.cpp * function: NS_IMETHODIMP nsDeviceContextSpecXlib::Init() * * ** Please update the other toolkits when changing this function. */ NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIPrintSettings *aPS, PRBool aIsPrintPreview) { DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::Init(aPS=%p)\n", aPS)); nsresult rv = NS_ERROR_FAILURE; mPrintSettings = aPS; // if there is a current selection then enable the "Selection" radio button rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); if (NS_FAILED(rv)) { return rv; } GlobalPrinters::GetInstance()->FreeGlobalPrinters(); if (aPS) { PRBool reversed = PR_FALSE; PRBool color = PR_FALSE; PRBool tofile = PR_FALSE; PRInt16 printRange = nsIPrintSettings::kRangeAllPages; PRInt32 orientation = NS_PORTRAIT; PRInt32 fromPage = 1; PRInt32 toPage = 1; PRUnichar *command = nsnull; PRInt32 copies = 1; PRUnichar *printer = nsnull; PRUnichar *papername = nsnull; PRUnichar *plexname = nsnull; PRUnichar *resolutionname = nsnull; PRUnichar *colorspace = nsnull; PRBool downloadfonts = PR_TRUE; PRUnichar *printfile = nsnull; double dleft = 0.5; double dright = 0.5; double dtop = 0.5; double dbottom = 0.5; aPS->GetPrinterName(&printer); aPS->GetPrintReversed(&reversed); aPS->GetPrintInColor(&color); aPS->GetPaperName(&papername); aPS->GetResolutionName(&resolutionname); aPS->GetColorspace(&colorspace); aPS->GetDownloadFonts(&downloadfonts); aPS->GetPlexName(&plexname); aPS->GetOrientation(&orientation); aPS->GetPrintCommand(&command); aPS->GetPrintRange(&printRange); aPS->GetToFileName(&printfile); aPS->GetPrintToFile(&tofile); aPS->GetStartPageRange(&fromPage); aPS->GetEndPageRange(&toPage); aPS->GetNumCopies(&copies); aPS->GetMarginTop(&dtop); aPS->GetMarginLeft(&dleft); aPS->GetMarginBottom(&dbottom); aPS->GetMarginRight(&dright); if (printfile) PL_strncpyz(mPath, NS_ConvertUCS2toUTF8(printfile).get(), sizeof(mPath)); if (command) PL_strncpyz(mCommand, NS_ConvertUCS2toUTF8(command).get(), sizeof(mCommand)); if (printer) PL_strncpyz(mPrinter, NS_ConvertUCS2toUTF8(printer).get(), sizeof(mPrinter)); if (papername) PL_strncpyz(mPaperName, NS_ConvertUCS2toUTF8(papername).get(), sizeof(mPaperName)); if (plexname) PL_strncpyz(mPlexName, NS_ConvertUCS2toUTF8(plexname).get(), sizeof(mPlexName)); if (resolutionname) PL_strncpyz(mResolutionName, NS_ConvertUCS2toUTF8(resolutionname).get(), sizeof(mResolutionName)); if (colorspace) PL_strncpyz(mColorspace, NS_ConvertUCS2toUTF8(colorspace).get(), sizeof(mColorspace)); DO_PR_DEBUG_LOG(("margins: %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright)); DO_PR_DEBUG_LOG(("printRange %d\n", printRange)); DO_PR_DEBUG_LOG(("fromPage %d\n", fromPage)); DO_PR_DEBUG_LOG(("toPage %d\n", toPage)); DO_PR_DEBUG_LOG(("tofile %d\n", tofile)); DO_PR_DEBUG_LOG(("printfile '%s'\n", printfile? NS_ConvertUCS2toUTF8(printfile).get():"")); DO_PR_DEBUG_LOG(("command '%s'\n", command? NS_ConvertUCS2toUTF8(command).get():"")); DO_PR_DEBUG_LOG(("printer '%s'\n", printer? NS_ConvertUCS2toUTF8(printer).get():"")); DO_PR_DEBUG_LOG(("papername '%s'\n", papername? NS_ConvertUCS2toUTF8(papername).get():"")); DO_PR_DEBUG_LOG(("plexname '%s'\n", plexname? NS_ConvertUCS2toUTF8(plexname).get():"")); DO_PR_DEBUG_LOG(("resolution '%s'\n", resolutionname? NS_ConvertUCS2toUTF8(resolutionname).get():"")); DO_PR_DEBUG_LOG(("colorspace '%s'\n", colorspace? NS_ConvertUCS2toUTF8(colorspace).get():"")); mTop = dtop; mBottom = dbottom; mLeft = dleft; mRight = dright; mFpf = !reversed; mDownloadFonts = downloadfonts; mGrayscale = !color; mOrientation = orientation; mToPrinter = !tofile; mCopies = copies; mIsPPreview = aIsPrintPreview; mCancel = PR_FALSE; } return rv; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetToPrinter(PRBool &aToPrinter) { aToPrinter = mToPrinter; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetIsPrintPreview(PRBool &aIsPPreview) { aIsPPreview = mIsPPreview; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetPrinterName ( const char **aPrinter ) { *aPrinter = mPrinter; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetCopies ( int &aCopies ) { aCopies = mCopies; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetFirstPageFirst(PRBool &aFpf) { aFpf = mFpf; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetGrayscale(PRBool &aGrayscale) { aGrayscale = mGrayscale; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetLandscape(PRBool &aLandscape) { aLandscape = (mOrientation == NS_LANDSCAPE); return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetTopMargin(float &aValue) { aValue = mTop; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetBottomMargin(float &aValue) { aValue = mBottom; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetRightMargin(float &aValue) { aValue = mRight; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetLeftMargin(float &aValue) { aValue = mLeft; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetCommand(const char **aCommand) { *aCommand = mCommand; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetPath(const char **aPath) { *aPath = mPath; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetUserCancelled(PRBool &aCancel) { aCancel = mCancel; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetPaperName( const char **aPaperName ) { *aPaperName = mPaperName; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetPlexName( const char **aPlexName ) { *aPlexName = mPlexName; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetResolutionName( const char **aResolutionName ) { *aResolutionName = mResolutionName; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetColorspace( const char **aColorspace ) { *aColorspace = mColorspace; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetDownloadFonts(PRBool &aDownloadFonts) { aDownloadFonts = mDownloadFonts; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecGTK::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) { return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight); } NS_IMETHODIMP nsDeviceContextSpecGTK::GetPrintMethod(PrintMethod &aMethod) { return GetPrintMethod(mPrinter, aMethod); } /* static !! */ nsresult nsDeviceContextSpecGTK::GetPrintMethod(const char *aPrinter, PrintMethod &aMethod) { #if defined(USE_POSTSCRIPT) && defined(USE_XPRINT) if (nsPSPrinterList::kTypeUnknown == nsPSPrinterList::GetPrinterType(nsDependentCString(aPrinter))) aMethod = pmXprint; else aMethod = pmPostScript; return NS_OK; #elif defined(USE_XPRINT) aMethod = pmXprint; return NS_OK; #elif defined(USE_POSTSCRIPT) aMethod = pmPostScript; return NS_OK; #else return NS_ERROR_UNEXPECTED; #endif } NS_IMETHODIMP nsDeviceContextSpecGTK::ClosePrintManager() { return NS_OK; } /* Get prefs for printer * Search order: * - Get prefs per printer name and module name * - Get prefs per printer name * - Get prefs per module name * - Get prefs */ static nsresult CopyPrinterCharPref(nsIPref *pref, const char *modulename, const char *printername, const char *prefname, char **return_buf) { DO_PR_DEBUG_LOG(("CopyPrinterCharPref('%s', '%s', '%s')\n", modulename, printername, prefname)); NS_ENSURE_ARG_POINTER(return_buf); nsXPIDLCString name; nsresult rv = NS_ERROR_FAILURE; if (printername && modulename) { /* Get prefs per printer name and module name */ name = nsPrintfCString(512, "print.%s.printer_%s.%s", modulename, printername, prefname); DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); rv = pref->CopyCharPref(name, return_buf); } if (NS_FAILED(rv)) { if (printername) { /* Get prefs per printer name */ name = nsPrintfCString(512, "print.printer_%s.%s", printername, prefname); DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); rv = pref->CopyCharPref(name, return_buf); } if (NS_FAILED(rv)) { if (modulename) { /* Get prefs per module name */ name = nsPrintfCString(512, "print.%s.%s", modulename, prefname); DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); rv = pref->CopyCharPref(name, return_buf); } if (NS_FAILED(rv)) { /* Get prefs */ name = nsPrintfCString(512, "print.%s", prefname); DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get())); rv = pref->CopyCharPref(name, return_buf); } } } #ifdef PR_LOG if (NS_SUCCEEDED(rv)) { DO_PR_DEBUG_LOG(("CopyPrinterCharPref returning '%s'.\n", *return_buf)); } else { DO_PR_DEBUG_LOG(("CopyPrinterCharPref failure.\n")); } #endif /* PR_LOG */ return rv; } // Printer Enumerator nsPrinterEnumeratorGTK::nsPrinterEnumeratorGTK() { } NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorGTK, nsIPrinterEnumerator) NS_IMETHODIMP nsPrinterEnumeratorGTK::EnumeratePrinters(PRUint32* aCount, PRUnichar*** aResult) { NS_ENSURE_ARG(aCount); NS_ENSURE_ARG_POINTER(aResult); if (aCount) *aCount = 0; else return NS_ERROR_NULL_POINTER; if (aResult) *aResult = nsnull; else return NS_ERROR_NULL_POINTER; nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); if (NS_FAILED(rv)) { return rv; } PRInt32 numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters(); PRUnichar** array = (PRUnichar**) nsMemory::Alloc(numPrinters * sizeof(PRUnichar*)); if (!array && numPrinters > 0) { GlobalPrinters::GetInstance()->FreeGlobalPrinters(); return NS_ERROR_OUT_OF_MEMORY; } int count = 0; while( count < numPrinters ) { PRUnichar *str = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(count)); if (!str) { for (int i = count - 1; i >= 0; i--) nsMemory::Free(array[i]); nsMemory::Free(array); GlobalPrinters::GetInstance()->FreeGlobalPrinters(); return NS_ERROR_OUT_OF_MEMORY; } array[count++] = str; } *aCount = count; *aResult = array; GlobalPrinters::GetInstance()->FreeGlobalPrinters(); return NS_OK; } /* readonly attribute wstring defaultPrinterName; */ NS_IMETHODIMP nsPrinterEnumeratorGTK::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName) { DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::GetDefaultPrinterName()\n")); NS_ENSURE_ARG_POINTER(aDefaultPrinterName); GlobalPrinters::GetInstance()->GetDefaultPrinterName(aDefaultPrinterName); DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", NS_ConvertUCS2toUTF8(*aDefaultPrinterName).get())); return NS_OK; } /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */ NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings) { DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter()")); nsresult rv; NS_ENSURE_ARG_POINTER(aPrinterName); NS_ENSURE_ARG_POINTER(aPrintSettings); NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE); NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE); nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */ printerName; /* "Stripped" name of printer */ fullPrinterName.Assign(NS_ConvertUCS2toUTF8(aPrinterName)); printerName.Assign(NS_ConvertUCS2toUTF8(aPrinterName)); DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get())); PrintMethod type = pmInvalid; rv = nsDeviceContextSpecGTK::GetPrintMethod(printerName, type); if (NS_FAILED(rv)) return rv; #ifdef USE_POSTSCRIPT /* "Demangle" postscript printer name */ if (type == pmPostScript) { /* Strip the printing method name from the printer, * e.g. turn "PostScript/foobar" to "foobar" */ PRInt32 slash = printerName.FindChar('/'); if (kNotFound != slash) printerName.Cut(0, slash + 1); } #endif /* USE_POSTSCRIPT */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS /* Defaults to FALSE */ pPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.has_special_printerfeatures", fullPrinterName.get()).get(), PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* Set filename */ nsXPIDLCString filename; if (NS_FAILED(CopyPrinterCharPref(pPrefs, nsnull, printerName, "filename", getter_Copies(filename)))) { const char *path; if (!(path = PR_GetEnv("PWD"))) path = PR_GetEnv("HOME"); if (path) filename = nsPrintfCString(PATH_MAX, "%s/mozilla.ps", path); else filename.Assign("mozilla.ps"); } DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get())); aPrintSettings->SetToFileName(NS_ConvertUTF8toUCS2(filename).get()); aPrintSettings->SetIsInitializedFromPrinter(PR_TRUE); #ifdef USE_XPRINT if (type == pmXprint) { DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for Xprint printer\n")); /* Setup the capabilties list of Mozilla's Xprint print module */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS nsPrinterFeatures printerFeatures(fullPrinterName); printerFeatures.SetSupportsPaperSizeChange(PR_TRUE); printerFeatures.SetSupportsOrientationChange(PR_TRUE); printerFeatures.SetSupportsPlexChange(PR_TRUE); printerFeatures.SetSupportsResolutionNameChange(PR_TRUE); printerFeatures.SetSupportsColorspaceChange(PR_TRUE); printerFeatures.SetSupportsJobTitleChange(PR_TRUE); printerFeatures.SetSupportsSpoolerCommandChange(PR_FALSE); /* won't work by design and very good reasons! */ #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* Setup the capabilties list of this specific printer */ Display *pdpy; XPContext pcontext; if (XpuGetPrinter(printerName, &pdpy, &pcontext) != 1) return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND; XpuSupportedFlags supported_doc_attrs = XpuGetSupportedDocAttributes(pdpy, pcontext); /* Setup orientation stuff */ XpuOrientationList olist; int ocount; XpuOrientationRec *default_orientation; /* Setup plex stuff */ XpuPlexList plexlist; int plexcount; XpuPlexRec *default_plex; #ifdef SET_PRINTER_FEATURES_VIA_PREFS PRBool canSetOrientation = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_CONTENT_ORIENTATION); printerFeatures.SetCanChangeOrientation(canSetOrientation); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* Get list of supported orientations */ olist = XpuGetOrientationList(pdpy, pcontext, &ocount); if (olist) { default_orientation = &olist[0]; /* First entry is the default one */ if (!PL_strcasecmp(default_orientation->orientation, "portrait")) { DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n")); aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation); } else if (!PL_strcasecmp(default_orientation->orientation, "landscape")) { DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n")); aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation); } else { DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", default_orientation->orientation)); } #ifdef SET_PRINTER_FEATURES_VIA_PREFS int i; for( i = 0 ; i < ocount ; i++ ) { XpuOrientationRec *curr = &olist[i]; printerFeatures.SetOrientationRecord(i, curr->orientation); } printerFeatures.SetNumOrientationRecords(ocount); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ XpuFreeOrientationList(olist); } #ifdef SET_PRINTER_FEATURES_VIA_PREFS PRBool canSetPlexMode = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_PLEX); printerFeatures.SetCanChangePlex(canSetPlexMode); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* Get list of supported plex modes */ plexlist = XpuGetPlexList(pdpy, pcontext, &plexcount); if (plexlist) { default_plex = &plexlist[0]; /* First entry is the default one */ DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", default_plex->plex)); aPrintSettings->SetPlexName(NS_ConvertUTF8toUCS2(default_plex->plex).get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS int i; for( i = 0 ; i < plexcount ; i++ ) { XpuPlexRec *curr = &plexlist[i]; printerFeatures.SetPlexRecord(i, curr->plex); } printerFeatures.SetNumPlexRecords(plexcount); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ XpuFreePlexList(plexlist); } /* Setup Number of Copies */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS PRBool canSetNumCopies = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_COPY_COUNT); printerFeatures.SetCanChangeNumCopies(canSetNumCopies); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ long numCopies; if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "copy-count", &numCopies) != 1 ) { /* Fallback on failure */ numCopies = 1; } aPrintSettings->SetNumCopies(numCopies); /* Setup paper size stuff */ XpuMediumSourceSizeList mlist; int mcount; XpuMediumSourceSizeRec *default_medium; #ifdef SET_PRINTER_FEATURES_VIA_PREFS PRBool canSetPaperSize = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM); printerFeatures.SetCanChangePaperSize(canSetPaperSize); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ mlist = XpuGetMediumSourceSizeList(pdpy, pcontext, &mcount); if (mlist) { nsXPIDLCString papername; default_medium = &mlist[0]; /* First entry is the default one */ double total_width = default_medium->ma1 + default_medium->ma2, total_height = default_medium->ma3 + default_medium->ma4; /* Either "paper" or "tray/paper" */ papername.Truncate(); if (default_medium->tray_name) { papername.Append(default_medium->tray_name); papername.Append("/"); } papername.Append(default_medium->medium_name); DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g/%g mm)\n", papername.get(), total_width, total_height)); aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined); aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters); aPrintSettings->SetPaperWidth(total_width); aPrintSettings->SetPaperHeight(total_height); aPrintSettings->SetPaperName(NS_ConvertUTF8toUCS2(papername).get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS int i; for( i = 0 ; i < mcount ; i++ ) { XpuMediumSourceSizeRec *curr = &mlist[i]; double total_width = curr->ma1 + curr->ma2, total_height = curr->ma3 + curr->ma4; papername.Truncate(); if (curr->tray_name) { papername.Append(curr->tray_name); papername.Append("/"); } papername.Append(curr->medium_name); printerFeatures.SetPaperRecord(i, papername, PRInt32(total_width), PRInt32(total_height), PR_FALSE); } printerFeatures.SetNumPaperSizeRecords(mcount); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ XpuFreeMediumSourceSizeList(mlist); } /* Setup resolution/quality stuff */ XpuResolutionList rlist; int rcount; XpuResolutionRec *default_resolution; #ifdef SET_PRINTER_FEATURES_VIA_PREFS PRBool canSetResolutionName = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_DEFAULT_PRINTER_RESOLUTION); printerFeatures.SetCanChangeResolutionName(canSetResolutionName); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ rlist = XpuGetResolutionList(pdpy, pcontext, &rcount); if (rlist) { default_resolution = &rlist[0]; /* First entry is the default one */ DO_PR_DEBUG_LOG(("setting default resolution to '%s'/%ldx%ld\n", default_resolution->name, default_resolution->x_dpi, default_resolution->y_dpi)); aPrintSettings->SetResolutionName(NS_ConvertUTF8toUCS2(default_resolution->name).get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS int i; for( i = 0 ; i < rcount ; i++ ) { XpuResolutionRec *curr = &rlist[i]; printerFeatures.SetResolutionNameRecord(i, curr->name); } printerFeatures.SetNumResolutionNameRecords(rcount); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ XpuFreeResolutionList(rlist); } /* We still support the old print-in-color boolean */ printerFeatures.SetSupportsPrintInColorChange(PR_TRUE); printerFeatures.SetCanChangePrintInColor(PR_TRUE); /* Setup colorspace stuff */ XpuColorspaceList cslist; int cscount; XpuColorspaceRec *default_colorspace; #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeColorspace(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ cslist = XpuGetColorspaceList(pdpy, pcontext, &cscount); if (cslist) { default_colorspace = &cslist[0]; /* First entry is the default one */ DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", default_colorspace->name)); aPrintSettings->SetColorspace(NS_ConvertUTF8toUCS2(default_colorspace->name).get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS int i; for( i = 0 ; i < cscount ; i++ ) { XpuColorspaceRec *curr = &cslist[i]; printerFeatures.SetColorspaceRecord(i, curr->name); } printerFeatures.SetNumColorspaceRecords(cscount); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ XpuFreeColorspaceList(cslist); } /* Fonts */ PRBool canSetListFontsMode = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_LISTFONTS_MODES); printerFeatures.SetCanChangeDownloadFonts(canSetListFontsMode); printerFeatures.SetSupportsDownloadFontsChange(PR_TRUE); Bool downloadFonts = XpuGetEnableFontDownload(pdpy, pcontext); aPrintSettings->SetDownloadFonts(downloadFonts); #ifdef SET_PRINTER_FEATURES_VIA_PREFS /* Xprint does not allow the client to set a spooler command. * Job spooling is the job of the server side (=Xprt) */ printerFeatures.SetCanChangeSpoolerCommand(PR_FALSE); /* Check whether printer/driver allow changes of the job name */ PRBool canSetJobName = MAKE_PR_BOOL(XpuGetSupportedJobAttributes(pdpy, pcontext) & XPUATTRIBUTESUPPORTED_JOB_NAME); printerFeatures.SetCanChangeJobTitle(canSetJobName); /* Mozilla's Xprint support allows multiple nsIDeviceContext instances * be used in parallel */ printerFeatures.SetMultipleConcurrentDeviceContextsSupported(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ XpuClosePrinterDisplay(pdpy, pcontext); return NS_OK; } else #endif /* USE_XPRINT */ #ifdef USE_POSTSCRIPT if (type == pmPostScript) { DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n")); #ifdef SET_PRINTER_FEATURES_VIA_PREFS nsPrinterFeatures printerFeatures(fullPrinterName); printerFeatures.SetSupportsPaperSizeChange(PR_TRUE); printerFeatures.SetSupportsOrientationChange(PR_TRUE); printerFeatures.SetSupportsPlexChange(PR_FALSE); printerFeatures.SetSupportsResolutionNameChange(PR_FALSE); printerFeatures.SetSupportsColorspaceChange(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeOrientation(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ nsXPIDLCString orientation; if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "orientation", getter_Copies(orientation)))) { if (!PL_strcasecmp(orientation, "portrait")) { DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n")); aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation); } else if (!PL_strcasecmp(orientation, "landscape")) { DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n")); aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation); } else { DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get())); } } #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetOrientationRecord(0, "portrait"); printerFeatures.SetOrientationRecord(1, "landscape"); printerFeatures.SetNumOrientationRecords(2); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* PostScript module does not support changing the plex mode... */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangePlex(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", "default")); aPrintSettings->SetPlexName(NS_LITERAL_STRING("default").get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetPlexRecord(0, "default"); printerFeatures.SetNumPlexRecords(1); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* PostScript module does not support changing the resolution mode... */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeResolutionName(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default")); aPrintSettings->SetResolutionName(NS_LITERAL_STRING("default").get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetResolutionNameRecord(0, "default"); printerFeatures.SetNumResolutionNameRecords(1); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ /* PostScript module does not support changing the colorspace... */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeColorspace(PR_FALSE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default")); aPrintSettings->SetColorspace(NS_LITERAL_STRING("default").get()); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetColorspaceRecord(0, "default"); printerFeatures.SetNumColorspaceRecords(1); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangePaperSize(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ nsXPIDLCString papername; if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) { nsPaperSizePS paper; if (paper.Find(papername)) { DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n", paper.Name(), paper.Width_mm(), paper.Height_mm())); aPrintSettings->SetPaperSizeUnit(paper.IsMetric() ? (int)nsIPrintSettings::kPaperSizeMillimeters : (int)nsIPrintSettings::kPaperSizeInches); aPrintSettings->SetPaperWidth(paper.Width_mm()); aPrintSettings->SetPaperHeight(paper.Height_mm()); aPrintSettings->SetPaperName(NS_ConvertASCIItoUCS2(paper.Name()).get()); } else { DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get())); } #ifdef SET_PRINTER_FEATURES_VIA_PREFS paper.First(); int count = 0; while (!paper.AtEnd()) { printerFeatures.SetPaperRecord(count++, paper.Name(), (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric()); paper.Next(); } printerFeatures.SetNumPaperSizeRecords(count); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ } PRBool hasSpoolerCmd = (nsPSPrinterList::kTypePS == nsPSPrinterList::GetPrinterType(fullPrinterName)); #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd); printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd); /* Postscript module does not pass the job title to lpr */ printerFeatures.SetSupportsJobTitleChange(PR_FALSE); printerFeatures.SetCanChangeJobTitle(PR_FALSE); /* Postscript module has no control over builtin fonts yet */ printerFeatures.SetSupportsDownloadFontsChange(PR_FALSE); printerFeatures.SetCanChangeDownloadFonts(PR_FALSE); /* Postscript module does not support multiple colorspaces * so it has to use the old way */ printerFeatures.SetSupportsPrintInColorChange(PR_TRUE); printerFeatures.SetCanChangePrintInColor(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ if (hasSpoolerCmd) { nsXPIDLCString command; if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "print_command", getter_Copies(command)))) { DO_PR_DEBUG_LOG(("setting default print command to '%s'\n", command.get())); aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUCS2(command).get()); } } #ifdef SET_PRINTER_FEATURES_VIA_PREFS printerFeatures.SetCanChangeNumCopies(PR_TRUE); #endif /* SET_PRINTER_FEATURES_VIA_PREFS */ return NS_OK; } #endif /* USE_POSTSCRIPT */ return NS_ERROR_UNEXPECTED; } NS_IMETHODIMP nsPrinterEnumeratorGTK::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings *aPrintSettings) { return NS_OK; } //---------------------------------------------------------------------- //String array enumeration callback to append a printer to the global //printer list. static PRBool GlobalPrinterEnumFunc(nsCString& aName, void *aData) { nsStringArray *a = (nsStringArray *)aData; a->AppendString(NS_ConvertUTF8toUTF16(aName)); return PR_TRUE; } //---------------------------------------------------------------------- nsresult GlobalPrinters::InitializeGlobalPrinters () { if (PrintersAreAllocated()) { return NS_OK; } mGlobalPrinterList = new nsStringArray(); if (!mGlobalPrinterList) return NS_ERROR_OUT_OF_MEMORY; nsresult rv; nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); if (NS_FAILED(rv)) return rv; #ifdef USE_XPRINT int printerCount; XPPrinterList plist = XpuGetPrinterList(nsnull, &printerCount); if (plist) { int i; for( i = 0 ; i < printerCount ; i++ ) { /* Add name to our list of printers... */ mGlobalPrinterList->AppendString(nsString(NS_ConvertUTF8toUCS2(plist[i].name))); /* ... and store the description text for this printer */ pPrefs->SetCharPref(nsPrintfCString(256, "print.printer_%s.printer_description", plist[i].name).get(), plist[i].desc); } XpuFreePrinterList(plist); } #endif /* USE_XPRINT */ #ifdef USE_POSTSCRIPT nsPSPrinterList psMgr; if (NS_SUCCEEDED(psMgr.Init()) && psMgr.Enabled()) { /* Get the list of PostScript-module printers */ nsCStringArray printerList; psMgr.GetPrinterList(printerList); printerList.EnumerateForwards(GlobalPrinterEnumFunc, mGlobalPrinterList); } #endif /* USE_POSTSCRIPT */ /* If there are no printers available after all checks, return an error */ if (!mGlobalPrinterList->Count()) { /* Make sure we do not cache an empty printer list */ FreeGlobalPrinters(); #ifdef USE_XPRINT /* Check if there are actually any Xprint servers available */ if (!XpuXprintServersAvailable()) { return NS_ERROR_GFX_PRINTER_XPRINT_NO_XPRINT_SERVERS_FOUND; } #endif /* USE_XPRINT */ return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE; } return NS_OK; } //---------------------------------------------------------------------- void GlobalPrinters::FreeGlobalPrinters() { if (mGlobalPrinterList) { delete mGlobalPrinterList; mGlobalPrinterList = nsnull; } } void GlobalPrinters::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName) { *aDefaultPrinterName = nsnull; PRBool allocate = (GlobalPrinters::GetInstance()->PrintersAreAllocated() == PR_FALSE); if (allocate) { nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); if (NS_FAILED(rv)) { return; } } NS_ASSERTION(GlobalPrinters::GetInstance()->PrintersAreAllocated(), "no GlobalPrinters"); if (GlobalPrinters::GetInstance()->GetNumPrinters() == 0) return; *aDefaultPrinterName = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(0)); if (allocate) { GlobalPrinters::GetInstance()->FreeGlobalPrinters(); } }