Back to index

lightning-sunbird  0.9+nobinonly
nsDeviceContextSpecB.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  *
00025  * Alternatively, the contents of this file may be used under the terms of
00026  * either of the GNU General Public License Version 2 or later (the "GPL"),
00027  * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
00028  * in which case the provisions of the GPL or the LGPL are applicable instead
00029  * of those above. If you wish to allow use of your version of this file only
00030  * under the terms of either the GPL or the LGPL, and not to allow others to
00031  * use your version of this file under the terms of the MPL, indicate your
00032  * decision by deleting the provisions above and replace them with the notice
00033  * and other provisions required by the GPL or the LGPL. If you do not delete
00034  * the provisions above, a recipient may use your version of this file under
00035  * the terms of any one of the MPL, the GPL or the LGPL.
00036  *
00037  * ***** END LICENSE BLOCK ***** */
00038 
00039 #include "nsDeviceContextSpecB.h"
00040  
00041 #include "nsIPref.h" 
00042 #include "prenv.h" /* for PR_GetEnv */ 
00043 #include "nsIServiceManager.h"
00044 #include "nsReadableUtils.h"
00045 #include "nsCRT.h"
00046 
00047 //----------------------------------------------------------------------------------
00048 // The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecG
00049 // The PrinterEnumerator creates the printer info
00050 // but the nsDeviceContextSpecG cleans it up
00051 // If it gets created (via the Page Setup Dialog) but the user never prints anything
00052 // then it will never be delete, so this class takes care of that.
00053 class GlobalPrinters {
00054 public:
00055   static GlobalPrinters* GetInstance()   { return &mGlobalPrinters; }
00056   ~GlobalPrinters()                      { FreeGlobalPrinters(); }
00057 
00058   void      FreeGlobalPrinters();
00059   nsresult  InitializeGlobalPrinters();
00060 
00061   PRBool    PrintersAreAllocated()       { return mGlobalPrinterList != nsnull; }
00062   PRInt32   GetNumPrinters()             { return mGlobalNumPrinters; }
00063   nsString* GetStringAt(PRInt32 aInx)    { return mGlobalPrinterList->StringAt(aInx); }
00064 
00065 protected:
00066   GlobalPrinters() {}
00067 
00068   static GlobalPrinters mGlobalPrinters;
00069   static nsStringArray* mGlobalPrinterList;
00070   static int            mGlobalNumPrinters;
00071 
00072 };
00073 //---------------
00074 // static members
00075 GlobalPrinters GlobalPrinters::mGlobalPrinters;
00076 nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull;
00077 int            GlobalPrinters::mGlobalNumPrinters = 0;
00078 
00083 nsDeviceContextSpecBeOS :: nsDeviceContextSpecBeOS()
00084 {
00085 }
00086 
00091 nsDeviceContextSpecBeOS :: ~nsDeviceContextSpecBeOS()
00092 {
00093 } 
00094  
00095 static NS_DEFINE_IID(kIDeviceContextSpecIID, NS_IDEVICE_CONTEXT_SPEC_IID); 
00096 #ifdef USE_POSTSCRIPT
00097 static NS_DEFINE_IID(kIDeviceContextSpecPSIID, NS_IDEVICE_CONTEXT_SPEC_PS_IID); 
00098 #endif /* USE_POSTSCRIPT */
00099  
00100 #if 0 
00101 NS_IMPL_ISUPPORTS1(nsDeviceContextSpecBeOS, nsIDeviceContextSpec)
00102 #endif 
00103  
00104 NS_IMETHODIMP nsDeviceContextSpecBeOS :: QueryInterface(REFNSIID aIID, void** aInstancePtr) 
00105 { 
00106   if (nsnull == aInstancePtr) 
00107     return NS_ERROR_NULL_POINTER; 
00108 
00109   if (aIID.Equals(kIDeviceContextSpecIID)) 
00110   { 
00111     nsIDeviceContextSpec* tmp = this; 
00112     *aInstancePtr = (void*) tmp; 
00113     NS_ADDREF_THIS(); 
00114     return NS_OK; 
00115   } 
00116  
00117 #ifdef USE_POSTSCRIPT
00118   if (aIID.Equals(kIDeviceContextSpecPSIID)) 
00119   { 
00120     nsIDeviceContextSpecPS* tmp = this; 
00121     *aInstancePtr = (void*) tmp; 
00122     NS_ADDREF_THIS(); 
00123     return NS_OK; 
00124   }
00125 #endif /* USE_POSTSCRIPT */
00126 
00127   static NS_DEFINE_IID(kISupportsIID, NS_ISUPPORTS_IID);
00128 
00129   if (aIID.Equals(kISupportsIID)) 
00130   { 
00131     nsIDeviceContextSpec* tmp = this; 
00132     nsISupports* tmp2 = tmp; 
00133     *aInstancePtr = (void*) tmp2; 
00134     NS_ADDREF_THIS(); 
00135     return NS_OK; 
00136   } 
00137  
00138   return NS_NOINTERFACE; 
00139 } 
00140  
00141 NS_IMPL_ADDREF(nsDeviceContextSpecBeOS)
00142 NS_IMPL_RELEASE(nsDeviceContextSpecBeOS)
00143 
00149 NS_IMETHODIMP nsDeviceContextSpecBeOS::Init(nsIPrintSettings* aPS)
00150 {
00151   nsresult rv = NS_ERROR_FAILURE;
00152   NS_ASSERTION(nsnull != aPS, "No print settings.");
00153 
00154   mPrintSettings = aPS;
00155   
00156   // if there is a current selection then enable the "Selection" radio button
00157   if (aPS != nsnull) {
00158     PRBool isOn;
00159     aPS->GetPrintOptions(nsIPrintSettings::kEnableSelectionRB, &isOn);
00160     nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
00161     if (NS_SUCCEEDED(rv)) {
00162       (void) pPrefs->SetBoolPref("print.selection_radio_enabled", isOn);
00163     }
00164   }
00165 
00166   char      *path;
00167   PRBool     reversed       = PR_FALSE;
00168   PRBool     color          = PR_FALSE;
00169   PRBool     tofile         = PR_FALSE;
00170   PRInt16    printRange     = nsIPrintSettings::kRangeAllPages;
00171   PRInt32    paper_size     = NS_LETTER_SIZE;
00172   PRInt32    orientation    = NS_PORTRAIT;
00173   PRInt32    fromPage       = 1;
00174   PRInt32    toPage         = 1;
00175   PRUnichar *command        = nsnull;
00176   PRInt32    copies         = 1;
00177   PRUnichar *printer        = nsnull;
00178   PRUnichar *printfile      = nsnull;
00179   double     dleft          = 0.5;
00180   double     dright         = 0.5;
00181   double     dtop           = 0.5;
00182   double     dbottom        = 0.5; 
00183 
00184   rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
00185   if (NS_FAILED(rv)) {
00186     return rv;
00187   }
00188 
00189   
00190   GlobalPrinters::GetInstance()->FreeGlobalPrinters();
00191 
00192   if (aPS != nsnull) {
00193     aPS->GetPrinterName(&printer);
00194     aPS->GetPrintReversed(&reversed);
00195     aPS->GetPrintInColor(&color);
00196     aPS->GetPaperSize(&paper_size);
00197     aPS->GetOrientation(&orientation);
00198     aPS->GetPrintCommand(&command);
00199     aPS->GetPrintRange(&printRange);
00200     aPS->GetToFileName(&printfile);
00201     aPS->GetPrintToFile(&tofile);
00202     aPS->GetStartPageRange(&fromPage);
00203     aPS->GetEndPageRange(&toPage);
00204     aPS->GetNumCopies(&copies);
00205     aPS->GetMarginTop(&dtop);
00206     aPS->GetMarginLeft(&dleft);
00207     aPS->GetMarginBottom(&dbottom);
00208     aPS->GetMarginRight(&dright);
00209 
00210     if (command != nsnull && printfile != nsnull) {
00211       // ToDo: Use LocalEncoding instead of UTF-8 (see bug 73446)
00212       strcpy(mPrData.command, NS_ConvertUCS2toUTF8(command).get());  
00213       strcpy(mPrData.path,    NS_ConvertUCS2toUTF8(printfile).get());
00214     }
00215     if (printer != nsnull) 
00216       strcpy(mPrData.printer, NS_ConvertUCS2toUTF8(printer).get());        
00217 #ifdef DEBUG_rods
00218     printf("margins:       %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright);
00219     printf("printRange     %d\n", printRange);
00220     printf("fromPage       %d\n", fromPage);
00221     printf("toPage         %d\n", toPage);
00222 #endif /* DEBUG_rods */
00223   } else {
00224 #ifdef VMS
00225     // Note to whoever puts the "lpr" into the prefs file. Please contact me
00226     // as I need to make the default be "print" instead of "lpr" for OpenVMS.
00227     strcpy(mPrData.command, "print");
00228 #else
00229     strcpy(mPrData.command, "lpr ${MOZ_PRINTER_NAME:+'-P'}${MOZ_PRINTER_NAME}");
00230 #endif /* VMS */
00231   }
00232 
00233   mPrData.top       = dtop;
00234   mPrData.bottom    = dbottom;
00235   mPrData.left      = dleft;
00236   mPrData.right     = dright;
00237   mPrData.fpf       = !reversed;
00238   mPrData.grayscale = !color;
00239   mPrData.size      = paper_size;
00240   mPrData.orientation = orientation;
00241   mPrData.toPrinter = !tofile;
00242   mPrData.copies = copies;
00243 
00244   // PWD, HOME, or fail 
00245   
00246   if (!printfile) {
00247     if ( ( path = PR_GetEnv( "PWD" ) ) == (char *) nsnull ) 
00248       if ( ( path = PR_GetEnv( "HOME" ) ) == (char *) nsnull )
00249         strcpy(mPrData.path, "mozilla.ps");
00250         
00251     if ( path != (char *) nsnull )
00252       sprintf(mPrData.path, "%s/mozilla.ps", path);
00253     else
00254       return NS_ERROR_FAILURE;
00255   }
00256   
00257 #ifdef NOT_IMPLEMENTED_YET
00258   if (mGlobalNumPrinters) {
00259      for(int i = 0; (i < mGlobalNumPrinters) && !mQueue; i++) {
00260         if (!(mGlobalPrinterList->StringAt(i)->EqualsIgnoreCase(mPrData.printer)))
00261            mQueue = PrnDlg.SetPrinterQueue(i);
00262      }
00263   }
00264 #endif /* NOT_IMPLEMENTED_YET */
00265   
00266   if (command != nsnull) {
00267     nsMemory::Free(command);
00268   }
00269   if (printfile != nsnull) {
00270     nsMemory::Free(printfile);
00271   }
00272 
00273   return rv;
00274 }
00275  
00276 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetToPrinter( PRBool &aToPrinter )     
00277 { 
00278   aToPrinter = mPrData.toPrinter;
00279         return NS_OK;
00280 } 
00281 
00282 NS_IMETHODIMP nsDeviceContextSpecBeOS::GetPrinterName ( const char **aPrinter )
00283 {
00284    *aPrinter = &mPrData.printer[0];
00285    return NS_OK;
00286 }
00287 
00288 NS_IMETHODIMP nsDeviceContextSpecBeOS::GetCopies ( int &aCopies )
00289 {
00290    aCopies = mPrData.copies;
00291    return NS_OK;
00292 }
00293  
00294 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetFirstPageFirst ( PRBool &aFpf )      
00295 { 
00296   aFpf = mPrData.fpf; 
00297   return NS_OK; 
00298 } 
00299  
00300 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetGrayscale ( PRBool &aGrayscale )      
00301 { 
00302   aGrayscale = mPrData.grayscale; 
00303   return NS_OK; 
00304 } 
00305  
00306 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetSize ( int &aSize )      
00307 { 
00308   aSize = mPrData.size; 
00309   return NS_OK; 
00310 } 
00311  
00312 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetPageDimensions ( float &aWidth, float &aHeight )      
00313 { 
00314     if ( mPrData.size == NS_LETTER_SIZE ) { 
00315         aWidth = 8.5; 
00316         aHeight = 11.0; 
00317     } else if ( mPrData.size == NS_LEGAL_SIZE ) { 
00318         aWidth = 8.5; 
00319         aHeight = 14.0; 
00320     } else if ( mPrData.size == NS_EXECUTIVE_SIZE ) { 
00321         aWidth = 7.5; 
00322         aHeight = 10.0; 
00323     } else if ( mPrData.size == NS_A4_SIZE ) { 
00324         // 210mm X 297mm == 8.27in X 11.69in 
00325         aWidth = 8.27; 
00326         aHeight = 11.69; 
00327     } else if ( mPrData.size == NS_A3_SIZE ) {
00328         // 297mm X 420mm == 11.69in X 16.53in
00329         aWidth = 11.69;
00330         aHeight = 16.53;
00331     } 
00332 
00333     if (mPrData.orientation == NS_LANDSCAPE) {
00334       float temp;
00335       temp = aWidth;
00336       aWidth = aHeight;
00337       aHeight = temp;
00338     }
00339 
00340     return NS_OK; 
00341 } 
00342  
00343 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetLandscape ( PRBool &landscape )      
00344 { 
00345   landscape = (mPrData.orientation == NS_LANDSCAPE);
00346   return NS_OK; 
00347 } 
00348  
00349 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetTopMargin ( float &value )      
00350 { 
00351   value = mPrData.top; 
00352   return NS_OK; 
00353 } 
00354  
00355 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetBottomMargin ( float &value )      
00356 { 
00357   value = mPrData.bottom; 
00358   return NS_OK; 
00359 } 
00360  
00361 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetRightMargin ( float &value )      
00362 { 
00363   value = mPrData.right; 
00364   return NS_OK; 
00365 } 
00366  
00367 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetLeftMargin ( float &value )      
00368 { 
00369   value = mPrData.left; 
00370   return NS_OK; 
00371 } 
00372  
00373 NS_IMETHODIMP nsDeviceContextSpecBeOS::GetCommand ( const char **aCommand )      
00374 { 
00375   *aCommand = &mPrData.command[0]; 
00376   return NS_OK; 
00377 } 
00378  
00379 NS_IMETHODIMP nsDeviceContextSpecBeOS::GetPath ( const char **aPath )      
00380 { 
00381   *aPath = &mPrData.path[0]; 
00382   return NS_OK; 
00383 } 
00384  
00385 NS_IMETHODIMP nsDeviceContextSpecBeOS :: GetUserCancelled( PRBool &aCancel )     
00386 { 
00387   aCancel = mPrData.cancel; 
00388   return NS_OK;
00389 }
00390 
00395 NS_IMETHODIMP nsDeviceContextSpecBeOS :: ClosePrintManager()
00396 {
00397   return NS_OK;
00398 }  
00399 
00400 NS_IMETHODIMP nsDeviceContextSpecBeOS::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight)
00401 {
00402   return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight);
00403 }
00404 
00405 //  Printer Enumerator
00406 nsPrinterEnumeratorBeOS::nsPrinterEnumeratorBeOS()
00407 {
00408 }
00409 
00410 NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorBeOS, nsIPrinterEnumerator)
00411 
00412 NS_IMETHODIMP nsPrinterEnumeratorBeOS::EnumeratePrinters(PRUint32* aCount, PRUnichar*** aResult)
00413 {
00414   NS_ENSURE_ARG(aCount);
00415   NS_ENSURE_ARG_POINTER(aResult);
00416 
00417   if (aCount) 
00418     *aCount = 0;
00419   else 
00420     return NS_ERROR_NULL_POINTER;
00421   
00422   if (aResult) 
00423     *aResult = nsnull;
00424   else 
00425     return NS_ERROR_NULL_POINTER;
00426   
00427   nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
00428   if (NS_FAILED(rv)) {
00429     return rv;
00430   }
00431 
00432   PRInt32 numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters();
00433 
00434   PRUnichar** array = (PRUnichar**) nsMemory::Alloc(numPrinters * sizeof(PRUnichar*));
00435   if (!array && numPrinters > 0) {
00436     GlobalPrinters::GetInstance()->FreeGlobalPrinters();
00437     return NS_ERROR_OUT_OF_MEMORY;
00438   }
00439   
00440   int count = 0;
00441   while( count < numPrinters )
00442   {
00443 
00444     PRUnichar *str = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(count));
00445 
00446     if (!str) {
00447       for (int i = count - 1; i >= 0; i--) 
00448         nsMemory::Free(array[i]);
00449       
00450       nsMemory::Free(array);
00451 
00452       GlobalPrinters::GetInstance()->FreeGlobalPrinters();
00453       return NS_ERROR_OUT_OF_MEMORY;
00454     }
00455     array[count++] = str;
00456     
00457   }
00458   *aCount = count;
00459   *aResult = array;
00460   GlobalPrinters::GetInstance()->FreeGlobalPrinters();
00461 
00462   return NS_OK;
00463 }
00464 
00465 /* readonly attribute wstring defaultPrinterName; */
00466 NS_IMETHODIMP nsPrinterEnumeratorBeOS::GetDefaultPrinterName(PRUnichar * *aDefaultPrinterName)
00467 {
00468   NS_ENSURE_ARG_POINTER(aDefaultPrinterName);
00469   *aDefaultPrinterName = nsnull;
00470   return NS_OK;
00471 }
00472 
00473 /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */
00474 NS_IMETHODIMP nsPrinterEnumeratorBeOS::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings)
00475 {
00476     return NS_OK;
00477 }
00478 
00479 NS_IMETHODIMP nsPrinterEnumeratorBeOS::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings *aPrintSettings)
00480 {
00481   return NS_OK;
00482 }
00483 
00484 //----------------------------------------------------------------------
00485 nsresult GlobalPrinters::InitializeGlobalPrinters ()
00486 {
00487   if (PrintersAreAllocated())
00488     return NS_OK;
00489 
00490   mGlobalNumPrinters = 0;
00491 
00492 #ifdef USE_POSTSCRIPT
00493   mGlobalPrinterList = new nsStringArray();
00494   if (!mGlobalPrinterList) 
00495     return NS_ERROR_OUT_OF_MEMORY;
00496 
00497   /* add an entry for the default printer (see nsPostScriptObj.cpp) */
00498   mGlobalPrinterList->AppendString(
00499     nsString(NS_ConvertASCIItoUCS2(NS_POSTSCRIPT_DRIVER_NAME "default")));
00500   mGlobalNumPrinters++;
00501 
00502   /* get the list of printers */
00503   char *printerList = nsnull;
00504   
00505   /* the env var MOZILLA_PRINTER_LIST can "override" the prefs */
00506   printerList = PR_GetEnv("MOZILLA_PRINTER_LIST");
00507   
00508   if (!printerList) {
00509     nsresult rv;
00510     nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
00511     if (NS_SUCCEEDED(rv)) {
00512       (void) pPrefs->CopyCharPref("print.printer_list", &printerList);
00513     }
00514   }  
00515 
00516   if (printerList) {
00517     char *tok_lasts;
00518     char *name;
00519     
00520     /* PL_strtok_r() will modify the string - copy it! */
00521     printerList = strdup(printerList);
00522     if (!printerList)
00523       return NS_ERROR_OUT_OF_MEMORY;    
00524 
00525     for( name = PL_strtok_r(printerList, " ", &tok_lasts) ; 
00526          name != nsnull ; 
00527          name = PL_strtok_r(nsnull, " ", &tok_lasts) )
00528     {
00529       mGlobalPrinterList->AppendString(
00530         nsString(NS_ConvertASCIItoUCS2(NS_POSTSCRIPT_DRIVER_NAME)) + 
00531         nsString(NS_ConvertASCIItoUCS2(name)));
00532       mGlobalNumPrinters++;      
00533     }
00534 
00535     free(printerList);
00536   }
00537 #endif /* USE_POSTSCRIPT */
00538       
00539   if (mGlobalNumPrinters == 0)
00540     return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE; 
00541 
00542   return NS_OK;
00543 }
00544 
00545 //----------------------------------------------------------------------
00546 void GlobalPrinters::FreeGlobalPrinters()
00547 {
00548   delete mGlobalPrinterList;
00549   mGlobalPrinterList = nsnull;
00550   mGlobalNumPrinters = 0;
00551 }
00552 
00553 
00554 
00555