/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */ /* ***** BEGIN LICENSE BLOCK ***** * Version: NPL 1.1/GPL 2.0/LGPL 2.1 * * The contents of this file are subject to the Netscape 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/NPL/ * * 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 * * * Alternatively, the contents of this file may be used under the terms of * either 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 NPL, 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 NPL, the GPL or the LGPL. * * ***** END LICENSE BLOCK ***** */ #include "nsDeviceContextSpecB.h" #include "nsIPref.h" #include "prenv.h" /* for PR_GetEnv */ #include "nsIServiceManager.h" #include "nsReadableUtils.h" #include "nsCRT.h" //---------------------------------------------------------------------------------- // The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecG // The PrinterEnumerator creates the printer info // but the nsDeviceContextSpecG 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 mGlobalNumPrinters; } nsString* GetStringAt(PRInt32 aInx) { return mGlobalPrinterList->StringAt(aInx); } protected: GlobalPrinters() {} static GlobalPrinters mGlobalPrinters; static nsStringArray* mGlobalPrinterList; static int mGlobalNumPrinters; }; //--------------- // static members GlobalPrinters GlobalPrinters::mGlobalPrinters; nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull; int GlobalPrinters::mGlobalNumPrinters = 0; /** ------------------------------------------------------- * Construct the nsDeviceContextSpecBeOS * @update dc 12/02/98 */ nsDeviceContextSpecBeOS :: nsDeviceContextSpecBeOS() { } /** ------------------------------------------------------- * Destroy the nsDeviceContextSpecBeOS * @update dc 2/15/98 */ nsDeviceContextSpecBeOS :: ~nsDeviceContextSpecBeOS() { } static NS_DEFINE_IID(kIDeviceContextSpecIID, NS_IDEVICE_CONTEXT_SPEC_IID); #ifdef USE_POSTSCRIPT static NS_DEFINE_IID(kIDeviceContextSpecPSIID, NS_IDEVICE_CONTEXT_SPEC_PS_IID); #endif /* USE_POSTSCRIPT */ #if 0 NS_IMPL_ISUPPORTS1(nsDeviceContextSpecBeOS, nsIDeviceContextSpec) #endif NS_IMETHODIMP nsDeviceContextSpecBeOS :: QueryInterface(REFNSIID aIID, void** aInstancePtr) { if (nsnull == aInstancePtr) return NS_ERROR_NULL_POINTER; if (aIID.Equals(kIDeviceContextSpecIID)) { nsIDeviceContextSpec* tmp = this; *aInstancePtr = (void*) tmp; NS_ADDREF_THIS(); return NS_OK; } #ifdef USE_POSTSCRIPT if (aIID.Equals(kIDeviceContextSpecPSIID)) { nsIDeviceContextSpecPS* tmp = this; *aInstancePtr = (void*) tmp; NS_ADDREF_THIS(); return NS_OK; } #endif /* USE_POSTSCRIPT */ static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID); if (aIID.Equals(kISupportsIID)) { nsIDeviceContextSpec* tmp = this; nsISupports* tmp2 = tmp; *aInstancePtr = (void*) tmp2; NS_ADDREF_THIS(); return NS_OK; } return NS_NOINTERFACE; } NS_IMPL_ADDREF(nsDeviceContextSpecBeOS) NS_IMPL_RELEASE(nsDeviceContextSpecBeOS) /** ------------------------------------------------------- * Initialize the nsDeviceContextSpecBeOS * @update dc 2/15/98 * @update syd 3/2/99 */ NS_IMETHODIMP nsDeviceContextSpecBeOS::Init(nsIPrintSettings* aPS) { nsresult rv = NS_ERROR_FAILURE; NS_ASSERTION(nsnull != aPS, "No print settings."); mPrintSettings = aPS; // if there is a current selection then enable the "Selection" radio button if (aPS != nsnull) { PRBool isOn; aPS->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn); nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { (void) pPrefs->SetBoolPref("print.selection_radio_enabled", isOn); } } char *path; PRBool reversed = PR_FALSE; PRBool color = PR_FALSE; PRBool tofile = PR_FALSE; PRInt16 printRange = nsIPrintSettings::kRangeAllPages; PRInt32 paper_size = NS_LETTER_SIZE; PRInt32 orientation = NS_PORTRAIT; PRInt32 fromPage = 1; PRInt32 toPage = 1; PRUnichar *command = nsnull; PRInt32 copies = 1; PRUnichar *printer = nsnull; PRUnichar *printfile = nsnull; double dleft = 0.5; double dright = 0.5; double dtop = 0.5; double dbottom = 0.5; rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters(); if (NS_FAILED(rv)) { return rv; } GlobalPrinters::GetInstance()->FreeGlobalPrinters(); if (aPS != nsnull) { aPS->GetPrinterName(&printer); aPS->GetPrintReversed(&reversed); aPS->GetPrintInColor(&color); aPS->GetPaperSize(&paper_size); 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 (command != nsnull && printfile != nsnull) { // ToDo: Use LocalEncoding instead of UTF-8 (see bug 73446) strcpy(mPrData.command, NS_ConvertUCS2toUTF8(command).get()); strcpy(mPrData.path, NS_ConvertUCS2toUTF8(printfile).get()); } if (printer != nsnull) strcpy(mPrData.printer, NS_ConvertUCS2toUTF8(printer).get()); #ifdef DEBUG_rods printf("margins: %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright); printf("printRange %d\n", printRange); printf("fromPage %d\n", fromPage); printf("toPage %d\n", toPage); #endif /* DEBUG_rods */ } else { #ifdef VMS // Note to whoever puts the "lpr" into the prefs file. Please contact me // as I need to make the default be "print" instead of "lpr" for OpenVMS. strcpy(mPrData.command, "print"); #else strcpy(mPrData.command, "lpr ${MOZ_PRINTER_NAME:+'-P'}${MOZ_PRINTER_NAME}"); #endif /* VMS */ } mPrData.top = dtop; mPrData.bottom = dbottom; mPrData.left = dleft; mPrData.right = dright; mPrData.fpf = !reversed; mPrData.grayscale = !color; mPrData.size = paper_size; mPrData.orientation = orientation; mPrData.toPrinter = !tofile; mPrData.copies = copies; // PWD, HOME, or fail if (!printfile) { if ( ( path = PR_GetEnv( "PWD" ) ) == (char *) nsnull ) if ( ( path = PR_GetEnv( "HOME" ) ) == (char *) nsnull ) strcpy(mPrData.path, "mozilla.ps"); if ( path != (char *) nsnull ) sprintf(mPrData.path, "%s/mozilla.ps", path); else return NS_ERROR_FAILURE; } #ifdef NOT_IMPLEMENTED_YET if (mGlobalNumPrinters) { for(int i = 0; (i < mGlobalNumPrinters) && !mQueue; i++) { if (!(mGlobalPrinterList->StringAt(i)->CompareWithConversion(mPrData.printer, TRUE, -1))) mQueue = PrnDlg.SetPrinterQueue(i); } } #endif /* NOT_IMPLEMENTED_YET */ if (command != nsnull) { nsMemory::Free(command); } if (printfile != nsnull) { nsMemory::Free(printfile); } return rv; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetToPrinter( PRBool &aToPrinter ) { aToPrinter = mPrData.toPrinter; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS::GetPrinterName ( const char **aPrinter ) { *aPrinter = &mPrData.printer[0]; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS::GetCopies ( int &aCopies ) { aCopies = mPrData.copies; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetFirstPageFirst ( PRBool &aFpf ) { aFpf = mPrData.fpf; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetGrayscale ( PRBool &aGrayscale ) { aGrayscale = mPrData.grayscale; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetSize ( int &aSize ) { aSize = mPrData.size; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetPageDimensions ( float &aWidth, float &aHeight ) { if ( mPrData.size == NS_LETTER_SIZE ) { aWidth = 8.5; aHeight = 11.0; } else if ( mPrData.size == NS_LEGAL_SIZE ) { aWidth = 8.5; aHeight = 14.0; } else if ( mPrData.size == NS_EXECUTIVE_SIZE ) { aWidth = 7.5; aHeight = 10.0; } else if ( mPrData.size == NS_A4_SIZE ) { // 210mm X 297mm == 8.27in X 11.69in aWidth = 8.27; aHeight = 11.69; } else if ( mPrData.size == NS_A3_SIZE ) { // 297mm X 420mm == 11.69in X 16.53in aWidth = 11.69; aHeight = 16.53; } if (mPrData.orientation == NS_LANDSCAPE) { float temp; temp = aWidth; aWidth = aHeight; aHeight = temp; } return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetLandscape ( PRBool &landscape ) { landscape = (mPrData.orientation == NS_LANDSCAPE); return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetTopMargin ( float &value ) { value = mPrData.top; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetBottomMargin ( float &value ) { value = mPrData.bottom; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetRightMargin ( float &value ) { value = mPrData.right; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetLeftMargin ( float &value ) { value = mPrData.left; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS::GetCommand ( const char **aCommand ) { *aCommand = &mPrData.command[0]; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS::GetPath ( const char **aPath ) { *aPath = &mPrData.path[0]; return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetUserCancelled( PRBool &aCancel ) { aCancel = mPrData.cancel; return NS_OK; } /** ------------------------------------------------------- * Closes the printmanager if it is open. * @update dc 2/15/98 */ NS_IMETHODIMP nsDeviceContextSpecBeOS :: ClosePrintManager() { return NS_OK; } NS_IMETHODIMP nsDeviceContextSpecBeOS::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight) { return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight); } // Printer Enumerator nsPrinterEnumeratorBeOS::nsPrinterEnumeratorBeOS() { } NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorBeOS, nsIPrinterEnumerator) NS_IMETHODIMP nsPrinterEnumeratorBeOS::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 nsPrinterEnumeratorBeOS::GetDefaultPrinterName(PRUnichar * *aDefaultPrinterName) { NS_ENSURE_ARG_POINTER(aDefaultPrinterName); *aDefaultPrinterName = nsnull; return NS_OK; } /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */ NS_IMETHODIMP nsPrinterEnumeratorBeOS::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings) { return NS_OK; } NS_IMETHODIMP nsPrinterEnumeratorBeOS::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings *aPrintSettings) { return NS_OK; } //---------------------------------------------------------------------- nsresult GlobalPrinters::InitializeGlobalPrinters () { if (PrintersAreAllocated()) return NS_OK; mGlobalNumPrinters = 0; #ifdef USE_POSTSCRIPT mGlobalPrinterList = new nsStringArray(); if (!mGlobalPrinterList) return NS_ERROR_OUT_OF_MEMORY; /* add an entry for the default printer (see nsPostScriptObj.cpp) */ mGlobalPrinterList->AppendString( nsString(NS_ConvertASCIItoUCS2(NS_POSTSCRIPT_DRIVER_NAME "default"))); mGlobalNumPrinters++; /* get the list of printers */ char *printerList = nsnull; /* the env var MOZILLA_PRINTER_LIST can "override" the prefs */ printerList = PR_GetEnv("MOZILLA_PRINTER_LIST"); if (!printerList) { nsresult rv; nsCOMPtr pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv); if (NS_SUCCEEDED(rv)) { (void) pPrefs->CopyCharPref("print.printer_list", &printerList); } } if (printerList) { char *tok_lasts; char *name; /* PL_strtok_r() will modify the string - copy it! */ printerList = strdup(printerList); if (!printerList) return NS_ERROR_OUT_OF_MEMORY; for( name = PL_strtok_r(printerList, " ", &tok_lasts) ; name != nsnull ; name = PL_strtok_r(nsnull, " ", &tok_lasts) ) { mGlobalPrinterList->AppendString( nsString(NS_ConvertASCIItoUCS2(NS_POSTSCRIPT_DRIVER_NAME)) + nsString(NS_ConvertASCIItoUCS2(name))); mGlobalNumPrinters++; } free(printerList); } #endif /* USE_POSTSCRIPT */ if (mGlobalNumPrinters == 0) return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE; return NS_OK; } //---------------------------------------------------------------------- void GlobalPrinters::FreeGlobalPrinters() { delete mGlobalPrinterList; mGlobalPrinterList = nsnull; mGlobalNumPrinters = 0; }