1 /* vim: set sw=2 sts=2 et cin: */
2 /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
3 /* ***** BEGIN LICENSE BLOCK *****
4 * Version: MPL 1.1/GPL 2.0/LGPL 2.1
6 * The contents of this file are subject to the Mozilla Public License Version
7 * 1.1 (the "License"); you may not use this file except in compliance with
8 * the License. You may obtain a copy of the License at
9 * http://www.mozilla.org/MPL/
11 * Software distributed under the License is distributed on an "AS IS" basis,
12 * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
13 * for the specific language governing rights and limitations under the
16 * The Original Code is the Mozilla OS/2 libraries.
18 * The Initial Developer of the Original Code is
19 * John Fairhurst, <john_fairhurst@iname.com>.
20 * Portions created by the Initial Developer are Copyright (C) 1999
21 * the Initial Developer. All Rights Reserved.
24 * Pierre Phaneuf <pp@ludusdesign.com>
25 * Peter Weilbacher <mozilla@weilbacher.org>
27 * Alternatively, the contents of this file may be used under the terms of
28 * either of the GNU General Public License Version 2 or later (the "GPL"),
29 * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
30 * in which case the provisions of the GPL or the LGPL are applicable instead
31 * of those above. If you wish to allow use of your version of this file only
32 * under the terms of either the GPL or the LGPL, and not to allow others to
33 * use your version of this file under the terms of the MPL, indicate your
34 * decision by deleting the provisions above and replace them with the notice
35 * and other provisions required by the GPL or the LGPL. If you do not delete
36 * the provisions above, a recipient may use your version of this file under
37 * the terms of any one of the MPL, the GPL or the LGPL.
39 * ***** END LICENSE BLOCK ***** */
42 #include "nsDeviceContextSpecOS2.h"
44 #include "nsReadableUtils.h"
47 #include "nsIPrefService.h"
48 #include "nsIPrefBranch.h"
49 #include "prenv.h" /* for PR_GetEnv */
52 #include "nsPrintfCString.h"
53 #include "nsIServiceManager.h"
54 #include "nsUnicharUtils.h"
55 #include "nsStringFwd.h"
56 #include "nsStringEnumerator.h"
60 #include "nsILocalFile.h"
61 #include "nsDirectoryServiceDefs.h"
62 #include "nsIFileStreams.h"
63 #include "gfxPDFSurface.h"
64 #include "gfxOS2Surface.h"
65 #include "nsIPrintSettingsService.h"
67 PRINTDLG
nsDeviceContextSpecOS2::PrnDlg
;
69 //----------------------------------------------------------------------------------
70 // The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecOS2
71 // The PrinterEnumerator creates the printer info
72 // but the nsDeviceContextSpecOS2 cleans it up
73 // If it gets created (via the Page Setup Dialog) but the user never prints anything
74 // then it will never be delete, so this class takes care of that.
75 class GlobalPrinters
{
77 static GlobalPrinters
* GetInstance() { return &mGlobalPrinters
; }
78 ~GlobalPrinters() { FreeGlobalPrinters(); }
80 void FreeGlobalPrinters();
81 nsresult
InitializeGlobalPrinters();
83 PRBool
PrintersAreAllocated() { return mGlobalPrinterList
!= nsnull
; }
84 PRUint32
GetNumPrinters() { return mGlobalNumPrinters
; }
85 nsString
* GetStringAt(PRInt32 aInx
) { return &mGlobalPrinterList
->ElementAt(aInx
); }
86 void GetDefaultPrinterName(PRUnichar
*& aDefaultPrinterName
);
91 static GlobalPrinters mGlobalPrinters
;
92 static nsTArray
<nsString
>* mGlobalPrinterList
;
93 static ULONG mGlobalNumPrinters
;
98 GlobalPrinters
GlobalPrinters::mGlobalPrinters
;
99 nsTArray
<nsString
>* GlobalPrinters::mGlobalPrinterList
= nsnull
;
100 ULONG
GlobalPrinters::mGlobalNumPrinters
= 0;
103 nsDeviceContextSpecOS2::nsDeviceContextSpecOS2()
104 : mQueue(nsnull
), mPrintDC(nsnull
), mPrintingStarted(PR_FALSE
)
108 nsDeviceContextSpecOS2::~nsDeviceContextSpecOS2()
111 PrnClosePrinter(mQueue
);
114 NS_IMPL_ISUPPORTS1(nsDeviceContextSpecOS2
, nsIDeviceContextSpec
)
116 void SetupDevModeFromSettings(ULONG printer
, nsIPrintSettings
* aPrintSettings
)
118 if (aPrintSettings
) {
119 int bufferSize
= 3 * sizeof(DJP_ITEM
);
120 PBYTE pDJP_Buffer
= new BYTE
[bufferSize
];
121 memset(pDJP_Buffer
, 0, bufferSize
);
122 PDJP_ITEM pDJP
= (PDJP_ITEM
) pDJP_Buffer
;
124 HDC hdc
= nsDeviceContextSpecOS2::PrnDlg
.GetDCHandle(printer
);
125 char* driver
= nsDeviceContextSpecOS2::PrnDlg
.GetDriverType(printer
);
129 aPrintSettings
->GetOrientation(&orientation
);
130 if (!strcmp(driver
, "LASERJET"))
131 pDJP
->lType
= DJP_ALL
;
133 pDJP
->lType
= DJP_CURRENT
;
134 pDJP
->cb
= sizeof(DJP_ITEM
);
135 pDJP
->ulNumReturned
= 1;
136 pDJP
->ulProperty
= DJP_SJ_ORIENTATION
;
137 pDJP
->ulValue
= orientation
== nsIPrintSettings::kPortraitOrientation
?DJP_ORI_PORTRAIT
:DJP_ORI_LANDSCAPE
;
140 // Setup Number of Copies
142 aPrintSettings
->GetNumCopies(&copies
);
143 pDJP
->cb
= sizeof(DJP_ITEM
);
144 pDJP
->lType
= DJP_CURRENT
;
145 pDJP
->ulNumReturned
= 1;
146 pDJP
->ulProperty
= DJP_SJ_COPIES
;
147 pDJP
->ulValue
= copies
;
150 pDJP
->cb
= sizeof(DJP_ITEM
);
151 pDJP
->lType
= DJP_NONE
;
152 pDJP
->ulNumReturned
= 1;
153 pDJP
->ulProperty
= 0;
156 LONG driverSize
= nsDeviceContextSpecOS2::PrnDlg
.GetPrintDriverSize(printer
);
157 GreEscape (hdc
, DEVESC_SETJOBPROPERTIES
, bufferSize
, pDJP_Buffer
,
158 &driverSize
, PBYTE(nsDeviceContextSpecOS2::PrnDlg
.GetPrintDriver(printer
)));
160 delete [] pDJP_Buffer
;
165 nsresult
nsDeviceContextSpecOS2::SetPrintSettingsFromDevMode(nsIPrintSettings
* aPrintSettings
, ULONG printer
)
167 if (aPrintSettings
== nsnull
)
168 return NS_ERROR_FAILURE
;
170 int bufferSize
= 3 * sizeof(DJP_ITEM
);
171 PBYTE pDJP_Buffer
= new BYTE
[bufferSize
];
172 memset(pDJP_Buffer
, 0, bufferSize
);
173 PDJP_ITEM pDJP
= (PDJP_ITEM
) pDJP_Buffer
;
175 HDC hdc
= nsDeviceContextSpecOS2::PrnDlg
.GetDCHandle(printer
);
177 //Get Number of Copies from Job Properties
178 pDJP
->lType
= DJP_CURRENT
;
179 pDJP
->cb
= sizeof(DJP_ITEM
);
180 pDJP
->ulNumReturned
= 1;
181 pDJP
->ulProperty
= DJP_SJ_COPIES
;
185 //Get Orientation from Job Properties
186 pDJP
->lType
= DJP_CURRENT
;
187 pDJP
->cb
= sizeof(DJP_ITEM
);
188 pDJP
->ulNumReturned
= 1;
189 pDJP
->ulProperty
= DJP_SJ_ORIENTATION
;
193 pDJP
->lType
= DJP_NONE
;
194 pDJP
->cb
= sizeof(DJP_ITEM
);
195 pDJP
->ulNumReturned
= 1;
196 pDJP
->ulProperty
= 0;
199 LONG driverSize
= nsDeviceContextSpecOS2::PrnDlg
.GetPrintDriverSize(printer
);
200 LONG rc
= GreEscape(hdc
, DEVESC_QUERYJOBPROPERTIES
, bufferSize
, pDJP_Buffer
,
201 &driverSize
, PBYTE(nsDeviceContextSpecOS2::PrnDlg
.GetPrintDriver(printer
)));
203 pDJP
= (PDJP_ITEM
) pDJP_Buffer
;
204 if ((rc
== DEV_OK
) || (rc
== DEV_WARNING
)) {
205 while (pDJP
->lType
!= DJP_NONE
) {
206 if ((pDJP
->ulProperty
== DJP_SJ_ORIENTATION
) && (pDJP
->lType
> 0)){
207 if ((pDJP
->ulValue
== DJP_ORI_PORTRAIT
) || (pDJP
->ulValue
== DJP_ORI_REV_PORTRAIT
))
208 aPrintSettings
->SetOrientation(nsIPrintSettings::kPortraitOrientation
);
210 aPrintSettings
->SetOrientation(nsIPrintSettings::kLandscapeOrientation
);
212 if ((pDJP
->ulProperty
== DJP_SJ_COPIES
) && (pDJP
->lType
> 0)){
213 aPrintSettings
->SetNumCopies(PRInt32(pDJP
->ulValue
));
215 pDJP
= DJP_NEXT_STRUCTP(pDJP
);
219 delete [] pDJP_Buffer
;
224 NS_IMETHODIMP
nsDeviceContextSpecOS2::Init(nsIWidget
*aWidget
,
225 nsIPrintSettings
* aPS
,
226 PRBool aIsPrintPreview
)
228 nsresult rv
= NS_ERROR_FAILURE
;
230 mPrintSettings
= aPS
;
231 NS_ASSERTION(aPS
, "Must have a PrintSettings!");
233 rv
= GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
239 PRBool tofile
= PR_FALSE
;
241 PRUnichar
*printer
= nsnull
;
242 PRUnichar
*printfile
= nsnull
;
244 mPrintSettings
->GetPrinterName(&printer
);
245 mPrintSettings
->GetToFileName(&printfile
);
246 mPrintSettings
->GetPrintToFile(&tofile
);
247 mPrintSettings
->GetNumCopies(&copies
);
249 if ((copies
== 0) || (copies
> 999)) {
250 GlobalPrinters::GetInstance()->FreeGlobalPrinters();
251 return NS_ERROR_FAILURE
;
254 if (printfile
!= nsnull
) {
255 // ToDo: Use LocalEncoding instead of UTF-8 (see bug 73446)
256 strcpy(mPrData
.path
, NS_ConvertUTF16toUTF8(printfile
).get());
258 if (printer
!= nsnull
)
259 strcpy(mPrData
.printer
, NS_ConvertUTF16toUTF8(printer
).get());
262 mPrData
.destination
= printPreview
;
264 mPrData
.destination
= printToFile
;
266 mPrData
.destination
= printToPrinter
;
267 mPrData
.copies
= copies
;
269 rv
= GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
273 const nsAFlatString
& printerUCS2
= NS_ConvertUTF8toUTF16(mPrData
.printer
);
274 ULONG numPrinters
= GlobalPrinters::GetInstance()->GetNumPrinters();
276 for(ULONG i
= 0; (i
< numPrinters
) && !mQueue
; i
++) {
277 if ((GlobalPrinters::GetInstance()->GetStringAt(i
)->Equals(printerUCS2
, nsCaseInsensitiveStringComparator()))) {
278 SetupDevModeFromSettings(i
, aPS
);
279 mQueue
= PrnDlg
.SetPrinterQueue(i
);
284 if (printfile
!= nsnull
)
285 nsMemory::Free(printfile
);
287 if (printer
!= nsnull
)
288 nsMemory::Free(printer
);
291 GlobalPrinters::GetInstance()->FreeGlobalPrinters();
296 NS_IMETHODIMP
nsDeviceContextSpecOS2 :: GetDestination( int &aDestination
)
298 aDestination
= mPrData
.destination
;
302 NS_IMETHODIMP
nsDeviceContextSpecOS2 :: GetPrinterName ( char **aPrinter
)
304 *aPrinter
= &mPrData
.printer
[0];
308 NS_IMETHODIMP
nsDeviceContextSpecOS2 :: GetCopies ( int &aCopies
)
310 aCopies
= mPrData
.copies
;
314 NS_IMETHODIMP
nsDeviceContextSpecOS2 :: GetPath ( char **aPath
)
316 *aPath
= &mPrData
.path
[0];
320 NS_IMETHODIMP
nsDeviceContextSpecOS2 :: GetUserCancelled( PRBool
&aCancel
)
322 aCancel
= mPrData
.cancel
;
326 /** -------------------------------------------------------
327 * Closes the printmanager if it is open.
330 NS_IMETHODIMP
nsDeviceContextSpecOS2 :: ClosePrintManager()
335 nsresult
nsDeviceContextSpecOS2::GetPRTQUEUE( PRTQUEUE
*&p
)
341 NS_IMETHODIMP
nsDeviceContextSpecOS2::GetSurfaceForPrinter(gfxASurface
**surface
)
343 NS_ASSERTION(mQueue
, "Queue can't be NULL here");
345 nsRefPtr
<gfxASurface
> newSurface
;
347 PRInt16 outputFormat
;
348 mPrintSettings
->GetOutputFormat(&outputFormat
);
350 GetDestination(printerDest
);
351 if (printerDest
!= printPreview
) {
352 // for now always set the output format to PDF, see bug 415522
353 outputFormat
= nsIPrintSettings::kOutputFormatPDF
;
354 mPrintSettings
->SetOutputFormat(outputFormat
); // save PDF format in settings
357 if (outputFormat
== nsIPrintSettings::kOutputFormatPDF
) {
358 nsXPIDLString filename
;
359 mPrintSettings
->GetToFileName(getter_Copies(filename
));
361 if (filename
.IsEmpty()) {
362 // print to a file that is visible, like one on the Desktop
363 nsCOMPtr
<nsIFile
> pdfLocation
;
364 rv
= NS_GetSpecialDirectory(NS_OS_DESKTOP_DIR
, getter_AddRefs(pdfLocation
));
365 NS_ENSURE_SUCCESS(rv
, rv
);
367 // construct a print output name using the current time, to make it
368 // unique and not overwrite existing files
369 char printName
[CCHMAXPATH
];
371 PR_ExplodeTime(PR_Now(), PR_LocalTimeParameters
, &time
);
372 snprintf(printName
, CCHMAXPATH
-1, "%s_%04d%02d%02d_%02d%02d%02d.pdf",
373 MOZ_APP_DISPLAYNAME
, time
.tm_year
, time
.tm_month
+1, time
.tm_mday
,
374 time
.tm_hour
, time
.tm_min
, time
.tm_sec
);
375 printName
[CCHMAXPATH
-1] = '\0';
377 nsCAutoString
printString(printName
);
378 rv
= pdfLocation
->AppendNative(printString
);
379 NS_ENSURE_SUCCESS(rv
, rv
);
380 rv
= pdfLocation
->GetPath(filename
);
381 NS_ENSURE_SUCCESS(rv
, rv
);
383 #ifdef debug_thebes_print
384 printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): print to filename=%s\n",
385 NS_LossyConvertUTF16toASCII(filename
).get());
388 double width
, height
;
389 mPrintSettings
->GetEffectivePageSize(&width
, &height
);
390 // convert twips to points
391 width
/= TWIPS_PER_POINT_FLOAT
;
392 height
/= TWIPS_PER_POINT_FLOAT
;
394 nsCOMPtr
<nsILocalFile
> file
= do_CreateInstance("@mozilla.org/file/local;1");
395 rv
= file
->InitWithPath(filename
);
399 nsCOMPtr
<nsIFileOutputStream
> stream
= do_CreateInstance("@mozilla.org/network/file-output-stream;1");
400 rv
= stream
->Init(file
, -1, -1, 0);
404 newSurface
= new(std::nothrow
) gfxPDFSurface(stream
, gfxSize(width
, height
));
407 GetCopies(numCopies
);
408 char *filename
= nsnull
;
409 if (printerDest
== printToFile
) {
412 mPrintingStarted
= PR_TRUE
;
413 mPrintDC
= PrnOpenDC(mQueue
, "Mozilla", numCopies
, printerDest
, filename
);
415 double width
, height
;
416 mPrintSettings
->GetEffectivePageSize(&width
, &height
);
417 #ifdef debug_thebes_print
418 printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): %fx%ftwips, copies=%d\n",
419 width
, height
, numCopies
);
422 // we need pixels, so scale from twips to the printer resolution
423 // and take into account that CAPS_*_RESOLUTION are in px/m, default
425 double hDPI
= 3937., vDPI
= 3937.;
427 if (DevQueryCaps(mPrintDC
, CAPS_HORIZONTAL_RESOLUTION
, 1, &value
))
428 hDPI
= value
* 0.0254;
429 if (DevQueryCaps(mPrintDC
, CAPS_VERTICAL_RESOLUTION
, 1, &value
))
430 vDPI
= value
* 0.0254;
431 width
= width
* hDPI
/ 1440;
432 height
= height
* vDPI
/ 1440;
433 #ifdef debug_thebes_print
434 printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): %fx%fpx (res=%fx%f)\n"
435 " expected size: %7.2f MiB\n",
436 width
, height
, hDPI
, vDPI
, width
*height
*4./1024./1024.);
439 // perhaps restrict to usable area
440 // (this or scaling down won't help, we will just get more pages and still crash!)
441 if (DevQueryCaps(mPrintDC
, CAPS_WIDTH
, 1, &value
) && width
> (double)value
)
442 width
= (double)value
;
443 if (DevQueryCaps(mPrintDC
, CAPS_HEIGHT
, 1, &value
) && height
> (double)value
)
444 height
= (double)value
;
446 #ifdef debug_thebes_print
447 printf("nsDeviceContextSpecOS2::GetSurfaceForPrinter(): capped? %fx%fpx (res=%fx%f)\n"
448 " expected size: %7.2f MiB per page\n",
449 width
, height
, hDPI
, vDPI
, width
*height
*4./1024./1024.);
452 // Now pass the created DC into the thebes surface for printing.
453 // It gets destroyed there.
454 newSurface
= new(std::nothrow
)
455 gfxOS2Surface(mPrintDC
, gfxIntSize(int(ceil(width
)), int(ceil(height
))));
459 return NS_ERROR_FAILURE
;
461 *surface
= newSurface
;
466 // Helper function to convert the string to the native codepage,
467 // similar to UnicodeToCodepage() in nsDragService.cpp.
468 char *GetACPString(const PRUnichar
* aStr
)
471 if (str
.Length() == 0) {
475 nsAutoCharBuffer buffer
;
477 WideCharToMultiByte(0, PromiseFlatString(str
).get(), str
.Length(),
479 return ToNewCString(nsDependentCString(buffer
.Elements()));
482 NS_IMETHODIMP
nsDeviceContextSpecOS2::BeginDocument(PRUnichar
* aTitle
,
483 PRUnichar
* aPrintToFileName
,
487 #ifdef debug_thebes_print
488 printf("nsDeviceContextSpecOS2[%#x]::BeginPrinting(%s, %s)\n", (unsigned)this,
489 NS_LossyConvertUTF16toASCII(nsString(aTitle
)).get(),
490 NS_LossyConvertUTF16toASCII(nsString(aPrintToFileName
)).get());
492 // don't try to send device escapes for non-native output (like PDF)
493 PRInt16 outputFormat
;
494 mPrintSettings
->GetOutputFormat(&outputFormat
);
495 if (outputFormat
!= nsIPrintSettings::kOutputFormatNative
) {
499 char *title
= GetACPString(aTitle
);
500 PCSZ pszGenericDocName
= "Mozilla Document";
501 PCSZ pszDocName
= title
? title
: pszGenericDocName
;
502 LONG lResult
= DevEscape(mPrintDC
, DEVESC_STARTDOC
,
503 strlen(pszDocName
) + 1, const_cast<BYTE
*>(pszDocName
),
504 (PLONG
)NULL
, (PBYTE
)NULL
);
505 mPrintingStarted
= PR_TRUE
;
507 nsMemory::Free(title
);
510 return lResult
== DEV_OK
? NS_OK
: NS_ERROR_GFX_PRINTER_STARTDOC
;
513 NS_IMETHODIMP
nsDeviceContextSpecOS2::EndDocument()
515 // don't try to send device escapes for non-native output (like PDF)
516 // but clear the filename to make sure that we don't overwrite it next time
517 PRInt16 outputFormat
;
518 mPrintSettings
->GetOutputFormat(&outputFormat
);
519 if (outputFormat
!= nsIPrintSettings::kOutputFormatNative
) {
520 mPrintSettings
->SetToFileName(NULL
);
521 nsCOMPtr
<nsIPrintSettingsService
> pss
= do_GetService("@mozilla.org/gfx/printsettings-service;1");
523 pss
->SavePrintSettingsToPrefs(mPrintSettings
, PR_TRUE
, nsIPrintSettings::kInitSaveToFileName
);
529 LONG lResult
= DevEscape(mPrintDC
, DEVESC_ENDDOC
, 0L, (PBYTE
)NULL
,
530 &lOutCount
, (PBYTE
)&usJobID
);
531 return lResult
== DEV_OK
? NS_OK
: NS_ERROR_GFX_PRINTER_ENDDOC
;
534 NS_IMETHODIMP
nsDeviceContextSpecOS2::BeginPage()
536 PRInt16 outputFormat
;
537 mPrintSettings
->GetOutputFormat(&outputFormat
);
538 if (outputFormat
!= nsIPrintSettings::kOutputFormatNative
) {
542 if (mPrintingStarted
) {
543 // we don't want an extra page break at the start of the document
544 mPrintingStarted
= PR_FALSE
;
547 LONG lResult
= DevEscape(mPrintDC
, DEVESC_NEWFRAME
, 0L, (PBYTE
)NULL
,
548 (PLONG
)NULL
, (PBYTE
)NULL
);
549 return lResult
== DEV_OK
? NS_OK
: NS_ERROR_GFX_PRINTER_STARTPAGE
;
552 NS_IMETHODIMP
nsDeviceContextSpecOS2::EndPage()
557 // Printer Enumerator
558 nsPrinterEnumeratorOS2::nsPrinterEnumeratorOS2()
562 NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorOS2
, nsIPrinterEnumerator
)
564 NS_IMETHODIMP
nsPrinterEnumeratorOS2::GetPrinterNameList(nsIStringEnumerator
**aPrinterNameList
)
566 NS_ENSURE_ARG_POINTER(aPrinterNameList
);
567 *aPrinterNameList
= nsnull
;
569 nsDeviceContextSpecOS2::PrnDlg
.RefreshPrintQueue();
571 nsresult rv
= GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
576 ULONG numPrinters
= GlobalPrinters::GetInstance()->GetNumPrinters();
577 nsTArray
<nsString
> *printers
= new nsTArray
<nsString
>(numPrinters
);
579 GlobalPrinters::GetInstance()->FreeGlobalPrinters();
580 return NS_ERROR_OUT_OF_MEMORY
;
584 while( count
< numPrinters
)
586 printers
->AppendElement(*GlobalPrinters::GetInstance()->GetStringAt(count
++));
588 GlobalPrinters::GetInstance()->FreeGlobalPrinters();
590 return NS_NewAdoptingStringEnumerator(aPrinterNameList
, printers
);
593 NS_IMETHODIMP
nsPrinterEnumeratorOS2::GetDefaultPrinterName(PRUnichar
* *aDefaultPrinterName
)
595 NS_ENSURE_ARG_POINTER(aDefaultPrinterName
);
596 GlobalPrinters::GetInstance()->GetDefaultPrinterName(*aDefaultPrinterName
);
600 /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */
601 NS_IMETHODIMP
nsPrinterEnumeratorOS2::InitPrintSettingsFromPrinter(const PRUnichar
*aPrinterName
, nsIPrintSettings
*aPrintSettings
)
603 NS_ENSURE_ARG_POINTER(aPrinterName
);
604 NS_ENSURE_ARG_POINTER(aPrintSettings
);
609 if (NS_FAILED(GlobalPrinters::GetInstance()->InitializeGlobalPrinters()))
610 return NS_ERROR_FAILURE
;
612 ULONG numPrinters
= GlobalPrinters::GetInstance()->GetNumPrinters();
613 for(ULONG i
= 0; i
< numPrinters
; i
++) {
614 if ((GlobalPrinters::GetInstance()->GetStringAt(i
)->Equals(aPrinterName
, nsCaseInsensitiveStringComparator())))
615 nsDeviceContextSpecOS2::SetPrintSettingsFromDevMode(aPrintSettings
, i
);
618 // Free them, we won't need them for a while
619 GlobalPrinters::GetInstance()->FreeGlobalPrinters();
620 aPrintSettings
->SetIsInitializedFromPrinter(PR_TRUE
);
624 NS_IMETHODIMP
nsPrinterEnumeratorOS2::DisplayPropertiesDlg(const PRUnichar
*aPrinter
, nsIPrintSettings
*aPrintSettings
)
626 nsresult rv
= GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
631 ULONG numPrinters
= GlobalPrinters::GetInstance()->GetNumPrinters();
632 for(ULONG i
= 0; i
< numPrinters
; i
++) {
633 if ((GlobalPrinters::GetInstance()->GetStringAt(i
)->Equals(aPrinter
, nsCaseInsensitiveStringComparator()))) {
634 SetupDevModeFromSettings(i
, aPrintSettings
);
635 if ( nsDeviceContextSpecOS2::PrnDlg
.ShowProperties(i
) ) {
636 nsDeviceContextSpecOS2::SetPrintSettingsFromDevMode(aPrintSettings
, i
);
639 return NS_ERROR_FAILURE
;
643 return NS_ERROR_FAILURE
;
646 nsresult
GlobalPrinters::InitializeGlobalPrinters ()
648 if (PrintersAreAllocated())
651 mGlobalNumPrinters
= 0;
652 mGlobalNumPrinters
= nsDeviceContextSpecOS2::PrnDlg
.GetNumPrinters();
653 if (!mGlobalNumPrinters
)
654 return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE
;
656 mGlobalPrinterList
= new nsTArray
<nsString
>();
657 if (!mGlobalPrinterList
)
658 return NS_ERROR_OUT_OF_MEMORY
;
661 nsCOMPtr
<nsIPrefBranch
> pPrefs
= do_GetService(NS_PREFSERVICE_CONTRACTID
, &rv
);
662 BOOL prefFailed
= NS_FAILED(rv
); // don't return on failure, optional feature
664 for (ULONG i
= 0; i
< mGlobalNumPrinters
; i
++) {
665 nsXPIDLCString printer
;
666 nsDeviceContextSpecOS2::PrnDlg
.GetPrinter(i
, getter_Copies(printer
));
668 nsAutoChar16Buffer printerName
;
669 PRInt32 printerNameLength
;
670 rv
= MultiByteToWideChar(0, printer
, strlen(printer
),
671 printerName
, printerNameLength
);
672 mGlobalPrinterList
->AppendElement(nsDependentString(printerName
.Elements()));
674 // store printer description in prefs for the print dialog
676 nsCAutoString printerDescription
;
677 printerDescription
= nsCAutoString(nsDeviceContextSpecOS2::PrnDlg
.GetPrintDriver(i
)->szDeviceName
);
678 printerDescription
+= " (";
679 printerDescription
+= nsCAutoString(nsDeviceContextSpecOS2::PrnDlg
.GetDriverType(i
));
680 printerDescription
+= ")";
681 pPrefs
->SetCharPref(nsPrintfCString(256,
682 "print.printer_%s.printer_description",
683 printer
.get()).get(),
684 printerDescription
.get());
690 void GlobalPrinters::GetDefaultPrinterName(PRUnichar
*& aDefaultPrinterName
)
692 aDefaultPrinterName
= nsnull
;
694 nsresult rv
= GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
698 if (GetNumPrinters() == 0)
701 // the default printer is always index 0
702 nsXPIDLCString printer
;
703 nsDeviceContextSpecOS2::PrnDlg
.GetPrinter(0, getter_Copies(printer
));
705 nsAutoChar16Buffer printerName
;
706 PRInt32 printerNameLength
;
707 MultiByteToWideChar(0, printer
, strlen(printer
), printerName
,
709 aDefaultPrinterName
= ToNewUnicode(nsDependentString(printerName
.Elements()));
711 GlobalPrinters::GetInstance()->FreeGlobalPrinters();
714 void GlobalPrinters::FreeGlobalPrinters()
716 delete mGlobalPrinterList
;
717 mGlobalPrinterList
= nsnull
;
718 mGlobalNumPrinters
= 0;