1 : /* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
2 : /* ***** BEGIN LICENSE BLOCK *****
3 : * Version: MPL 1.1/GPL 2.0/LGPL 2.1
4 : *
5 : * The contents of this file are subject to the Mozilla Public License Version
6 : * 1.1 (the "License"); you may not use this file except in compliance with
7 : * the License. You may obtain a copy of the License at
8 : * http://www.mozilla.org/MPL/
9 : *
10 : * Software distributed under the License is distributed on an "AS IS" basis,
11 : * WITHOUT WARRANTY OF ANY KIND, either express or implied. See the License
12 : * for the specific language governing rights and limitations under the
13 : * License.
14 : *
15 : * The Original Code is mozilla.org code.
16 : *
17 : * The Initial Developer of the Original Code is
18 : * Netscape Communications Corporation.
19 : * Portions created by the Initial Developer are Copyright (C) 1998
20 : * the Initial Developer. All Rights Reserved.
21 : *
22 : * Contributor(s):
23 : * Roland Mainz <roland.mainz@informatik.med.uni-giessen.de>
24 : * Ken Herron <kherron+mozilla@fmailbox.com>
25 : * Julien Lafon <julien.lafon@gmail.com>
26 : * Michael Ventnor <m.ventnor@gmail.com>
27 : *
28 : * Alternatively, the contents of this file may be used under the terms of
29 : * either of the GNU General Public License Version 2 or later (the "GPL"),
30 : * or the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
31 : * in which case the provisions of the GPL or the LGPL are applicable instead
32 : * of those above. If you wish to allow use of your version of this file only
33 : * under the terms of either the GPL or the LGPL, and not to allow others to
34 : * use your version of this file under the terms of the MPL, indicate your
35 : * decision by deleting the provisions above and replace them with the notice
36 : * and other provisions required by the GPL or the LGPL. If you do not delete
37 : * the provisions above, a recipient may use your version of this file under
38 : * the terms of any one of the MPL, the GPL or the LGPL.
39 : *
40 : * ***** END LICENSE BLOCK ***** */
41 :
42 : /* Store per-printer features in temp. prefs vars that the
43 : * print dialog can pick them up... */
44 : #define SET_PRINTER_FEATURES_VIA_PREFS 1
45 : #define PRINTERFEATURES_PREF "print.tmp.printerfeatures"
46 :
47 : #ifdef MOZ_LOGGING
48 : #define FORCE_PR_LOG 1 /* Allow logging in the release build */
49 : #endif /* MOZ_LOGGING */
50 : #include "prlog.h"
51 :
52 : #include "plstr.h"
53 :
54 : #include "nsDeviceContextSpecG.h"
55 :
56 : #include "prenv.h" /* for PR_GetEnv */
57 :
58 : #include "nsPrintfCString.h"
59 : #include "nsReadableUtils.h"
60 : #include "nsStringEnumerator.h"
61 : #include "nsIServiceManager.h"
62 :
63 : #include "nsPSPrinters.h"
64 : #include "nsPaperPS.h" /* Paper size list */
65 :
66 : #include "nsPrintSettingsGTK.h"
67 :
68 : #include "nsIFileStreams.h"
69 : #include "nsILocalFile.h"
70 : #include "nsTArray.h"
71 :
72 : #include "mozilla/Preferences.h"
73 :
74 : #include <unistd.h>
75 : #include <sys/types.h>
76 : #include <sys/stat.h>
77 :
78 : using namespace mozilla;
79 :
80 : #ifdef PR_LOGGING
81 1464 : static PRLogModuleInfo *DeviceContextSpecGTKLM = PR_NewLogModule("DeviceContextSpecGTK");
82 : #endif /* PR_LOGGING */
83 : /* Macro to make lines shorter */
84 : #define DO_PR_DEBUG_LOG(x) PR_LOG(DeviceContextSpecGTKLM, PR_LOG_DEBUG, x)
85 :
86 : //----------------------------------------------------------------------------------
87 : // The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecGTK
88 : // The PrinterEnumerator creates the printer info
89 : // but the nsDeviceContextSpecGTK cleans it up
90 : // If it gets created (via the Page Setup Dialog) but the user never prints anything
91 : // then it will never be delete, so this class takes care of that.
92 : class GlobalPrinters {
93 : public:
94 0 : static GlobalPrinters* GetInstance() { return &mGlobalPrinters; }
95 1487 : ~GlobalPrinters() { FreeGlobalPrinters(); }
96 :
97 : void FreeGlobalPrinters();
98 : nsresult InitializeGlobalPrinters();
99 :
100 0 : bool PrintersAreAllocated() { return mGlobalPrinterList != nsnull; }
101 0 : PRUint32 GetNumPrinters()
102 0 : { return mGlobalPrinterList ? mGlobalPrinterList->Length() : 0; }
103 0 : nsString* GetStringAt(PRInt32 aInx) { return &mGlobalPrinterList->ElementAt(aInx); }
104 : void GetDefaultPrinterName(PRUnichar **aDefaultPrinterName);
105 :
106 : protected:
107 1464 : GlobalPrinters() {}
108 :
109 : static GlobalPrinters mGlobalPrinters;
110 : static nsTArray<nsString>* mGlobalPrinterList;
111 : };
112 :
113 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
114 : /* "Prototype" for the new nsPrinterFeatures service */
115 : class nsPrinterFeatures {
116 : public:
117 : nsPrinterFeatures( const char *printername );
118 0 : ~nsPrinterFeatures() {}
119 :
120 : /* Does this printer allow to set/change the paper size ? */
121 : void SetCanChangePaperSize( bool aCanSetPaperSize );
122 : /* Does this Mozilla print module allow set/change the paper size ? */
123 : void SetSupportsPaperSizeChange( bool aSupportsPaperSizeChange );
124 : /* Set number of paper size records and the records itself */
125 : void SetNumPaperSizeRecords( PRInt32 aCount );
126 : void SetPaperRecord( PRInt32 aIndex, const char *aName, PRInt32 aWidthMM, PRInt32 aHeightMM, bool aIsInch );
127 :
128 : /* Does this printer allow to set/change the content orientation ? */
129 : void SetCanChangeOrientation( bool aCanSetOrientation );
130 : /* Does this Mozilla print module allow set/change the content orientation ? */
131 : void SetSupportsOrientationChange( bool aSupportsOrientationChange );
132 : /* Set number of orientation records and the records itself */
133 : void SetNumOrientationRecords( PRInt32 aCount );
134 : void SetOrientationRecord( PRInt32 aIndex, const char *aName );
135 :
136 : /* Does this printer allow to set/change the plex mode ? */
137 : void SetCanChangePlex( bool aCanSetPlex );
138 : /* Does this Mozilla print module allow set/change the plex mode ? */
139 : void SetSupportsPlexChange( bool aSupportsPlexChange );
140 : /* Set number of plex records and the records itself */
141 : void SetNumPlexRecords( PRInt32 aCount );
142 : void SetPlexRecord( PRInt32 aIndex, const char *aName );
143 :
144 : /* Does this printer allow to set/change the resolution name ? */
145 : void SetCanChangeResolutionName( bool aCanSetResolutionName );
146 : /* Does this Mozilla print module allow set/change the resolution name ? */
147 : void SetSupportsResolutionNameChange( bool aSupportsResolutionChange );
148 : /* Set number of resolution records and the records itself */
149 : void SetNumResolutionNameRecords( PRInt32 aCount );
150 : void SetResolutionNameRecord( PRInt32 aIndex, const char *aName );
151 :
152 : /* Does this printer allow to set/change the colorspace ? */
153 : void SetCanChangeColorspace( bool aCanSetColorspace );
154 : /* Does this Mozilla print module allow set/change the colorspace ? */
155 : void SetSupportsColorspaceChange( bool aSupportsColorspace );
156 : /* Set number of colorspace records and the records itself */
157 : void SetNumColorspaceRecords( PRInt32 aCount );
158 : void SetColorspaceRecord( PRInt32 aIndex, const char *aName );
159 :
160 : /* Does this device allow to set/change the usage of the internal grayscale mode ? */
161 : void SetCanChangePrintInColor( bool aCanSetPrintInColor );
162 : /* Does this printer allow to set/change the usage of the internal grayscale mode ? */
163 : void SetSupportsPrintInColorChange( bool aSupportPrintInColorChange );
164 :
165 : /* Does this device allow to set/change the usage of font download to the printer? */
166 : void SetCanChangeDownloadFonts( bool aCanSetDownloadFonts );
167 : /* Does this printer allow to set/change the usage of font download to the printer? */
168 : void SetSupportsDownloadFontsChange( bool aSupportDownloadFontsChange );
169 :
170 : /* Does this device allow to set/change the job title ? */
171 : void SetCanChangeJobTitle( bool aCanSetJobTitle );
172 : /* Does this printer allow to set/change the job title ? */
173 : void SetSupportsJobTitleChange( bool aSupportJobTitleChange );
174 :
175 : /* Does this device allow to set/change the spooler command ? */
176 : void SetCanChangeSpoolerCommand( bool aCanSetSpoolerCommand );
177 : /* Does this printer allow to set/change the spooler command ? */
178 : void SetSupportsSpoolerCommandChange( bool aSupportSpoolerCommandChange );
179 :
180 : /* Does this device allow to set/change number of copies for an document ? */
181 : void SetCanChangeNumCopies( bool aCanSetNumCopies );
182 :
183 : private:
184 : /* private helper methods */
185 : void SetBoolValue( const char *tagname, bool value );
186 : void SetIntValue( const char *tagname, PRInt32 value );
187 : void SetCharValue( const char *tagname, const char *value );
188 :
189 : nsXPIDLCString mPrinterName;
190 : };
191 :
192 0 : void nsPrinterFeatures::SetBoolValue( const char *tagname, bool value )
193 : {
194 : nsPrintfCString prefName(256, PRINTERFEATURES_PREF ".%s.%s",
195 0 : mPrinterName.get(), tagname);
196 0 : Preferences::SetBool(prefName.get(), value);
197 0 : }
198 :
199 0 : void nsPrinterFeatures::SetIntValue( const char *tagname, PRInt32 value )
200 : {
201 : nsPrintfCString prefName(256, PRINTERFEATURES_PREF ".%s.%s",
202 0 : mPrinterName.get(), tagname);
203 0 : Preferences::SetInt(prefName.get(), value);
204 0 : }
205 :
206 0 : void nsPrinterFeatures::SetCharValue( const char *tagname, const char *value )
207 : {
208 : nsPrintfCString prefName(256, PRINTERFEATURES_PREF ".%s.%s",
209 0 : mPrinterName.get(), tagname);
210 0 : Preferences::SetCString(prefName.get(), value);
211 0 : }
212 :
213 0 : nsPrinterFeatures::nsPrinterFeatures( const char *printername )
214 : {
215 0 : DO_PR_DEBUG_LOG(("nsPrinterFeatures::nsPrinterFeatures('%s')\n", printername));
216 0 : mPrinterName.Assign(printername);
217 :
218 0 : SetBoolValue("has_special_printerfeatures", true);
219 0 : }
220 :
221 0 : void nsPrinterFeatures::SetCanChangePaperSize( bool aCanSetPaperSize )
222 : {
223 0 : SetBoolValue("can_change_paper_size", aCanSetPaperSize);
224 0 : }
225 :
226 0 : void nsPrinterFeatures::SetSupportsPaperSizeChange( bool aSupportsPaperSizeChange )
227 : {
228 0 : SetBoolValue("supports_paper_size_change", aSupportsPaperSizeChange);
229 0 : }
230 :
231 : /* Set number of paper size records and the records itself */
232 0 : void nsPrinterFeatures::SetNumPaperSizeRecords( PRInt32 aCount )
233 : {
234 0 : SetIntValue("paper.count", aCount);
235 0 : }
236 :
237 0 : void nsPrinterFeatures::SetPaperRecord(PRInt32 aIndex, const char *aPaperName, PRInt32 aWidthMM, PRInt32 aHeightMM, bool aIsInch)
238 : {
239 0 : SetCharValue(nsPrintfCString(256, "paper.%d.name", aIndex).get(), aPaperName);
240 0 : SetIntValue( nsPrintfCString(256, "paper.%d.width_mm", aIndex).get(), aWidthMM);
241 0 : SetIntValue( nsPrintfCString(256, "paper.%d.height_mm", aIndex).get(), aHeightMM);
242 0 : SetBoolValue(nsPrintfCString(256, "paper.%d.is_inch", aIndex).get(), aIsInch);
243 0 : }
244 :
245 0 : void nsPrinterFeatures::SetCanChangeOrientation( bool aCanSetOrientation )
246 : {
247 0 : SetBoolValue("can_change_orientation", aCanSetOrientation);
248 0 : }
249 :
250 0 : void nsPrinterFeatures::SetSupportsOrientationChange( bool aSupportsOrientationChange )
251 : {
252 0 : SetBoolValue("supports_orientation_change", aSupportsOrientationChange);
253 0 : }
254 :
255 0 : void nsPrinterFeatures::SetNumOrientationRecords( PRInt32 aCount )
256 : {
257 0 : SetIntValue("orientation.count", aCount);
258 0 : }
259 :
260 0 : void nsPrinterFeatures::SetOrientationRecord( PRInt32 aIndex, const char *aOrientationName )
261 : {
262 0 : SetCharValue(nsPrintfCString(256, "orientation.%d.name", aIndex).get(), aOrientationName);
263 0 : }
264 :
265 0 : void nsPrinterFeatures::SetCanChangePlex( bool aCanSetPlex )
266 : {
267 0 : SetBoolValue("can_change_plex", aCanSetPlex);
268 0 : }
269 :
270 0 : void nsPrinterFeatures::SetSupportsPlexChange( bool aSupportsPlexChange )
271 : {
272 0 : SetBoolValue("supports_plex_change", aSupportsPlexChange);
273 0 : }
274 :
275 0 : void nsPrinterFeatures::SetNumPlexRecords( PRInt32 aCount )
276 : {
277 0 : SetIntValue("plex.count", aCount);
278 0 : }
279 :
280 0 : void nsPrinterFeatures::SetPlexRecord( PRInt32 aIndex, const char *aPlexName )
281 : {
282 0 : SetCharValue(nsPrintfCString(256, "plex.%d.name", aIndex).get(), aPlexName);
283 0 : }
284 :
285 0 : void nsPrinterFeatures::SetCanChangeResolutionName( bool aCanSetResolutionName )
286 : {
287 0 : SetBoolValue("can_change_resolution", aCanSetResolutionName);
288 0 : }
289 :
290 0 : void nsPrinterFeatures::SetSupportsResolutionNameChange( bool aSupportsResolutionNameChange )
291 : {
292 0 : SetBoolValue("supports_resolution_change", aSupportsResolutionNameChange);
293 0 : }
294 :
295 0 : void nsPrinterFeatures::SetNumResolutionNameRecords( PRInt32 aCount )
296 : {
297 0 : SetIntValue("resolution.count", aCount);
298 0 : }
299 :
300 0 : void nsPrinterFeatures::SetResolutionNameRecord( PRInt32 aIndex, const char *aResolutionName )
301 : {
302 0 : SetCharValue(nsPrintfCString(256, "resolution.%d.name", aIndex).get(), aResolutionName);
303 0 : }
304 :
305 0 : void nsPrinterFeatures::SetCanChangeColorspace( bool aCanSetColorspace )
306 : {
307 0 : SetBoolValue("can_change_colorspace", aCanSetColorspace);
308 0 : }
309 :
310 0 : void nsPrinterFeatures::SetSupportsColorspaceChange( bool aSupportsColorspaceChange )
311 : {
312 0 : SetBoolValue("supports_colorspace_change", aSupportsColorspaceChange);
313 0 : }
314 :
315 0 : void nsPrinterFeatures::SetNumColorspaceRecords( PRInt32 aCount )
316 : {
317 0 : SetIntValue("colorspace.count", aCount);
318 0 : }
319 :
320 0 : void nsPrinterFeatures::SetColorspaceRecord( PRInt32 aIndex, const char *aColorspace )
321 : {
322 0 : SetCharValue(nsPrintfCString(256, "colorspace.%d.name", aIndex).get(), aColorspace);
323 0 : }
324 :
325 0 : void nsPrinterFeatures::SetCanChangeDownloadFonts( bool aCanSetDownloadFonts )
326 : {
327 0 : SetBoolValue("can_change_downloadfonts", aCanSetDownloadFonts);
328 0 : }
329 :
330 0 : void nsPrinterFeatures::SetSupportsDownloadFontsChange( bool aSupportDownloadFontsChange )
331 : {
332 0 : SetBoolValue("supports_downloadfonts_change", aSupportDownloadFontsChange);
333 0 : }
334 :
335 0 : void nsPrinterFeatures::SetCanChangePrintInColor( bool aCanSetPrintInColor )
336 : {
337 0 : SetBoolValue("can_change_printincolor", aCanSetPrintInColor);
338 0 : }
339 :
340 0 : void nsPrinterFeatures::SetSupportsPrintInColorChange( bool aSupportPrintInColorChange )
341 : {
342 0 : SetBoolValue("supports_printincolor_change", aSupportPrintInColorChange);
343 0 : }
344 :
345 0 : void nsPrinterFeatures::SetCanChangeSpoolerCommand( bool aCanSetSpoolerCommand )
346 : {
347 0 : SetBoolValue("can_change_spoolercommand", aCanSetSpoolerCommand);
348 0 : }
349 :
350 0 : void nsPrinterFeatures::SetSupportsSpoolerCommandChange( bool aSupportSpoolerCommandChange )
351 : {
352 0 : SetBoolValue("supports_spoolercommand_change", aSupportSpoolerCommandChange);
353 0 : }
354 :
355 0 : void nsPrinterFeatures::SetCanChangeJobTitle( bool aCanSetJobTitle )
356 : {
357 0 : SetBoolValue("can_change_jobtitle", aCanSetJobTitle);
358 0 : }
359 :
360 0 : void nsPrinterFeatures::SetSupportsJobTitleChange( bool aSupportsJobTitle )
361 : {
362 0 : SetBoolValue("supports_jobtitle_change", aSupportsJobTitle);
363 0 : }
364 :
365 0 : void nsPrinterFeatures::SetCanChangeNumCopies( bool aCanSetNumCopies )
366 : {
367 0 : SetBoolValue("can_change_num_copies", aCanSetNumCopies);
368 0 : }
369 :
370 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
371 :
372 : //---------------
373 : // static members
374 1464 : GlobalPrinters GlobalPrinters::mGlobalPrinters;
375 : nsTArray<nsString>* GlobalPrinters::mGlobalPrinterList = nsnull;
376 : //---------------
377 :
378 0 : nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()
379 : : mPrintJob(NULL)
380 : , mGtkPrinter(NULL)
381 : , mGtkPrintSettings(NULL)
382 0 : , mGtkPageSetup(NULL)
383 : {
384 0 : DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::nsDeviceContextSpecGTK()\n"));
385 0 : }
386 :
387 0 : nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()
388 : {
389 0 : DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::~nsDeviceContextSpecGTK()\n"));
390 :
391 0 : if (mGtkPageSetup) {
392 0 : g_object_unref(mGtkPageSetup);
393 : }
394 :
395 0 : if (mGtkPrintSettings) {
396 0 : g_object_unref(mGtkPrintSettings);
397 : }
398 0 : }
399 :
400 0 : NS_IMPL_ISUPPORTS1(nsDeviceContextSpecGTK,
401 : nsIDeviceContextSpec)
402 :
403 : #include "gfxPDFSurface.h"
404 : #include "gfxPSSurface.h"
405 0 : NS_IMETHODIMP nsDeviceContextSpecGTK::GetSurfaceForPrinter(gfxASurface **aSurface)
406 : {
407 0 : *aSurface = nsnull;
408 :
409 : const char *path;
410 0 : GetPath(&path);
411 :
412 : double width, height;
413 0 : mPrintSettings->GetEffectivePageSize(&width, &height);
414 :
415 : // convert twips to points
416 0 : width /= TWIPS_PER_POINT_FLOAT;
417 0 : height /= TWIPS_PER_POINT_FLOAT;
418 :
419 0 : DO_PR_DEBUG_LOG(("\"%s\", %f, %f\n", path, width, height));
420 : nsresult rv;
421 :
422 : // Spool file. Use Glib's temporary file function since we're
423 : // already dependent on the gtk software stack.
424 : gchar *buf;
425 0 : gint fd = g_file_open_tmp("XXXXXX.tmp", &buf, nsnull);
426 0 : if (-1 == fd)
427 0 : return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
428 0 : close(fd);
429 :
430 0 : rv = NS_NewNativeLocalFile(nsDependentCString(buf), false,
431 0 : getter_AddRefs(mSpoolFile));
432 0 : if (NS_FAILED(rv)) {
433 0 : unlink(buf);
434 0 : return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
435 : }
436 :
437 0 : mSpoolName = buf;
438 0 : g_free(buf);
439 :
440 0 : mSpoolFile->SetPermissions(0600);
441 :
442 0 : nsCOMPtr<nsIFileOutputStream> stream = do_CreateInstance("@mozilla.org/network/file-output-stream;1");
443 0 : rv = stream->Init(mSpoolFile, -1, -1, 0);
444 0 : if (NS_FAILED(rv))
445 0 : return rv;
446 :
447 : PRInt16 format;
448 0 : mPrintSettings->GetOutputFormat(&format);
449 :
450 0 : nsRefPtr<gfxASurface> surface;
451 0 : gfxSize surfaceSize(width, height);
452 :
453 : // Determine the real format with some GTK magic
454 0 : if (format == nsIPrintSettings::kOutputFormatNative) {
455 0 : if (mIsPPreview) {
456 : // There is nothing to detect on Print Preview, use PS.
457 0 : format = nsIPrintSettings::kOutputFormatPS;
458 : } else {
459 0 : const gchar* fmtGTK = gtk_print_settings_get(mGtkPrintSettings, GTK_PRINT_SETTINGS_OUTPUT_FILE_FORMAT);
460 0 : if (!fmtGTK && GTK_IS_PRINTER(mGtkPrinter)) {
461 : // Likely not print-to-file, check printer's capabilities
462 :
463 : // Prior to gtk 2.24, gtk_printer_accepts_pdf() and
464 : // gtk_printer_accepts_ps() always returned true regardless of the
465 : // printer's capability.
466 0 : if (gtk_major_version > 2 ||
467 : (gtk_major_version == 2 && gtk_minor_version >= 24)) {
468 : format =
469 0 : gtk_printer_accepts_pdf(mGtkPrinter) ?
470 : static_cast<PRInt16>(nsIPrintSettings::kOutputFormatPDF) :
471 0 : static_cast<PRInt16>(nsIPrintSettings::kOutputFormatPS);
472 : } else {
473 0 : format = nsIPrintSettings::kOutputFormatPS;
474 : }
475 :
476 0 : } else if (nsDependentCString(fmtGTK).EqualsIgnoreCase("pdf")) {
477 0 : format = nsIPrintSettings::kOutputFormatPDF;
478 : } else {
479 0 : format = nsIPrintSettings::kOutputFormatPS;
480 : }
481 : }
482 : }
483 :
484 0 : if (format == nsIPrintSettings::kOutputFormatPDF) {
485 0 : surface = new gfxPDFSurface(stream, surfaceSize);
486 : } else {
487 : PRInt32 orientation;
488 0 : mPrintSettings->GetOrientation(&orientation);
489 0 : if (nsIPrintSettings::kPortraitOrientation == orientation) {
490 0 : surface = new gfxPSSurface(stream, surfaceSize, gfxPSSurface::PORTRAIT);
491 : } else {
492 0 : surface = new gfxPSSurface(stream, surfaceSize, gfxPSSurface::LANDSCAPE);
493 : }
494 : }
495 :
496 0 : if (!surface)
497 0 : return NS_ERROR_OUT_OF_MEMORY;
498 :
499 0 : surface.swap(*aSurface);
500 :
501 0 : return NS_OK;
502 : }
503 :
504 : /** -------------------------------------------------------
505 : * Initialize the nsDeviceContextSpecGTK
506 : * @update dc 2/15/98
507 : * @update syd 3/2/99
508 : */
509 0 : NS_IMETHODIMP nsDeviceContextSpecGTK::Init(nsIWidget *aWidget,
510 : nsIPrintSettings* aPS,
511 : bool aIsPrintPreview)
512 : {
513 0 : DO_PR_DEBUG_LOG(("nsDeviceContextSpecGTK::Init(aPS=%p)\n", aPS));
514 :
515 0 : if (gtk_major_version < 2 ||
516 : (gtk_major_version == 2 && gtk_minor_version < 10))
517 0 : return NS_ERROR_NOT_AVAILABLE; // I'm so sorry bz
518 :
519 0 : mPrintSettings = aPS;
520 0 : mIsPPreview = aIsPrintPreview;
521 :
522 : // This is only set by embedders
523 : bool toFile;
524 0 : aPS->GetPrintToFile(&toFile);
525 :
526 0 : mToPrinter = !toFile && !aIsPrintPreview;
527 :
528 0 : nsCOMPtr<nsPrintSettingsGTK> printSettingsGTK(do_QueryInterface(aPS));
529 0 : if (!printSettingsGTK)
530 0 : return NS_ERROR_NO_INTERFACE;
531 :
532 0 : mGtkPrinter = printSettingsGTK->GetGtkPrinter();
533 0 : mGtkPrintSettings = printSettingsGTK->GetGtkPrintSettings();
534 0 : mGtkPageSetup = printSettingsGTK->GetGtkPageSetup();
535 :
536 : // This is a horrible workaround for some printer driver bugs that treat custom page sizes different
537 : // to standard ones. If our paper object matches one of a standard one, use a standard paper size
538 : // object instead. See bug 414314 for more info.
539 0 : GtkPaperSize* geckosHackishPaperSize = gtk_page_setup_get_paper_size(mGtkPageSetup);
540 0 : GtkPaperSize* standardGtkPaperSize = gtk_paper_size_new(gtk_paper_size_get_name(geckosHackishPaperSize));
541 :
542 0 : mGtkPageSetup = gtk_page_setup_copy(mGtkPageSetup);
543 0 : mGtkPrintSettings = gtk_print_settings_copy(mGtkPrintSettings);
544 :
545 : GtkPaperSize* properPaperSize;
546 0 : if (gtk_paper_size_is_equal(geckosHackishPaperSize, standardGtkPaperSize)) {
547 0 : properPaperSize = standardGtkPaperSize;
548 : } else {
549 0 : properPaperSize = geckosHackishPaperSize;
550 : }
551 0 : gtk_print_settings_set_paper_size(mGtkPrintSettings, properPaperSize);
552 0 : gtk_page_setup_set_paper_size_and_default_margins(mGtkPageSetup, properPaperSize);
553 0 : gtk_paper_size_free(standardGtkPaperSize);
554 :
555 0 : return NS_OK;
556 : }
557 :
558 0 : NS_IMETHODIMP nsDeviceContextSpecGTK::GetPath(const char **aPath)
559 : {
560 0 : *aPath = mPath;
561 0 : return NS_OK;
562 : }
563 :
564 : /* static !! */
565 0 : nsresult nsDeviceContextSpecGTK::GetPrintMethod(const char *aPrinter, PrintMethod &aMethod)
566 : {
567 0 : aMethod = pmPostScript;
568 0 : return NS_OK;
569 : }
570 :
571 : static void
572 0 : print_callback(GtkPrintJob *aJob, gpointer aData, GError *aError) {
573 0 : g_object_unref(aJob);
574 0 : ((nsILocalFile*) aData)->Remove(false);
575 0 : }
576 :
577 : static void
578 0 : ns_release_macro(gpointer aData) {
579 0 : nsILocalFile* spoolFile = (nsILocalFile*) aData;
580 0 : NS_RELEASE(spoolFile);
581 0 : }
582 :
583 0 : NS_IMETHODIMP nsDeviceContextSpecGTK::BeginDocument(PRUnichar * aTitle, PRUnichar * aPrintToFileName,
584 : PRInt32 aStartPage, PRInt32 aEndPage)
585 : {
586 0 : if (mToPrinter) {
587 0 : if (!GTK_IS_PRINTER(mGtkPrinter))
588 0 : return NS_ERROR_FAILURE;
589 :
590 0 : mPrintJob = gtk_print_job_new(NS_ConvertUTF16toUTF8(aTitle).get(), mGtkPrinter,
591 0 : mGtkPrintSettings, mGtkPageSetup);
592 : }
593 :
594 0 : return NS_OK;
595 : }
596 :
597 0 : NS_IMETHODIMP nsDeviceContextSpecGTK::EndDocument()
598 : {
599 0 : if (mToPrinter) {
600 0 : if (!mPrintJob)
601 0 : return NS_OK; // The operation was aborted.
602 :
603 0 : if (!gtk_print_job_set_source_file(mPrintJob, mSpoolName.get(), nsnull))
604 0 : return NS_ERROR_GFX_PRINTER_COULD_NOT_OPEN_FILE;
605 :
606 0 : NS_ADDREF(mSpoolFile.get());
607 0 : gtk_print_job_send(mPrintJob, print_callback, mSpoolFile, ns_release_macro);
608 : } else {
609 : // Handle print-to-file ourselves for the benefit of embedders
610 0 : nsXPIDLString targetPath;
611 0 : nsCOMPtr<nsILocalFile> destFile;
612 0 : mPrintSettings->GetToFileName(getter_Copies(targetPath));
613 :
614 0 : nsresult rv = NS_NewNativeLocalFile(NS_ConvertUTF16toUTF8(targetPath),
615 0 : false, getter_AddRefs(destFile));
616 0 : NS_ENSURE_SUCCESS(rv, rv);
617 :
618 0 : nsAutoString destLeafName;
619 0 : rv = destFile->GetLeafName(destLeafName);
620 0 : NS_ENSURE_SUCCESS(rv, rv);
621 :
622 0 : nsCOMPtr<nsIFile> destDir;
623 0 : rv = destFile->GetParent(getter_AddRefs(destDir));
624 0 : NS_ENSURE_SUCCESS(rv, rv);
625 :
626 0 : rv = mSpoolFile->MoveTo(destDir, destLeafName);
627 0 : NS_ENSURE_SUCCESS(rv, rv);
628 :
629 : // This is the standard way to get the UNIX umask. Ugh.
630 0 : mode_t mask = umask(0);
631 0 : umask(mask);
632 : // If you're not familiar with umasks, they contain the bits of what NOT to set in the permissions
633 : // (thats because files and directories have different numbers of bits for their permissions)
634 0 : destFile->SetPermissions(0666 & ~(mask));
635 : }
636 0 : return NS_OK;
637 : }
638 :
639 : /* Get prefs for printer
640 : * Search order:
641 : * - Get prefs per printer name and module name
642 : * - Get prefs per printer name
643 : * - Get prefs per module name
644 : * - Get prefs
645 : */
646 : static
647 0 : nsresult CopyPrinterCharPref(const char *modulename, const char *printername,
648 : const char *prefname, nsCString &return_buf)
649 : {
650 0 : DO_PR_DEBUG_LOG(("CopyPrinterCharPref('%s', '%s', '%s')\n", modulename, printername, prefname));
651 :
652 0 : nsresult rv = NS_ERROR_FAILURE;
653 :
654 0 : if (printername && modulename) {
655 : /* Get prefs per printer name and module name */
656 0 : nsPrintfCString name(512, "print.%s.printer_%s.%s", modulename, printername, prefname);
657 0 : DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
658 0 : rv = Preferences::GetCString(name.get(), &return_buf);
659 : }
660 :
661 0 : if (NS_FAILED(rv)) {
662 0 : if (printername) {
663 : /* Get prefs per printer name */
664 0 : nsPrintfCString name(512, "print.printer_%s.%s", printername, prefname);
665 0 : DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
666 0 : rv = Preferences::GetCString(name.get(), &return_buf);
667 : }
668 :
669 0 : if (NS_FAILED(rv)) {
670 0 : if (modulename) {
671 : /* Get prefs per module name */
672 0 : nsPrintfCString name(512, "print.%s.%s", modulename, prefname);
673 0 : DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
674 0 : rv = Preferences::GetCString(name.get(), &return_buf);
675 : }
676 :
677 0 : if (NS_FAILED(rv)) {
678 : /* Get prefs */
679 0 : nsPrintfCString name(512, "print.%s", prefname);
680 0 : DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
681 0 : rv = Preferences::GetCString(name.get(), &return_buf);
682 : }
683 : }
684 : }
685 :
686 : #ifdef PR_LOG
687 0 : if (NS_SUCCEEDED(rv)) {
688 0 : DO_PR_DEBUG_LOG(("CopyPrinterCharPref returning '%s'.\n", return_buf.get()));
689 : }
690 : else
691 : {
692 0 : DO_PR_DEBUG_LOG(("CopyPrinterCharPref failure.\n"));
693 : }
694 : #endif /* PR_LOG */
695 :
696 0 : return rv;
697 : }
698 :
699 : // Printer Enumerator
700 0 : nsPrinterEnumeratorGTK::nsPrinterEnumeratorGTK()
701 : {
702 0 : }
703 :
704 0 : NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorGTK, nsIPrinterEnumerator)
705 :
706 0 : NS_IMETHODIMP nsPrinterEnumeratorGTK::GetPrinterNameList(nsIStringEnumerator **aPrinterNameList)
707 : {
708 0 : NS_ENSURE_ARG_POINTER(aPrinterNameList);
709 0 : *aPrinterNameList = nsnull;
710 :
711 0 : nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
712 0 : if (NS_FAILED(rv)) {
713 0 : return rv;
714 : }
715 :
716 0 : PRUint32 numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters();
717 0 : nsTArray<nsString> *printers = new nsTArray<nsString>(numPrinters);
718 0 : if (!printers) {
719 0 : GlobalPrinters::GetInstance()->FreeGlobalPrinters();
720 0 : return NS_ERROR_OUT_OF_MEMORY;
721 : }
722 :
723 0 : PRUint32 count = 0;
724 0 : while( count < numPrinters )
725 : {
726 0 : printers->AppendElement(*GlobalPrinters::GetInstance()->GetStringAt(count++));
727 : }
728 0 : GlobalPrinters::GetInstance()->FreeGlobalPrinters();
729 :
730 0 : return NS_NewAdoptingStringEnumerator(aPrinterNameList, printers);
731 : }
732 :
733 : /* readonly attribute wstring defaultPrinterName; */
734 0 : NS_IMETHODIMP nsPrinterEnumeratorGTK::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName)
735 : {
736 0 : DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::GetDefaultPrinterName()\n"));
737 0 : NS_ENSURE_ARG_POINTER(aDefaultPrinterName);
738 :
739 0 : GlobalPrinters::GetInstance()->GetDefaultPrinterName(aDefaultPrinterName);
740 :
741 0 : DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", NS_ConvertUTF16toUTF8(*aDefaultPrinterName).get()));
742 0 : return NS_OK;
743 : }
744 :
745 : /* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */
746 0 : NS_IMETHODIMP nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings)
747 : {
748 0 : DO_PR_DEBUG_LOG(("nsPrinterEnumeratorGTK::InitPrintSettingsFromPrinter()"));
749 : nsresult rv;
750 :
751 0 : NS_ENSURE_ARG_POINTER(aPrinterName);
752 0 : NS_ENSURE_ARG_POINTER(aPrintSettings);
753 :
754 0 : NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE);
755 0 : NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE);
756 :
757 0 : nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */
758 0 : printerName; /* "Stripped" name of printer */
759 0 : fullPrinterName.Assign(NS_ConvertUTF16toUTF8(aPrinterName));
760 0 : printerName.Assign(NS_ConvertUTF16toUTF8(aPrinterName));
761 0 : DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get()));
762 :
763 0 : PrintMethod type = pmInvalid;
764 0 : rv = nsDeviceContextSpecGTK::GetPrintMethod(printerName, type);
765 0 : if (NS_FAILED(rv))
766 0 : return rv;
767 :
768 : /* "Demangle" postscript printer name */
769 0 : if (type == pmPostScript) {
770 : /* Strip the printing method name from the printer,
771 : * e.g. turn "PostScript/foobar" to "foobar" */
772 0 : PRInt32 slash = printerName.FindChar('/');
773 0 : if (kNotFound != slash)
774 0 : printerName.Cut(0, slash + 1);
775 : }
776 :
777 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
778 : /* Defaults to FALSE */
779 : nsPrintfCString prefName(256,
780 : PRINTERFEATURES_PREF ".%s.has_special_printerfeatures",
781 0 : fullPrinterName.get());
782 0 : Preferences::SetBool(prefName.get(), false);
783 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
784 :
785 :
786 : /* Set filename */
787 0 : nsCAutoString filename;
788 0 : if (NS_FAILED(CopyPrinterCharPref(nsnull, printerName, "filename", filename))) {
789 : const char *path;
790 :
791 0 : if (!(path = PR_GetEnv("PWD")))
792 0 : path = PR_GetEnv("HOME");
793 :
794 0 : if (path)
795 0 : filename = nsPrintfCString(PATH_MAX, "%s/mozilla.pdf", path);
796 : else
797 0 : filename.AssignLiteral("mozilla.pdf");
798 : }
799 0 : DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get()));
800 0 : aPrintSettings->SetToFileName(NS_ConvertUTF8toUTF16(filename).get());
801 :
802 0 : aPrintSettings->SetIsInitializedFromPrinter(true);
803 :
804 0 : if (type == pmPostScript) {
805 0 : DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n"));
806 :
807 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
808 0 : nsPrinterFeatures printerFeatures(fullPrinterName);
809 :
810 0 : printerFeatures.SetSupportsPaperSizeChange(true);
811 0 : printerFeatures.SetSupportsOrientationChange(true);
812 0 : printerFeatures.SetSupportsPlexChange(false);
813 0 : printerFeatures.SetSupportsResolutionNameChange(false);
814 0 : printerFeatures.SetSupportsColorspaceChange(false);
815 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
816 :
817 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
818 0 : printerFeatures.SetCanChangeOrientation(true);
819 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
820 :
821 0 : nsCAutoString orientation;
822 0 : if (NS_SUCCEEDED(CopyPrinterCharPref("postscript", printerName,
823 : "orientation", orientation))) {
824 0 : if (orientation.LowerCaseEqualsLiteral("portrait")) {
825 0 : DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n"));
826 0 : aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
827 : }
828 0 : else if (orientation.LowerCaseEqualsLiteral("landscape")) {
829 0 : DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n"));
830 0 : aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);
831 : }
832 : else {
833 0 : DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get()));
834 : }
835 : }
836 :
837 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
838 0 : printerFeatures.SetOrientationRecord(0, "portrait");
839 0 : printerFeatures.SetOrientationRecord(1, "landscape");
840 0 : printerFeatures.SetNumOrientationRecords(2);
841 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
842 :
843 : /* PostScript module does not support changing the plex mode... */
844 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
845 0 : printerFeatures.SetCanChangePlex(false);
846 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
847 0 : DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", "default"));
848 0 : aPrintSettings->SetPlexName(NS_LITERAL_STRING("default").get());
849 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
850 0 : printerFeatures.SetPlexRecord(0, "default");
851 0 : printerFeatures.SetNumPlexRecords(1);
852 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
853 :
854 : /* PostScript module does not support changing the resolution mode... */
855 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
856 0 : printerFeatures.SetCanChangeResolutionName(false);
857 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
858 0 : DO_PR_DEBUG_LOG(("setting default resolution to '%s'\n", "default"));
859 0 : aPrintSettings->SetResolutionName(NS_LITERAL_STRING("default").get());
860 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
861 0 : printerFeatures.SetResolutionNameRecord(0, "default");
862 0 : printerFeatures.SetNumResolutionNameRecords(1);
863 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
864 :
865 : /* PostScript module does not support changing the colorspace... */
866 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
867 0 : printerFeatures.SetCanChangeColorspace(false);
868 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
869 0 : DO_PR_DEBUG_LOG(("setting default colorspace to '%s'\n", "default"));
870 0 : aPrintSettings->SetColorspace(NS_LITERAL_STRING("default").get());
871 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
872 0 : printerFeatures.SetColorspaceRecord(0, "default");
873 0 : printerFeatures.SetNumColorspaceRecords(1);
874 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
875 :
876 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
877 0 : printerFeatures.SetCanChangePaperSize(true);
878 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
879 0 : nsCAutoString papername;
880 0 : if (NS_SUCCEEDED(CopyPrinterCharPref("postscript", printerName,
881 : "paper_size", papername))) {
882 0 : nsPaperSizePS paper;
883 :
884 0 : if (paper.Find(papername.get())) {
885 0 : DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
886 : paper.Name(), paper.Width_mm(), paper.Height_mm()));
887 0 : aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
888 0 : aPrintSettings->SetPaperWidth(paper.Width_mm());
889 0 : aPrintSettings->SetPaperHeight(paper.Height_mm());
890 0 : aPrintSettings->SetPaperName(NS_ConvertASCIItoUTF16(paper.Name()).get());
891 : }
892 : else {
893 0 : DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
894 : }
895 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
896 0 : paper.First();
897 0 : int count = 0;
898 0 : while (!paper.AtEnd())
899 : {
900 : printerFeatures.SetPaperRecord(count++, paper.Name(),
901 0 : (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric());
902 0 : paper.Next();
903 : }
904 0 : printerFeatures.SetNumPaperSizeRecords(count);
905 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
906 : }
907 :
908 : bool hasSpoolerCmd = (nsPSPrinterList::kTypePS ==
909 0 : nsPSPrinterList::GetPrinterType(fullPrinterName));
910 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
911 0 : printerFeatures.SetSupportsSpoolerCommandChange(hasSpoolerCmd);
912 0 : printerFeatures.SetCanChangeSpoolerCommand(hasSpoolerCmd);
913 :
914 : /* Postscript module does not pass the job title to lpr */
915 0 : printerFeatures.SetSupportsJobTitleChange(false);
916 0 : printerFeatures.SetCanChangeJobTitle(false);
917 : /* Postscript module has no control over builtin fonts yet */
918 0 : printerFeatures.SetSupportsDownloadFontsChange(false);
919 0 : printerFeatures.SetCanChangeDownloadFonts(false);
920 : /* Postscript module does not support multiple colorspaces
921 : * so it has to use the old way */
922 0 : printerFeatures.SetSupportsPrintInColorChange(true);
923 0 : printerFeatures.SetCanChangePrintInColor(true);
924 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
925 :
926 0 : if (hasSpoolerCmd) {
927 0 : nsCAutoString command;
928 0 : if (NS_SUCCEEDED(CopyPrinterCharPref("postscript",
929 : printerName, "print_command", command))) {
930 0 : DO_PR_DEBUG_LOG(("setting default print command to '%s'\n",
931 : command.get()));
932 0 : aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUTF16(command).get());
933 : }
934 : }
935 :
936 : #ifdef SET_PRINTER_FEATURES_VIA_PREFS
937 0 : printerFeatures.SetCanChangeNumCopies(true);
938 : #endif /* SET_PRINTER_FEATURES_VIA_PREFS */
939 :
940 0 : return NS_OK;
941 : }
942 :
943 0 : return NS_ERROR_UNEXPECTED;
944 : }
945 :
946 0 : NS_IMETHODIMP nsPrinterEnumeratorGTK::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings *aPrintSettings)
947 : {
948 0 : return NS_OK;
949 : }
950 :
951 : //----------------------------------------------------------------------
952 0 : nsresult GlobalPrinters::InitializeGlobalPrinters ()
953 : {
954 0 : if (PrintersAreAllocated()) {
955 0 : return NS_OK;
956 : }
957 :
958 0 : mGlobalPrinterList = new nsTArray<nsString>();
959 :
960 0 : nsPSPrinterList psMgr;
961 0 : if (psMgr.Enabled()) {
962 : /* Get the list of PostScript-module printers */
963 : // XXX: this function is the only user of GetPrinterList
964 : // So it may be interesting to convert the nsCStrings
965 : // in this function, we would save one loop here
966 0 : nsTArray<nsCString> printerList;
967 0 : psMgr.GetPrinterList(printerList);
968 0 : for (PRUint32 i = 0; i < printerList.Length(); i++)
969 : {
970 0 : mGlobalPrinterList->AppendElement(NS_ConvertUTF8toUTF16(printerList[i]));
971 : }
972 : }
973 :
974 : /* If there are no printers available after all checks, return an error */
975 0 : if (!mGlobalPrinterList->Length())
976 : {
977 : /* Make sure we do not cache an empty printer list */
978 0 : FreeGlobalPrinters();
979 :
980 0 : return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
981 : }
982 :
983 0 : return NS_OK;
984 : }
985 :
986 : //----------------------------------------------------------------------
987 1487 : void GlobalPrinters::FreeGlobalPrinters()
988 : {
989 1487 : if (mGlobalPrinterList) {
990 0 : delete mGlobalPrinterList;
991 0 : mGlobalPrinterList = nsnull;
992 : }
993 1487 : }
994 :
995 : void
996 0 : GlobalPrinters::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName)
997 : {
998 0 : *aDefaultPrinterName = nsnull;
999 :
1000 0 : bool allocate = !GlobalPrinters::GetInstance()->PrintersAreAllocated();
1001 :
1002 0 : if (allocate) {
1003 0 : nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
1004 0 : if (NS_FAILED(rv)) {
1005 0 : return;
1006 : }
1007 : }
1008 0 : NS_ASSERTION(GlobalPrinters::GetInstance()->PrintersAreAllocated(), "no GlobalPrinters");
1009 :
1010 0 : if (GlobalPrinters::GetInstance()->GetNumPrinters() == 0)
1011 0 : return;
1012 :
1013 0 : *aDefaultPrinterName = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(0));
1014 :
1015 0 : if (allocate) {
1016 0 : GlobalPrinters::GetInstance()->FreeGlobalPrinters();
1017 : }
1018 4392 : }
1019 :
|