2006-02-07 01:12:56 +00:00
/* -*- 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
1998-11-14 02:05:13 +00:00
*
2006-02-07 01:12:56 +00:00
* 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/
1998-11-14 02:05:13 +00:00
*
2006-02-07 01:12:56 +00:00
* 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 .
1998-11-14 02:05:13 +00:00
*
1999-11-06 02:06:26 +00:00
* The Original Code is mozilla . org code .
*
2006-02-07 01:12:56 +00:00
* 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 .
1999-11-06 02:06:26 +00:00
*
2006-02-07 01:12:56 +00:00
* Contributor ( s ) :
*
*
* 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 * * * * * */
1998-11-14 02:05:13 +00:00
# include "nsDeviceContextSpecWin.h"
# include "prmem.h"
2006-02-07 01:13:53 +00:00
# include <winspool.h>
2006-02-07 01:14:31 +00:00
# include <tchar.h>
2006-02-07 01:13:21 +00:00
2006-02-07 01:13:12 +00:00
# include "nsVoidArray.h"
2006-02-07 01:13:53 +00:00
# include "nsIPrintSettingsWin.h"
2006-02-07 01:13:12 +00:00
# include "nsString.h"
2006-02-07 01:14:01 +00:00
# include "nsCRT.h"
2006-02-07 01:13:12 +00:00
# include "nsIServiceManager.h"
# include "nsReadableUtils.h"
# include "nsGfxCIID.h"
2006-02-07 01:13:53 +00:00
// File Picker
# include "nsILocalFile.h"
# include "nsIFile.h"
# include "nsIFilePicker.h"
2006-02-07 01:13:12 +00:00
# include "nsIStringBundle.h"
2006-02-07 01:14:02 +00:00
# define NS_ERROR_GFX_PRINTER_BUNDLE_URL "chrome: //global/locale/printing.properties"
2006-02-07 01:13:21 +00:00
2006-02-07 01:14:03 +00:00
# include "prlog.h"
# ifdef PR_LOGGING
2006-02-07 01:14:14 +00:00
extern PRLogModuleInfo * kGfxPrintingLogMod ;
# define PR_PL(_p1) PR_LOG(kGfxPrintingLogMod, PR_LOG_DEBUG, _p1)
2006-02-07 01:14:03 +00:00
# else
# define PR_PL(_p1)
# endif
2006-02-07 01:13:12 +00:00
//-----------------------------------------------
// Global Data
//-----------------------------------------------
static HWND gParentWnd = NULL ;
//----------------------------------------------------------------------------------
// The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecWin
// The PrinterEnumerator creates the printer info
// but the nsDeviceContextSpecWin 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 ( ) ;
2006-02-07 01:13:21 +00:00
PRBool PrintersAreAllocated ( ) { return mPrinters ! = nsnull ; }
LPTSTR GetItemFromList ( PRInt32 aInx ) { return mPrinters ? ( LPTSTR ) mPrinters - > ElementAt ( aInx ) : nsnull ; }
nsresult EnumeratePrinterList ( ) ;
void GetDefaultPrinterName ( LPTSTR & aDefaultPrinterName ) ;
PRInt32 GetNumPrinters ( ) { return mPrinters ? mPrinters - > Count ( ) : 0 ; }
2006-02-07 01:13:12 +00:00
protected :
GlobalPrinters ( ) { }
2006-02-07 01:13:21 +00:00
nsresult EnumerateNativePrinters ( ) ;
2006-02-07 01:13:12 +00:00
void ReallocatePrinters ( ) ;
static GlobalPrinters mGlobalPrinters ;
static nsVoidArray * mPrinters ;
} ;
//---------------
// static members
GlobalPrinters GlobalPrinters : : mGlobalPrinters ;
2006-02-07 01:13:21 +00:00
nsVoidArray * GlobalPrinters : : mPrinters = nsnull ;
2006-02-07 01:13:12 +00:00
//******************************************************
// Define native paper sizes
//******************************************************
typedef struct {
short mPaperSize ; // native enum
double mWidth ;
double mHeight ;
PRBool mIsInches ;
} NativePaperSizes ;
// There are around 40 default print sizes defined by Windows
const NativePaperSizes kPaperSizes [ ] = {
{ DMPAPER_LETTER , 8.5 , 11.0 , PR_TRUE } ,
{ DMPAPER_LEGAL , 8.5 , 14.0 , PR_TRUE } ,
{ DMPAPER_A4 , 210.0 , 297.0 , PR_FALSE } ,
{ DMPAPER_TABLOID , 11.0 , 17.0 , PR_TRUE } ,
{ DMPAPER_LEDGER , 17.0 , 11.0 , PR_TRUE } ,
{ DMPAPER_STATEMENT , 5.5 , 8.5 , PR_TRUE } ,
{ DMPAPER_EXECUTIVE , 7.25 , 10.5 , PR_TRUE } ,
{ DMPAPER_A3 , 297.0 , 420.0 , PR_FALSE } ,
{ DMPAPER_A5 , 148.0 , 210.0 , PR_FALSE } ,
{ DMPAPER_CSHEET , 17.0 , 22.0 , PR_TRUE } ,
{ DMPAPER_DSHEET , 22.0 , 34.0 , PR_TRUE } ,
{ DMPAPER_ESHEET , 34.0 , 44.0 , PR_TRUE } ,
{ DMPAPER_LETTERSMALL , 8.5 , 11.0 , PR_TRUE } ,
{ DMPAPER_A4SMALL , 210.0 , 297.0 , PR_FALSE } ,
{ DMPAPER_B4 , 250.0 , 354.0 , PR_FALSE } ,
{ DMPAPER_B5 , 182.0 , 257.0 , PR_FALSE } ,
{ DMPAPER_FOLIO , 8.5 , 13.0 , PR_TRUE } ,
{ DMPAPER_QUARTO , 215.0 , 275.0 , PR_FALSE } ,
{ DMPAPER_10X14 , 10.0 , 14.0 , PR_TRUE } ,
{ DMPAPER_11X17 , 11.0 , 17.0 , PR_TRUE } ,
{ DMPAPER_NOTE , 8.5 , 11.0 , PR_TRUE } ,
{ DMPAPER_ENV_9 , 3.875 , 8.875 , PR_TRUE } ,
{ DMPAPER_ENV_10 , 40.125 , 9.5 , PR_TRUE } ,
{ DMPAPER_ENV_11 , 4.5 , 10.375 , PR_TRUE } ,
{ DMPAPER_ENV_12 , 4.75 , 11.0 , PR_TRUE } ,
{ DMPAPER_ENV_14 , 5.0 , 11.5 , PR_TRUE } ,
{ DMPAPER_ENV_DL , 110.0 , 220.0 , PR_FALSE } ,
{ DMPAPER_ENV_C5 , 162.0 , 229.0 , PR_FALSE } ,
{ DMPAPER_ENV_C3 , 324.0 , 458.0 , PR_FALSE } ,
{ DMPAPER_ENV_C4 , 229.0 , 324.0 , PR_FALSE } ,
{ DMPAPER_ENV_C6 , 114.0 , 162.0 , PR_FALSE } ,
{ DMPAPER_ENV_C65 , 114.0 , 229.0 , PR_FALSE } ,
{ DMPAPER_ENV_B4 , 250.0 , 353.0 , PR_FALSE } ,
{ DMPAPER_ENV_B5 , 176.0 , 250.0 , PR_FALSE } ,
{ DMPAPER_ENV_B6 , 176.0 , 125.0 , PR_FALSE } ,
{ DMPAPER_ENV_ITALY , 110.0 , 230.0 , PR_FALSE } ,
{ DMPAPER_ENV_MONARCH , 3.875 , 7.5 , PR_TRUE } ,
{ DMPAPER_ENV_PERSONAL , 3.625 , 6.5 , PR_TRUE } ,
{ DMPAPER_FANFOLD_US , 14.875 , 11.0 , PR_TRUE } ,
{ DMPAPER_FANFOLD_STD_GERMAN , 8.5 , 12.0 , PR_TRUE } ,
{ DMPAPER_FANFOLD_LGL_GERMAN , 8.5 , 13.0 , PR_TRUE } ,
} ;
const PRInt32 kNumPaperSizes = 41 ;
//----------------------------------------------------------------------------------
2006-02-07 01:13:53 +00:00
nsDeviceContextSpecWin : : nsDeviceContextSpecWin ( )
1998-11-14 02:05:13 +00:00
{
2006-02-07 01:13:12 +00:00
mDriverName = nsnull ;
mDeviceName = nsnull ;
mDevMode = NULL ;
2006-02-07 01:13:21 +00:00
1998-11-14 02:05:13 +00:00
}
2006-02-07 01:13:12 +00:00
//----------------------------------------------------------------------------------
NS_IMPL_ISUPPORTS1 ( nsDeviceContextSpecWin , nsIDeviceContextSpec )
2006-02-07 01:13:32 +00:00
nsDeviceContextSpecWin : : ~ nsDeviceContextSpecWin ( )
1998-11-14 02:05:13 +00:00
{
2006-02-07 01:13:12 +00:00
SetDeviceName ( nsnull ) ;
SetDriverName ( nsnull ) ;
SetDevMode ( NULL ) ;
2006-02-07 01:13:54 +00:00
nsCOMPtr < nsIPrintSettingsWin > psWin ( do_QueryInterface ( mPrintSettings ) ) ;
if ( psWin ) {
psWin - > SetDeviceName ( nsnull ) ;
psWin - > SetDriverName ( nsnull ) ;
psWin - > SetDevMode ( NULL ) ;
}
2006-02-07 01:13:12 +00:00
// Free them, we won't need them for a while
GlobalPrinters : : GetInstance ( ) - > FreeGlobalPrinters ( ) ;
}
2006-02-07 01:13:53 +00:00
//------------------------------------------------------------------
// helper
static PRUnichar * GetDefaultPrinterNameFromGlobalPrinters ( )
2006-02-07 01:13:50 +00:00
{
2006-02-07 01:13:53 +00:00
PRUnichar * printerName ;
LPTSTR lpPrtName ;
GlobalPrinters : : GetInstance ( ) - > GetDefaultPrinterName ( lpPrtName ) ;
nsString str ;
# ifdef UNICODE
str . AppendWithConversion ( ( PRUnichar * ) lpPrtName ) ;
# else
str . AssignWithConversion ( ( char * ) lpPrtName ) ;
2006-02-07 01:13:51 +00:00
# endif
2006-02-07 01:13:53 +00:00
printerName = ToNewUnicode ( str ) ;
free ( lpPrtName ) ;
return printerName ;
}
1998-11-14 02:05:13 +00:00
2006-02-07 01:13:53 +00:00
//----------------------------------------------------------------
static nsresult
EnumerateNativePrinters ( DWORD aWhichPrinters , LPTSTR aPrinterName , PRBool & aIsFound , PRBool & aIsFile )
{
2006-02-07 01:14:13 +00:00
DWORD dwSizeNeeded = 0 ;
DWORD dwNumItems = 0 ;
LPPRINTER_INFO_2 lpInfo = NULL ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:53 +00:00
// Get buffer size
2006-02-07 01:14:13 +00:00
if ( : : EnumPrinters ( aWhichPrinters , NULL , 2 , NULL , 0 , & dwSizeNeeded , & dwNumItems ) ) {
return NS_ERROR_FAILURE ;
}
2006-02-07 01:13:50 +00:00
2006-02-07 01:13:53 +00:00
// allocate memory
lpInfo = ( LPPRINTER_INFO_2 ) HeapAlloc ( GetProcessHeap ( ) , HEAP_ZERO_MEMORY , dwSizeNeeded ) ;
if ( lpInfo = = NULL ) {
return NS_ERROR_OUT_OF_MEMORY ;
2006-02-07 01:13:50 +00:00
}
2006-02-07 01:13:53 +00:00
if ( : : EnumPrinters ( PRINTER_ENUM_LOCAL , NULL , 2 , ( LPBYTE ) lpInfo , dwSizeNeeded , & dwSizeNeeded , & dwNumItems ) = = 0 ) {
2006-02-07 01:14:13 +00:00
: : HeapFree ( GetProcessHeap ( ) , 0 , lpInfo ) ;
2006-02-07 01:13:53 +00:00
return NS_OK ;
}
2006-02-07 01:13:51 +00:00
2006-02-07 01:13:53 +00:00
for ( DWORD i = 0 ; i < dwNumItems ; i + + ) {
2006-02-07 01:13:59 +00:00
if ( _tcscmp ( lpInfo [ i ] . pPrinterName , aPrinterName ) = = 0 ) {
2006-02-07 01:13:53 +00:00
aIsFound = PR_TRUE ;
aIsFile = _tcscmp ( lpInfo [ i ] . pPortName , _T ( " FILE: " ) ) = = 0 ;
break ;
}
}
2006-02-07 01:14:13 +00:00
: : HeapFree ( GetProcessHeap ( ) , 0 , lpInfo ) ;
2006-02-07 01:13:53 +00:00
return NS_OK ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:53 +00:00
//----------------------------------------------------------------
2006-02-07 01:13:59 +00:00
static void
CheckForPrintToFileWithName ( LPTSTR aPrinterName , PRBool & aIsFile )
2006-02-07 01:13:12 +00:00
{
2006-02-07 01:13:53 +00:00
PRBool isFound = PR_FALSE ;
aIsFile = PR_FALSE ;
nsresult rv = EnumerateNativePrinters ( PRINTER_ENUM_LOCAL , aPrinterName , isFound , aIsFile ) ;
2006-02-07 01:13:59 +00:00
if ( isFound ) return ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:53 +00:00
rv = EnumerateNativePrinters ( PRINTER_ENUM_NETWORK , aPrinterName , isFound , aIsFile ) ;
2006-02-07 01:13:59 +00:00
if ( isFound ) return ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:53 +00:00
rv = EnumerateNativePrinters ( PRINTER_ENUM_SHARED , aPrinterName , isFound , aIsFile ) ;
2006-02-07 01:13:59 +00:00
if ( isFound ) return ;
2006-02-07 01:13:50 +00:00
2006-02-07 01:13:53 +00:00
rv = EnumerateNativePrinters ( PRINTER_ENUM_REMOTE , aPrinterName , isFound , aIsFile ) ;
2006-02-07 01:13:59 +00:00
if ( isFound ) return ;
2006-02-07 01:13:53 +00:00
1998-11-14 02:05:13 +00:00
}
2006-02-07 01:13:53 +00:00
static nsresult
GetFileNameForPrintSettings ( nsIPrintSettings * aPS )
2006-02-07 01:13:12 +00:00
{
2006-02-07 01:13:53 +00:00
// for testing
2006-02-07 01:14:04 +00:00
# ifdef DEBUG_rods
2006-02-07 01:13:53 +00:00
return NS_OK ;
# endif
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:53 +00:00
nsresult rv ;
nsCOMPtr < nsIFilePicker > filePicker = do_CreateInstance ( " @mozilla.org/filepicker;1 " , & rv ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
nsCOMPtr < nsIStringBundleService > bundleService = do_GetService ( NS_STRINGBUNDLE_CONTRACTID , & rv ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
nsCOMPtr < nsIStringBundle > bundle ;
rv = bundleService - > CreateBundle ( NS_ERROR_GFX_PRINTER_BUNDLE_URL , getter_AddRefs ( bundle ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
nsXPIDLString title ;
rv = bundle - > GetStringFromName ( NS_LITERAL_STRING ( " PrintToFile " ) . get ( ) , getter_Copies ( title ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
rv = filePicker - > Init ( nsnull , title . get ( ) , nsIFilePicker : : modeSave ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
rv = filePicker - > AppendFilters ( nsIFilePicker : : filterAll ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
PRUnichar * fileName ;
aPS - > GetToFileName ( & fileName ) ;
if ( fileName ) {
if ( * fileName ) {
2006-02-07 01:13:55 +00:00
nsAutoString leafName ;
2006-02-07 01:13:53 +00:00
nsCOMPtr < nsILocalFile > file ( do_CreateInstance ( " @mozilla.org/file/local;1 " ) ) ;
if ( file ) {
2006-02-07 01:13:55 +00:00
rv = file - > InitWithPath ( nsDependentString ( fileName ) ) ;
2006-02-07 01:13:53 +00:00
if ( NS_SUCCEEDED ( rv ) ) {
file - > GetLeafName ( leafName ) ;
filePicker - > SetDisplayDirectory ( file ) ;
}
}
if ( ! leafName . IsEmpty ( ) ) {
2006-02-07 01:13:55 +00:00
rv = filePicker - > SetDefaultString ( leafName . get ( ) ) ;
2006-02-07 01:13:53 +00:00
}
NS_ENSURE_SUCCESS ( rv , rv ) ;
}
nsMemory : : Free ( fileName ) ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:53 +00:00
PRInt16 dialogResult ;
filePicker - > Show ( & dialogResult ) ;
if ( dialogResult = = nsIFilePicker : : returnCancel ) {
return NS_ERROR_ABORT ;
2006-02-07 01:13:47 +00:00
}
2006-02-07 01:13:53 +00:00
nsCOMPtr < nsILocalFile > localFile ;
rv = filePicker - > GetFile ( getter_AddRefs ( localFile ) ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
if ( dialogResult = = nsIFilePicker : : returnReplace ) {
// be extra safe and only delete when the file is really a file
PRBool isFile ;
rv = localFile - > IsFile ( & isFile ) ;
if ( NS_SUCCEEDED ( rv ) & & isFile ) {
rv = localFile - > Remove ( PR_FALSE /* recursive delete */ ) ;
NS_ENSURE_SUCCESS ( rv , rv ) ;
2006-02-07 01:13:51 +00:00
}
2006-02-07 01:13:50 +00:00
}
2006-02-07 01:13:55 +00:00
nsAutoString unicodePath ;
rv = localFile - > GetPath ( unicodePath ) ;
2006-02-07 01:13:53 +00:00
NS_ENSURE_SUCCESS ( rv , rv ) ;
2006-02-07 01:13:50 +00:00
2006-02-07 01:13:55 +00:00
if ( unicodePath . IsEmpty ( ) ) {
2006-02-07 01:13:53 +00:00
rv = NS_ERROR_ABORT ;
}
if ( NS_SUCCEEDED ( rv ) ) aPS - > SetToFileName ( unicodePath . get ( ) ) ;
return rv ;
}
//----------------------------------------------------------------------------------
static nsresult
CheckForPrintToFile ( nsIPrintSettings * aPS , LPTSTR aPrinterName , PRUnichar * aUPrinterName )
{
nsresult rv = NS_OK ;
if ( ! aPrinterName & & ! aUPrinterName ) return rv ;
PRBool toFile ;
# ifdef UNICODE
2006-02-07 01:13:59 +00:00
CheckForPrintToFileWithName ( aPrinterName ? aPrinterName : aUPrinterName , toFile ) ;
2006-02-07 01:13:53 +00:00
# else
if ( aPrinterName ) {
2006-02-07 01:13:59 +00:00
CheckForPrintToFileWithName ( aPrinterName , toFile ) ;
2006-02-07 01:13:12 +00:00
} else {
2006-02-07 01:13:59 +00:00
CheckForPrintToFileWithName ( ( char * ) NS_ConvertUCS2toUTF8 ( aUPrinterName ) . get ( ) , toFile ) ;
2006-02-07 01:13:50 +00:00
}
2006-02-07 01:13:53 +00:00
# endif
2006-02-07 01:14:19 +00:00
// Since the driver wasn't a "Print To File" Driver, check to see
// if the name of the file has been set to the special "FILE:"
if ( ! toFile ) {
nsXPIDLString toFileName ;
aPS - > GetToFileName ( getter_Copies ( toFileName ) ) ;
if ( toFileName ) {
if ( * toFileName ) {
if ( toFileName . Equals ( NS_LITERAL_STRING ( " FILE: " ) ) ) {
// this skips the setting of the "print to file" info below
// which we don't want to do.
return NS_OK ;
}
}
}
}
2006-02-07 01:13:53 +00:00
aPS - > SetPrintToFile ( toFile ) ;
if ( toFile ) {
rv = GetFileNameForPrintSettings ( aPS ) ;
}
return rv ;
2006-02-07 01:13:12 +00:00
}
//----------------------------------------------------------------------------------
2006-02-07 01:13:32 +00:00
NS_IMETHODIMP nsDeviceContextSpecWin : : Init ( nsIWidget * aWidget ,
nsIPrintSettings * aPrintSettings ,
2006-02-07 01:13:53 +00:00
PRBool aIsPrintPreview )
2006-02-07 01:13:12 +00:00
{
mPrintSettings = aPrintSettings ;
gParentWnd = ( HWND ) aWidget - > GetNativeData ( NS_NATIVE_WINDOW ) ;
nsresult rv = NS_ERROR_FAILURE ;
2006-02-07 01:13:53 +00:00
if ( aPrintSettings ) {
nsCOMPtr < nsIPrintSettingsWin > psWin ( do_QueryInterface ( aPrintSettings ) ) ;
if ( psWin ) {
char * deviceName ;
char * driverName ;
psWin - > GetDeviceName ( & deviceName ) ; // creates new memory (makes a copy)
psWin - > GetDriverName ( & driverName ) ; // creates new memory (makes a copy)
LPDEVMODE devMode ;
psWin - > GetDevMode ( & devMode ) ; // creates new memory (makes a copy)
if ( deviceName & & driverName & & devMode ) {
// Scaling is special, it is one of the few
// devMode items that we control in layout
if ( devMode - > dmFields & DM_SCALE ) {
double scale = double ( devMode - > dmScale ) / 100.0f ;
if ( scale ! = 1.0 ) {
aPrintSettings - > SetScaling ( scale ) ;
devMode - > dmScale = 100 ;
}
}
2006-02-07 01:13:50 +00:00
2006-02-07 01:13:53 +00:00
SetDeviceName ( deviceName ) ;
SetDriverName ( driverName ) ;
SetDevMode ( devMode ) ;
if ( ! aIsPrintPreview ) {
rv = CheckForPrintToFile ( mPrintSettings , deviceName , nsnull ) ;
2006-02-07 01:14:13 +00:00
if ( NS_FAILED ( rv ) ) {
nsCRT : : free ( deviceName ) ;
nsCRT : : free ( driverName ) ;
return NS_ERROR_FAILURE ;
}
2006-02-07 01:13:53 +00:00
}
// clean up
nsCRT : : free ( deviceName ) ;
nsCRT : : free ( driverName ) ;
return NS_OK ;
} else {
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ***** nsDeviceContextSpecWin::Init - deviceName/driverName/devMode was NULL! \n " ) ) ;
2006-02-07 01:13:53 +00:00
if ( deviceName ) nsCRT : : free ( deviceName ) ;
if ( driverName ) nsCRT : : free ( driverName ) ;
2006-02-07 01:14:13 +00:00
if ( devMode ) : : HeapFree ( : : GetProcessHeap ( ) , 0 , devMode ) ;
2006-02-07 01:13:53 +00:00
}
2006-02-07 01:13:21 +00:00
}
2006-02-07 01:13:59 +00:00
} else {
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ***** nsDeviceContextSpecWin::Init - aPrintSettingswas NULL! \n " ) ) ;
2006-02-07 01:13:59 +00:00
}
2006-02-07 01:13:53 +00:00
LPDEVMODE pDevMode = NULL ;
HGLOBAL hDevNames = NULL ;
// Get the Print Name to be used
PRUnichar * printerName ;
mPrintSettings - > GetPrinterName ( & printerName ) ;
// If there is no name then use the default printer
if ( ! printerName | | ( printerName & & ! * printerName ) ) {
printerName = GetDefaultPrinterNameFromGlobalPrinters ( ) ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:53 +00:00
NS_ASSERTION ( printerName , " We have to have a printer name " ) ;
if ( ! printerName | | ! * printerName ) return NS_ERROR_FAILURE ;
if ( ! aIsPrintPreview ) {
CheckForPrintToFile ( mPrintSettings , nsnull , printerName ) ;
}
return GetDataFromPrinter ( printerName , mPrintSettings ) ;
2006-02-07 01:13:12 +00:00
}
//----------------------------------------------------------
// Helper Function - Free and reallocate the string
static void CleanAndCopyString ( char * & aStr , char * aNewStr )
{
if ( aStr ! = nsnull ) {
if ( aNewStr ! = nsnull & & strlen ( aStr ) > strlen ( aNewStr ) ) { // reuse it if we can
PL_strcpy ( aStr , aNewStr ) ;
return ;
} else {
PR_Free ( aStr ) ;
aStr = nsnull ;
}
}
if ( nsnull ! = aNewStr ) {
aStr = ( char * ) PR_Malloc ( PL_strlen ( aNewStr ) + 1 ) ;
PL_strcpy ( aStr , aNewStr ) ;
}
}
//----------------------------------------------------------------------------------
2006-02-07 01:13:32 +00:00
void nsDeviceContextSpecWin : : SetDeviceName ( char * aDeviceName )
2006-02-07 01:13:12 +00:00
{
CleanAndCopyString ( mDeviceName , aDeviceName ) ;
}
//----------------------------------------------------------------------------------
2006-02-07 01:13:32 +00:00
void nsDeviceContextSpecWin : : SetDriverName ( char * aDriverName )
2006-02-07 01:13:12 +00:00
{
CleanAndCopyString ( mDriverName , aDriverName ) ;
}
//----------------------------------------------------------------------------------
2006-02-07 01:13:32 +00:00
void nsDeviceContextSpecWin : : SetDevMode ( LPDEVMODE aDevMode )
2006-02-07 01:13:12 +00:00
{
2006-02-07 01:14:13 +00:00
if ( mDevMode ) {
: : HeapFree ( : : GetProcessHeap ( ) , 0 , mDevMode ) ;
}
2006-02-07 01:13:29 +00:00
2006-02-07 01:13:12 +00:00
mDevMode = aDevMode ;
}
2006-02-07 01:13:53 +00:00
//------------------------------------------------------------------
void
nsDeviceContextSpecWin : : GetDevMode ( LPDEVMODE & aDevMode )
2006-02-07 01:13:51 +00:00
{
2006-02-07 01:14:13 +00:00
aDevMode = mDevMode ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:21 +00:00
//----------------------------------------------------------------------------------
2006-02-07 01:13:53 +00:00
// Map an incoming size to a Windows Native enum in the DevMode
static void
MapPaperSizeToNativeEnum ( LPDEVMODE aDevMode ,
PRInt16 aType ,
double aW ,
double aH )
2006-02-07 01:13:51 +00:00
{
2006-02-07 01:13:53 +00:00
# ifdef DEBUG_rods
BOOL doingOrientation = aDevMode - > dmFields & DM_ORIENTATION ;
BOOL doingPaperSize = aDevMode - > dmFields & DM_PAPERSIZE ;
BOOL doingPaperLength = aDevMode - > dmFields & DM_PAPERLENGTH ;
BOOL doingPaperWidth = aDevMode - > dmFields & DM_PAPERWIDTH ;
2006-02-07 01:13:51 +00:00
# endif
2006-02-07 01:13:53 +00:00
PRBool foundEnum = PR_FALSE ;
for ( PRInt32 i = 0 ; i < kNumPaperSizes ; i + + ) {
if ( kPaperSizes [ i ] . mWidth = = aW & & kPaperSizes [ i ] . mHeight = = aH ) {
aDevMode - > dmPaperSize = kPaperSizes [ i ] . mPaperSize ;
aDevMode - > dmFields & = ~ DM_PAPERLENGTH ;
aDevMode - > dmFields & = ~ DM_PAPERWIDTH ;
aDevMode - > dmFields | = DM_PAPERSIZE ;
return ;
2006-02-07 01:13:51 +00:00
}
}
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:53 +00:00
short width = 0 ;
short height = 0 ;
if ( aType = = nsIPrintSettings : : kPaperSizeInches ) {
width = short ( NS_TWIPS_TO_MILLIMETERS ( NS_INCHES_TO_TWIPS ( float ( aW ) ) ) / 10 ) ;
height = short ( NS_TWIPS_TO_MILLIMETERS ( NS_INCHES_TO_TWIPS ( float ( aH ) ) ) / 10 ) ;
2006-02-07 01:13:51 +00:00
2006-02-07 01:13:53 +00:00
} else if ( aType = = nsIPrintSettings : : kPaperSizeMillimeters ) {
width = short ( aW / 10.0 ) ;
height = short ( aH / 10.0 ) ;
2006-02-07 01:13:51 +00:00
} else {
2006-02-07 01:13:53 +00:00
return ; // don't set anything
2006-02-07 01:13:51 +00:00
}
2006-02-07 01:13:53 +00:00
// width and height is in
aDevMode - > dmPaperSize = 0 ;
aDevMode - > dmPaperWidth = width ;
aDevMode - > dmPaperLength = height ;
2006-02-07 01:13:51 +00:00
2006-02-07 01:13:53 +00:00
aDevMode - > dmFields | = DM_PAPERSIZE ;
aDevMode - > dmFields | = DM_PAPERLENGTH ;
aDevMode - > dmFields | = DM_PAPERWIDTH ;
2006-02-07 01:13:51 +00:00
}
2006-02-07 01:13:53 +00:00
//----------------------------------------------------------------------------------
// Setup Paper Size & Orientation options into the DevMode
//
static void
SetupDevModeFromSettings ( LPDEVMODE aDevMode , nsIPrintSettings * aPrintSettings )
2006-02-07 01:13:51 +00:00
{
2006-02-07 01:13:53 +00:00
// Setup paper size
if ( aPrintSettings ) {
PRInt16 type ;
aPrintSettings - > GetPaperSizeType ( & type ) ;
if ( type = = nsIPrintSettings : : kPaperSizeNativeData ) {
PRInt16 paperEnum ;
aPrintSettings - > GetPaperData ( & paperEnum ) ;
aDevMode - > dmPaperSize = paperEnum ;
aDevMode - > dmFields & = ~ DM_PAPERLENGTH ;
aDevMode - > dmFields & = ~ DM_PAPERWIDTH ;
aDevMode - > dmFields | = DM_PAPERSIZE ;
2006-02-07 01:13:51 +00:00
} else {
2006-02-07 01:13:53 +00:00
PRInt16 unit ;
double width , height ;
aPrintSettings - > GetPaperSizeUnit ( & unit ) ;
aPrintSettings - > GetPaperWidth ( & width ) ;
aPrintSettings - > GetPaperHeight ( & height ) ;
MapPaperSizeToNativeEnum ( aDevMode , unit , width , height ) ;
2006-02-07 01:13:51 +00:00
}
2006-02-07 01:13:53 +00:00
// Setup Orientation
PRInt32 orientation ;
aPrintSettings - > GetOrientation ( & orientation ) ;
aDevMode - > dmOrientation = orientation = = nsIPrintSettings : : kPortraitOrientation ? DMORIENT_PORTRAIT : DMORIENT_LANDSCAPE ;
aDevMode - > dmFields | = DM_ORIENTATION ;
2006-02-07 01:13:51 +00:00
2006-02-07 01:13:53 +00:00
// Setup Number of Copies
PRInt32 copies ;
aPrintSettings - > GetNumCopies ( & copies ) ;
aDevMode - > dmCopies = copies ;
aDevMode - > dmFields | = DM_COPIES ;
}
2006-02-07 01:13:51 +00:00
2006-02-07 01:13:21 +00:00
}
2006-02-07 01:13:59 +00:00
# if defined(DEBUG_rods) || defined(DEBUG_dcone)
static void DisplayLastError ( )
{
LPVOID lpMsgBuf ;
DWORD errCode = GetLastError ( ) ;
FormatMessage (
FORMAT_MESSAGE_ALLOCATE_BUFFER | FORMAT_MESSAGE_FROM_SYSTEM ,
NULL ,
GetLastError ( ) ,
MAKELANGID ( LANG_NEUTRAL , SUBLANG_DEFAULT ) , // Default language
( LPTSTR ) & lpMsgBuf ,
0 ,
NULL
) ;
// Display the string.
MessageBox ( NULL , ( const char * ) lpMsgBuf , " GetLastError " , MB_OK | MB_ICONINFORMATION ) ;
}
# define DISPLAY_LAST_ERROR DisplayLastError();
# else
# define DISPLAY_LAST_ERROR
# endif
2006-02-07 01:13:12 +00:00
//----------------------------------------------------------------------------------
// Setup the object's data member with the selected printer's data
2006-02-07 01:13:29 +00:00
nsresult
2006-02-07 01:13:32 +00:00
nsDeviceContextSpecWin : : GetDataFromPrinter ( const PRUnichar * aName , nsIPrintSettings * aPS )
1998-11-14 02:05:13 +00:00
{
2006-02-07 01:13:29 +00:00
nsresult rv = NS_ERROR_FAILURE ;
2006-02-07 01:13:12 +00:00
if ( ! GlobalPrinters : : GetInstance ( ) - > PrintersAreAllocated ( ) ) {
2006-02-07 01:13:37 +00:00
rv = GlobalPrinters : : GetInstance ( ) - > EnumeratePrinterList ( ) ;
2006-02-07 01:13:59 +00:00
if ( NS_FAILED ( rv ) ) {
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ***** nsDeviceContextSpecWin::GetDataFromPrinter - Couldn't enumerate printers! \n " ) ) ;
2006-02-07 01:13:59 +00:00
DISPLAY_LAST_ERROR
}
2006-02-07 01:13:37 +00:00
NS_ENSURE_SUCCESS ( rv , rv ) ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:21 +00:00
HANDLE hPrinter = NULL ;
BOOL status = : : OpenPrinter ( ( char * ) NS_ConvertUCS2toUTF8 ( aName ) . get ( ) , & hPrinter , NULL ) ;
if ( status ) {
LPDEVMODE pDevMode ;
DWORD dwNeeded , dwRet ;
// Allocate a buffer of the correct size.
dwNeeded = DocumentProperties ( gParentWnd , hPrinter , ( char * ) NS_ConvertUCS2toUTF8 ( aName ) . get ( ) ,
NULL , NULL , 0 ) ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:14:13 +00:00
pDevMode = ( LPDEVMODE ) : : HeapAlloc ( : : GetProcessHeap ( ) , HEAP_ZERO_MEMORY , dwNeeded ) ;
if ( ! pDevMode ) return NS_ERROR_FAILURE ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:21 +00:00
// Get the default DevMode for the printer and modify it for our needs.
dwRet = DocumentProperties ( gParentWnd , hPrinter , ( char * ) NS_ConvertUCS2toUTF8 ( aName ) . get ( ) ,
pDevMode , NULL , DM_OUT_BUFFER ) ;
2006-02-07 01:14:18 +00:00
if ( dwRet = = IDOK & & aPS ) {
SetupDevModeFromSettings ( pDevMode , aPS ) ;
// Sets back the changes we made to the DevMode into the Printer Driver
dwRet = : : DocumentProperties ( gParentWnd , hPrinter , ( char * ) NS_ConvertUCS2toUTF8 ( aName ) . get ( ) , pDevMode , pDevMode , DM_IN_BUFFER | DM_OUT_BUFFER ) ;
2006-02-07 01:13:29 +00:00
}
2006-02-07 01:14:18 +00:00
if ( dwRet ! = IDOK ) {
: : HeapFree ( : : GetProcessHeap ( ) , 0 , pDevMode ) ;
: : ClosePrinter ( hPrinter ) ;
PR_PL ( ( " ***** nsDeviceContextSpecWin::GetDataFromPrinter - DocumentProperties call failed code: %d/0x%x \n " , dwRet , dwRet ) ) ;
DISPLAY_LAST_ERROR
return NS_ERROR_FAILURE ;
2006-02-07 01:13:21 +00:00
}
2006-02-07 01:14:18 +00:00
SetDevMode ( pDevMode ) ; // cache the pointer and takes responsibility for the memory
2006-02-07 01:13:21 +00:00
SetDeviceName ( ( char * ) NS_ConvertUCS2toUTF8 ( aName ) . get ( ) ) ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:21 +00:00
// The driver should be NULL for Win95/Win98
OSVERSIONINFO os ;
os . dwOSVersionInfoSize = sizeof ( os ) ;
: : GetVersionEx ( & os ) ;
if ( VER_PLATFORM_WIN32_NT = = os . dwPlatformId ) {
SetDriverName ( " WINSPOOL " ) ;
} else {
SetDriverName ( NULL ) ;
}
: : ClosePrinter ( hPrinter ) ;
2006-02-07 01:13:29 +00:00
rv = NS_OK ;
} else {
rv = NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND ;
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ***** nsDeviceContextSpecWin::GetDataFromPrinter - Couldn't open printer: [%s] \n " , NS_ConvertUCS2toUTF8 ( aName ) . get ( ) ) ) ;
2006-02-07 01:13:59 +00:00
DISPLAY_LAST_ERROR
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:29 +00:00
return rv ;
2006-02-07 01:13:12 +00:00
}
//----------------------------------------------------------------------------------
// Setup Paper Size options into the DevMode
//
// When using a data member it may be a HGLOCAL or LPDEVMODE
// if it is a HGLOBAL then we need to "lock" it to get the LPDEVMODE
// and unlock it when we are done.
void
2006-02-07 01:13:32 +00:00
nsDeviceContextSpecWin : : SetupPaperInfoFromSettings ( )
2006-02-07 01:13:12 +00:00
{
LPDEVMODE devMode ;
2006-02-07 01:13:32 +00:00
GetDevMode ( devMode ) ;
NS_ASSERTION ( devMode , " DevMode can't be NULL here " ) ;
if ( devMode ) {
SetupDevModeFromSettings ( devMode , mPrintSettings ) ;
2006-02-07 01:13:12 +00:00
}
}
//----------------------------------------------------------------------------------
2006-02-07 01:13:53 +00:00
// Helper Function - Free and reallocate the string
2006-02-07 01:13:12 +00:00
nsresult
2006-02-07 01:13:53 +00:00
nsDeviceContextSpecWin : : SetPrintSettingsFromDevMode ( nsIPrintSettings * aPrintSettings ,
LPDEVMODE aDevMode )
2006-02-07 01:13:12 +00:00
{
2006-02-07 01:13:53 +00:00
if ( aPrintSettings = = nsnull ) {
return NS_ERROR_FAILURE ;
}
2006-02-07 01:14:23 +00:00
aPrintSettings - > SetIsInitializedFromPrinter ( PR_TRUE ) ;
2006-02-07 01:13:53 +00:00
BOOL doingNumCopies = aDevMode - > dmFields & DM_COPIES ;
BOOL doingOrientation = aDevMode - > dmFields & DM_ORIENTATION ;
BOOL doingPaperSize = aDevMode - > dmFields & DM_PAPERSIZE ;
BOOL doingPaperLength = aDevMode - > dmFields & DM_PAPERLENGTH ;
BOOL doingPaperWidth = aDevMode - > dmFields & DM_PAPERWIDTH ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:53 +00:00
if ( doingOrientation ) {
PRInt32 orientation = aDevMode - > dmOrientation = = DMORIENT_PORTRAIT ?
nsIPrintSettings : : kPortraitOrientation : nsIPrintSettings : : kLandscapeOrientation ;
aPrintSettings - > SetOrientation ( orientation ) ;
2006-02-07 01:13:50 +00:00
}
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:53 +00:00
// Setup Number of Copies
if ( doingNumCopies ) {
aPrintSettings - > SetNumCopies ( PRInt32 ( aDevMode - > dmCopies ) ) ;
}
2006-02-07 01:13:51 +00:00
2006-02-07 01:13:53 +00:00
if ( aDevMode - > dmFields & DM_SCALE ) {
double scale = double ( aDevMode - > dmScale ) / 100.0f ;
if ( scale ! = 1.0 ) {
aPrintSettings - > SetScaling ( scale ) ;
aDevMode - > dmScale = 100 ;
// To turn this on you must change where the mPrt->mShrinkToFit is being set in the DocumentViewer
//aPrintSettings->SetShrinkToFit(PR_FALSE);
2006-02-07 01:13:12 +00:00
}
}
2006-02-07 01:13:53 +00:00
if ( doingPaperSize ) {
aPrintSettings - > SetPaperSizeType ( nsIPrintSettings : : kPaperSizeNativeData ) ;
aPrintSettings - > SetPaperData ( aDevMode - > dmPaperSize ) ;
2006-02-07 01:14:23 +00:00
for ( PRInt32 i = 0 ; i < kNumPaperSizes ; i + + ) {
if ( kPaperSizes [ i ] . mPaperSize = = aDevMode - > dmPaperSize ) {
aPrintSettings - > SetPaperSizeUnit ( kPaperSizes [ i ] . mIsInches ? nsIPrintSettings : : kPaperSizeInches : nsIPrintSettings : : kPaperSizeMillimeters ) ;
break ;
}
}
2006-02-07 01:13:51 +00:00
2006-02-07 01:13:53 +00:00
} else if ( doingPaperLength & & doingPaperWidth ) {
PRBool found = PR_FALSE ;
for ( PRInt32 i = 0 ; i < kNumPaperSizes ; i + + ) {
if ( kPaperSizes [ i ] . mPaperSize = = aDevMode - > dmPaperSize ) {
aPrintSettings - > SetPaperSizeType ( nsIPrintSettings : : kPaperSizeDefined ) ;
aPrintSettings - > SetPaperWidth ( kPaperSizes [ i ] . mWidth ) ;
aPrintSettings - > SetPaperHeight ( kPaperSizes [ i ] . mHeight ) ;
2006-02-07 01:14:23 +00:00
aPrintSettings - > SetPaperSizeUnit ( kPaperSizes [ i ] . mIsInches ? nsIPrintSettings : : kPaperSizeInches : nsIPrintSettings : : kPaperSizeMillimeters ) ;
2006-02-07 01:13:53 +00:00
found = PR_TRUE ;
break ;
2006-02-07 01:13:12 +00:00
}
}
2006-02-07 01:13:53 +00:00
if ( ! found ) {
return NS_ERROR_FAILURE ;
}
} else {
return NS_ERROR_FAILURE ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:53 +00:00
return NS_OK ;
2006-02-07 01:13:12 +00:00
}
//***********************************************************
// Printer Enumerator
//***********************************************************
nsPrinterEnumeratorWin : : nsPrinterEnumeratorWin ( )
{
}
nsPrinterEnumeratorWin : : ~ nsPrinterEnumeratorWin ( )
{
// Do not free printers here
// GlobalPrinters::GetInstance()->FreeGlobalPrinters();
}
NS_IMPL_ISUPPORTS1 ( nsPrinterEnumeratorWin , nsIPrinterEnumerator )
static void CleanupArray ( PRUnichar * * & aArray , PRInt32 & aCount )
{
for ( PRInt32 i = aCount - 1 ; i > = 0 ; i - - ) {
nsMemory : : Free ( aArray [ i ] ) ;
}
nsMemory : : Free ( aArray ) ;
aArray = NULL ;
aCount = 0 ;
}
2006-02-07 01:13:32 +00:00
//----------------------------------------------------------------------------------
// Return the Default Printer name
/* readonly attribute wstring defaultPrinterName; */
NS_IMETHODIMP
nsPrinterEnumeratorWin : : GetDefaultPrinterName ( PRUnichar * * aDefaultPrinterName )
{
NS_ENSURE_ARG_POINTER ( aDefaultPrinterName ) ;
* aDefaultPrinterName = GetDefaultPrinterNameFromGlobalPrinters ( ) ; // helper
return NS_OK ;
}
/* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */
NS_IMETHODIMP
nsPrinterEnumeratorWin : : InitPrintSettingsFromPrinter ( const PRUnichar * aPrinterName , nsIPrintSettings * aPrintSettings )
{
NS_ENSURE_ARG_POINTER ( aPrinterName ) ;
NS_ENSURE_ARG_POINTER ( aPrintSettings ) ;
if ( ! * aPrinterName ) {
return NS_OK ;
}
nsCOMPtr < nsDeviceContextSpecWin > devSpecWin = new nsDeviceContextSpecWin ( ) ;
if ( ! devSpecWin ) return NS_ERROR_OUT_OF_MEMORY ;
if ( NS_FAILED ( GlobalPrinters : : GetInstance ( ) - > EnumeratePrinterList ( ) ) ) {
return NS_ERROR_FAILURE ;
}
devSpecWin - > GetDataFromPrinter ( aPrinterName ) ;
LPDEVMODE devmode ;
devSpecWin - > GetDevMode ( devmode ) ;
NS_ASSERTION ( devmode , " DevMode can't be NULL here " ) ;
if ( devmode ) {
2006-02-07 01:14:23 +00:00
aPrintSettings - > SetPrinterName ( aPrinterName ) ;
2006-02-07 01:13:32 +00:00
nsDeviceContextSpecWin : : SetPrintSettingsFromDevMode ( aPrintSettings , devmode ) ;
}
// Free them, we won't need them for a while
GlobalPrinters : : GetInstance ( ) - > FreeGlobalPrinters ( ) ;
return NS_OK ;
}
2006-02-07 01:13:12 +00:00
//----------------------------------------------------------------------------------
// Enumerate all the Printers from the global array and pass their
// names back (usually to script)
2006-02-07 01:13:21 +00:00
NS_IMETHODIMP
nsPrinterEnumeratorWin : : EnumeratePrinters ( PRUint32 * aCount , PRUnichar * * * aResult )
2006-02-07 01:13:12 +00:00
{
NS_ENSURE_ARG ( aCount ) ;
NS_ENSURE_ARG_POINTER ( aResult ) ;
if ( NS_FAILED ( GlobalPrinters : : GetInstance ( ) - > EnumeratePrinterList ( ) ) ) {
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ***** nsDeviceContextSpecWin::EnumeratePrinters - Couldn't enumerate printers! \n " ) ) ;
2006-02-07 01:13:12 +00:00
return NS_ERROR_FAILURE ;
}
if ( aCount )
* aCount = 0 ;
else
return NS_ERROR_NULL_POINTER ;
if ( aResult )
* aResult = nsnull ;
else
return NS_ERROR_NULL_POINTER ;
PRInt32 numPrinters = GlobalPrinters : : GetInstance ( ) - > GetNumPrinters ( ) ;
2006-02-07 01:13:21 +00:00
PRInt32 numItems = numPrinters ;
2006-02-07 01:13:12 +00:00
PRUnichar * * array = ( PRUnichar * * ) nsMemory : : Alloc ( numItems * sizeof ( PRUnichar * ) ) ;
if ( ! array )
return NS_ERROR_OUT_OF_MEMORY ;
2006-02-07 01:13:21 +00:00
PRInt32 count = 0 ;
PRInt32 printerInx = 0 ;
2006-02-07 01:13:12 +00:00
while ( count < numItems ) {
2006-02-07 01:13:37 +00:00
LPTSTR name = GlobalPrinters : : GetInstance ( ) - > GetItemFromList ( printerInx + + ) ;
2006-02-07 01:13:12 +00:00
nsString newName ;
2006-02-07 01:13:21 +00:00
newName . AssignWithConversion ( name ) ;
2006-02-07 01:13:12 +00:00
PRUnichar * str = ToNewUnicode ( newName ) ;
if ( ! str ) {
CleanupArray ( array , count ) ;
return NS_ERROR_OUT_OF_MEMORY ;
}
array [ count + + ] = str ;
}
* aCount = count ;
* aResult = array ;
1998-11-14 02:05:13 +00:00
return NS_OK ;
2006-02-07 01:13:12 +00:00
}
//----------------------------------------------------------------------------------
// Display the AdvancedDocumentProperties for the selected Printer
NS_IMETHODIMP nsPrinterEnumeratorWin : : DisplayPropertiesDlg ( const PRUnichar * aPrinterName , nsIPrintSettings * aPrintSettings )
{
nsresult rv = NS_ERROR_FAILURE ;
2006-02-07 01:13:21 +00:00
HANDLE hPrinter = NULL ;
BOOL status = : : OpenPrinter ( ( char * ) NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) , & hPrinter , NULL ) ;
if ( status ) {
LPDEVMODE pDevMode ;
LPDEVMODE pNewDevMode ;
DWORD dwNeeded , dwRet ;
2006-02-07 01:14:13 +00:00
// Get the buffer correct buffer size
2006-02-07 01:13:21 +00:00
dwNeeded = : : DocumentProperties ( gParentWnd , hPrinter ,
( char * ) NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) , NULL , NULL , 0 ) ;
2006-02-07 01:14:13 +00:00
// Allocate a buffer of the correct size.
pNewDevMode = ( LPDEVMODE ) : : HeapAlloc ( : : GetProcessHeap ( ) , HEAP_ZERO_MEMORY , dwNeeded ) ;
if ( ! pNewDevMode ) return NS_ERROR_FAILURE ;
2006-02-07 01:13:21 +00:00
dwRet = : : DocumentProperties ( gParentWnd , hPrinter , ( char * ) NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) ,
pNewDevMode , NULL , DM_OUT_BUFFER ) ;
if ( dwRet ! = IDOK ) {
2006-02-07 01:14:13 +00:00
: : HeapFree ( : : GetProcessHeap ( ) , 0 , pNewDevMode ) ;
2006-02-07 01:13:21 +00:00
: : ClosePrinter ( hPrinter ) ;
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ***** nsDeviceContextSpecWin::DisplayPropertiesDlg - Couldn't get DocumentProperties (pNewDevMode) for [%s] \n " , NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) ) ) ;
2006-02-07 01:13:21 +00:00
return NS_ERROR_FAILURE ;
}
2006-02-07 01:14:13 +00:00
pDevMode = ( LPDEVMODE ) : : HeapAlloc ( : : GetProcessHeap ( ) , HEAP_ZERO_MEMORY , dwNeeded ) ;
if ( ! pDevMode ) return NS_ERROR_FAILURE ;
2006-02-07 01:13:21 +00:00
dwRet = : : DocumentProperties ( gParentWnd , hPrinter , ( char * ) NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) ,
pDevMode , NULL , DM_OUT_BUFFER ) ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:21 +00:00
if ( dwRet ! = IDOK ) {
2006-02-07 01:14:13 +00:00
: : HeapFree ( : : GetProcessHeap ( ) , 0 , pDevMode ) ;
: : HeapFree ( : : GetProcessHeap ( ) , 0 , pNewDevMode ) ;
2006-02-07 01:13:21 +00:00
: : ClosePrinter ( hPrinter ) ;
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ***** nsDeviceContextSpecWin::DisplayPropertiesDlg - Couldn't get DocumentProperties (pDevMode) for [%s] \n " , NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) ) ) ;
2006-02-07 01:13:21 +00:00
return NS_ERROR_FAILURE ;
}
if ( pDevMode & & pNewDevMode ) {
SetupDevModeFromSettings ( pDevMode , aPrintSettings ) ;
// Display the Dialog and get the new DevMode
#if 0 // need more to do more work to see why AdvancedDocumentProperties fails
// when cancel is pressed
LONG stat = : : AdvancedDocumentProperties ( gParentWnd , hPrinter , ( char * ) NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) , pNewDevMode , pDevMode ) ;
2006-02-07 01:13:12 +00:00
# else
2006-02-07 01:13:21 +00:00
LONG stat = : : DocumentProperties ( gParentWnd , hPrinter , ( char * ) NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) , pDevMode , NULL , DM_IN_PROMPT | DM_OUT_BUFFER ) ;
2006-02-07 01:13:12 +00:00
# endif
2006-02-07 01:13:21 +00:00
if ( stat = = IDOK ) {
// Now set the print options from the native Page Setup
2006-02-07 01:13:32 +00:00
nsDeviceContextSpecWin : : SetPrintSettingsFromDevMode ( aPrintSettings , pDevMode ) ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:14:13 +00:00
: : HeapFree ( : : GetProcessHeap ( ) , 0 , pDevMode ) ;
: : HeapFree ( : : GetProcessHeap ( ) , 0 , pNewDevMode ) ;
2006-02-07 01:13:21 +00:00
rv = NS_OK ;
} else {
rv = NS_ERROR_OUT_OF_MEMORY ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:21 +00:00
: : ClosePrinter ( hPrinter ) ;
2006-02-07 01:13:12 +00:00
} else {
2006-02-07 01:14:03 +00:00
rv = NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND ;
PR_PL ( ( " ***** nsDeviceContextSpecWin::DisplayPropertiesDlg - Couldn't open printer [%s] \n " , NS_ConvertUCS2toUTF8 ( aPrinterName ) . get ( ) ) ) ;
DISPLAY_LAST_ERROR
2006-02-07 01:13:12 +00:00
}
return rv ;
}
//----------------------------------------------------------------------------------
//-- Global Printers
//----------------------------------------------------------------------------------
//----------------------------------------------------------------------------------
2006-02-07 01:13:21 +00:00
// THe array hold the name and port for each printer
2006-02-07 01:13:12 +00:00
void
GlobalPrinters : : ReallocatePrinters ( )
{
if ( PrintersAreAllocated ( ) ) {
FreeGlobalPrinters ( ) ;
}
mPrinters = new nsVoidArray ( ) ;
NS_ASSERTION ( mPrinters , " Printers Array is NULL! " ) ;
}
//----------------------------------------------------------------------------------
void
GlobalPrinters : : FreeGlobalPrinters ( )
{
if ( mPrinters ! = nsnull ) {
2006-02-07 01:13:21 +00:00
for ( int i = 0 ; i < mPrinters - > Count ( ) ; i + + ) {
free ( ( LPTSTR ) mPrinters - > ElementAt ( i ) ) ;
}
2006-02-07 01:13:12 +00:00
delete mPrinters ;
mPrinters = nsnull ;
}
}
//----------------------------------------------------------------------------------
nsresult
2006-02-07 01:13:21 +00:00
GlobalPrinters : : EnumerateNativePrinters ( )
1998-11-14 02:05:13 +00:00
{
2006-02-07 01:13:21 +00:00
nsresult rv = NS_ERROR_FAILURE ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ----------------------- \n " ) ) ;
PR_PL ( ( " EnumerateNativePrinters \n " ) ) ;
2006-02-07 01:13:21 +00:00
TCHAR szDefaultPrinterName [ 1024 ] ;
DWORD status = GetProfileString ( " devices " , 0 , " , " , szDefaultPrinterName , sizeof ( szDefaultPrinterName ) / sizeof ( TCHAR ) ) ;
if ( status > 0 ) {
DWORD count = 0 ;
LPTSTR sPtr = ( LPTSTR ) szDefaultPrinterName ;
LPTSTR ePtr = ( LPTSTR ) ( szDefaultPrinterName + ( status * sizeof ( TCHAR ) ) ) ;
LPTSTR prvPtr = sPtr ;
while ( sPtr < ePtr ) {
if ( * sPtr = = NULL ) {
LPTSTR name = _tcsdup ( prvPtr ) ;
mPrinters - > AppendElement ( name ) ;
2006-02-07 01:14:03 +00:00
PR_PL ( ( " Printer Name: %s \n " , prvPtr ) ) ;
2006-02-07 01:13:21 +00:00
prvPtr = sPtr + 1 ;
count + + ;
}
sPtr + + ;
}
rv = NS_OK ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ----------------------- \n " ) ) ;
2006-02-07 01:13:12 +00:00
2006-02-07 01:13:21 +00:00
return rv ;
1998-11-14 02:05:13 +00:00
}
2006-02-07 01:13:12 +00:00
//------------------------------------------------------------------
2006-02-07 01:13:17 +00:00
// Uses the GetProfileString to get the default printer from the registry
2006-02-07 01:13:12 +00:00
void
2006-02-07 01:13:21 +00:00
GlobalPrinters : : GetDefaultPrinterName ( LPTSTR & aDefaultPrinterName )
2006-02-07 01:13:12 +00:00
{
aDefaultPrinterName = nsnull ;
2006-02-07 01:13:17 +00:00
TCHAR szDefaultPrinterName [ 1024 ] ;
DWORD status = GetProfileString ( " windows " , " device " , 0 , szDefaultPrinterName , sizeof ( szDefaultPrinterName ) / sizeof ( TCHAR ) ) ;
if ( status > 0 ) {
TCHAR comma = ( TCHAR ) ' , ' ;
LPTSTR sPtr = ( LPTSTR ) szDefaultPrinterName ;
while ( * sPtr ! = comma & & * sPtr ! = NULL )
sPtr + + ;
if ( * sPtr = = comma ) {
* sPtr = NULL ;
2006-02-07 01:13:12 +00:00
}
2006-02-07 01:13:21 +00:00
aDefaultPrinterName = _tcsdup ( szDefaultPrinterName ) ;
2006-02-07 01:13:17 +00:00
} else {
2006-02-07 01:13:21 +00:00
aDefaultPrinterName = _tcsdup ( " " ) ;
2006-02-07 01:13:17 +00:00
}
2006-02-07 01:14:03 +00:00
PR_PL ( ( " DEFAULT PRINTER [%s] \n " , aDefaultPrinterName ) ) ;
2006-02-07 01:13:12 +00:00
}
//----------------------------------------------------------------------------------
2006-02-07 01:14:30 +00:00
// This goes and gets the list of available printers and puts
2006-02-07 01:13:12 +00:00
// the default printer at the beginning of the list
nsresult
GlobalPrinters : : EnumeratePrinterList ( )
1998-11-14 02:05:13 +00:00
{
2006-02-07 01:13:12 +00:00
// reallocate and get a new list each time it is asked for
// this deletes the list and re-allocates them
ReallocatePrinters ( ) ;
// any of these could only fail with an OUT_MEMORY_ERROR
// PRINTER_ENUM_LOCAL should get the network printers on Win95
2006-02-07 01:13:21 +00:00
nsresult rv = EnumerateNativePrinters ( ) ;
if ( NS_FAILED ( rv ) ) return rv ;
2006-02-07 01:13:14 +00:00
2006-02-07 01:13:15 +00:00
// get the name of the default printer
2006-02-07 01:13:21 +00:00
LPTSTR defPrinterName ;
2006-02-07 01:13:15 +00:00
GetDefaultPrinterName ( defPrinterName ) ;
// put the default printer at the beginning of list
if ( defPrinterName ! = nsnull ) {
for ( PRInt32 i = 0 ; i < mPrinters - > Count ( ) ; i + + ) {
2006-02-07 01:13:21 +00:00
LPTSTR name = ( LPTSTR ) mPrinters - > ElementAt ( i ) ;
if ( ! _tcscmp ( name , defPrinterName ) ) {
2006-02-07 01:13:15 +00:00
if ( i > 0 ) {
2006-02-07 01:13:21 +00:00
LPTSTR ptr = ( LPTSTR ) mPrinters - > ElementAt ( 0 ) ;
mPrinters - > ReplaceElementAt ( ( void * ) name , 0 ) ;
2006-02-07 01:13:15 +00:00
mPrinters - > ReplaceElementAt ( ( void * ) ptr , i ) ;
}
break ;
}
}
2006-02-07 01:13:21 +00:00
free ( defPrinterName ) ;
2006-02-07 01:13:12 +00:00
}
// make sure we at least tried to get the printers
if ( ! PrintersAreAllocated ( ) ) {
2006-02-07 01:14:03 +00:00
PR_PL ( ( " ***** nsDeviceContextSpecWin::EnumeratePrinterList - Printers aren`t allocated \n " ) ) ;
2006-02-07 01:13:12 +00:00
return NS_ERROR_FAILURE ;
}
1998-11-14 02:05:13 +00:00
return NS_OK ;
}
2006-02-07 01:13:12 +00:00