~ubuntu-branches/ubuntu/precise/kompozer/precise

« back to all changes in this revision

Viewing changes to mozilla/gfx/src/xlib/nsDeviceContextSpecXlib.cpp

  • Committer: Bazaar Package Importer
  • Author(s): Anthony Yarusso
  • Date: 2007-08-27 01:11:03 UTC
  • Revision ID: james.westby@ubuntu.com-20070827011103-2jgf4s6532gqu2ka
Tags: upstream-0.7.10
ImportĀ upstreamĀ versionĀ 0.7.10

Show diffs side-by-side

added added

removed removed

Lines of Context:
 
1
/* -*- Mode: C++; tab-width: 2; indent-tabs-mode: nil; c-basic-offset: 2 -*- */
 
2
/* ***** BEGIN LICENSE BLOCK *****
 
3
 * Version: NPL 1.1/GPL 2.0/LGPL 2.1
 
4
 *
 
5
 * The contents of this file are subject to the Netscape Public License
 
6
 * Version 1.1 (the "License"); you may not use this file except in
 
7
 * compliance with the License. You may obtain a copy of the License at
 
8
 * http://www.mozilla.org/NPL/
 
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
 *
 
25
 *
 
26
 * Alternatively, the contents of this file may be used under the terms of
 
27
 * either the GNU General Public License Version 2 or later (the "GPL"), or
 
28
 * the GNU Lesser General Public License Version 2.1 or later (the "LGPL"),
 
29
 * in which case the provisions of the GPL or the LGPL are applicable instead
 
30
 * of those above. If you wish to allow use of your version of this file only
 
31
 * under the terms of either the GPL or the LGPL, and not to allow others to
 
32
 * use your version of this file under the terms of the NPL, indicate your
 
33
 * decision by deleting the provisions above and replace them with the notice
 
34
 * and other provisions required by the GPL or the LGPL. If you do not delete
 
35
 * the provisions above, a recipient may use your version of this file under
 
36
 * the terms of any one of the NPL, the GPL or the LGPL.
 
37
 *
 
38
 * ***** END LICENSE BLOCK ***** */
 
39
 
 
40
/* Store per-printer features in temp. prefs vars that the
 
41
 * print dialog can pick them up... */
 
42
#define SET_PRINTER_FEATURES_VIA_PREFS 1 
 
43
#define PRINTERFEATURES_PREF "print.tmp.printerfeatures"
 
44
 
 
45
#ifdef MOZ_LOGGING
 
46
#define FORCE_PR_LOG 1 /* Allow logging in the release build */
 
47
#endif /* MOZ_LOGGING */
 
48
#include "prlog.h"
 
49
 
 
50
#include "plstr.h"
 
51
 
 
52
#include "nsDeviceContextSpecXlib.h"
 
53
 
 
54
#include "nsIPref.h"
 
55
#include "prenv.h" /* for PR_GetEnv */
 
56
 
 
57
#include "nsPrintfCString.h"
 
58
#include "nsReadableUtils.h"
 
59
#include "nsIServiceManager.h" 
 
60
 
 
61
#ifdef USE_XPRINT
 
62
#include "xprintutil.h"
 
63
#endif /* USE_XPRINT */
 
64
 
 
65
#ifdef USE_POSTSCRIPT
 
66
#include "nsPaperPS.h"  /* Paper size list */
 
67
#endif /* USE_POSTSCRIPT */
 
68
 
 
69
/* Ensure that the result is always equal to either PR_TRUE or PR_FALSE */
 
70
#define MAKE_PR_BOOL(val) ((val)?(PR_TRUE):(PR_FALSE))
 
71
 
 
72
#ifdef PR_LOGGING 
 
73
static PRLogModuleInfo *DeviceContextSpecXlibLM = PR_NewLogModule("DeviceContextSpecXlib");
 
74
#endif /* PR_LOGGING */
 
75
/* Macro to make lines shorter */
 
76
#define DO_PR_DEBUG_LOG(x) PR_LOG(DeviceContextSpecXlibLM, PR_LOG_DEBUG, x)
 
77
 
 
78
//----------------------------------------------------------------------------------
 
79
// The printer data is shared between the PrinterEnumerator and the nsDeviceContextSpecXlib
 
80
// The PrinterEnumerator creates the printer info
 
81
// but the nsDeviceContextSpecXlib cleans it up
 
82
// If it gets created (via the Page Setup Dialog) but the user never prints anything
 
83
// then it will never be delete, so this class takes care of that.
 
84
class GlobalPrinters {
 
85
public:
 
86
  static GlobalPrinters* GetInstance()   { return &mGlobalPrinters; }
 
87
  ~GlobalPrinters()                      { FreeGlobalPrinters(); }
 
88
 
 
89
  void      FreeGlobalPrinters();
 
90
  nsresult  InitializeGlobalPrinters();
 
91
 
 
92
  PRBool    PrintersAreAllocated()       { return mGlobalPrinterList != nsnull; }
 
93
  PRInt32   GetNumPrinters()             { return mGlobalNumPrinters; }
 
94
  nsString* GetStringAt(PRInt32 aInx)    { return mGlobalPrinterList->StringAt(aInx); }
 
95
  void      GetDefaultPrinterName(PRUnichar **aDefaultPrinterName);
 
96
 
 
97
protected:
 
98
  GlobalPrinters() {}
 
99
 
 
100
  static GlobalPrinters mGlobalPrinters;
 
101
  static nsStringArray* mGlobalPrinterList;
 
102
  static int            mGlobalNumPrinters;
 
103
};
 
104
 
 
105
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
106
/* "Prototype" for the new nsPrinterFeatures service */
 
107
class nsPrinterFeatures {
 
108
public:
 
109
  nsPrinterFeatures( const char *printername );
 
110
  ~nsPrinterFeatures() {};
 
111
 
 
112
  /* Does this printer allow to set/change the paper size ? */
 
113
  void SetCanChangePaperSize( PRBool aCanSetPaperSize );
 
114
  /* Does this Mozilla print module allow set/change the paper size ? */
 
115
  void SetSupportsPaperSizeChange( PRBool aSupportsPaperSizeChange );
 
116
  /* Set number of paper size records and the records itself */
 
117
  void SetNumPaperSizeRecords( PRInt32 aCount );
 
118
  void SetPaperRecord( PRInt32 aIndex, const char *aName, PRInt32 aWidthMM, PRInt32 aHeightMM, PRBool aIsInch );
 
119
 
 
120
  /* Does this printer allow to set/change the content orientation ? */
 
121
  void SetCanChangeOrientation( PRBool aCanSetOrientation );
 
122
  /* Does this Mozilla print module allow set/change the content orientation ? */
 
123
  void SetSupportsOrientationChange( PRBool aSupportsOrientationChange );
 
124
  /* Set number of orientation records and the records itself */
 
125
  void SetNumOrientationRecords( PRInt32 aCount );
 
126
  void SetOrientationRecord( PRInt32 aIndex, const char *aName );
 
127
 
 
128
  /* Does this printer allow to set/change the plex mode ? */
 
129
  void SetCanChangePlex( PRBool aCanSetPlex );
 
130
  /* Does this Mozilla print module allow set/change the plex mode ? */
 
131
  void SetSupportsPlexChange( PRBool aSupportsPlexChange );
 
132
  /* Set number of plex records and the records itself */
 
133
  void SetNumPlexRecords( PRInt32 aCount );
 
134
  void SetPlexRecord( PRInt32 aIndex, const char *aName );
 
135
    
 
136
  /* Does this device allow to set/change the spooler command ? */
 
137
  void SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand );
 
138
  /* Does this printer allow to set/change the spooler command ? */
 
139
  void SetSupportsSpoolerCommandChange( PRBool aSupportSpoolerCommandChange );
 
140
  
 
141
  /* Does this device allow to set/change number of copies for an document ? */
 
142
  void SetCanChangeNumCopies( PRBool aCanSetNumCopies );
 
143
 
 
144
  /* Does this device allow multiple devicecontext instances to be used in
 
145
   * parallel (e.g. print while the device is already in use by print-preview
 
146
   * or printing while another print job is in progress) ? */
 
147
  void SetMultipleConcurrentDeviceContextsSupported( PRBool aCanUseMultipleInstances );
 
148
  
 
149
private:
 
150
  /* private helper methods */
 
151
  void SetBoolValue( const char *tagname, PRBool value );
 
152
  void SetIntValue(  const char *tagname, PRInt32 value );
 
153
  void SetCharValue(  const char *tagname, const char *value );
 
154
 
 
155
  nsXPIDLCString    mPrinterName;
 
156
  nsCOMPtr<nsIPref> mPrefs;
 
157
};
 
158
 
 
159
void nsPrinterFeatures::SetBoolValue( const char *tagname, PRBool value )
 
160
{
 
161
  mPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value);
 
162
}
 
163
 
 
164
void nsPrinterFeatures::SetIntValue(  const char *tagname, PRInt32 value )
 
165
{
 
166
  mPrefs->SetIntPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value);
 
167
}
 
168
 
 
169
void nsPrinterFeatures::SetCharValue(  const char *tagname, const char *value )
 
170
{
 
171
  mPrefs->SetCharPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.%s", mPrinterName.get(), tagname).get(), value);
 
172
}
 
173
 
 
174
nsPrinterFeatures::nsPrinterFeatures( const char *printername )
 
175
{
 
176
  DO_PR_DEBUG_LOG(("nsPrinterFeatures::nsPrinterFeatures('%s')\n", printername));
 
177
  mPrinterName.Assign(printername);
 
178
  mPrefs = do_GetService(NS_PREF_CONTRACTID);
 
179
 
 
180
  SetBoolValue("has_special_printerfeatures", PR_TRUE);
 
181
}
 
182
 
 
183
void nsPrinterFeatures::SetCanChangePaperSize( PRBool aCanSetPaperSize )
 
184
{
 
185
  SetBoolValue("can_change_paper_size", aCanSetPaperSize);
 
186
}
 
187
 
 
188
void nsPrinterFeatures::SetSupportsPaperSizeChange( PRBool aSupportsPaperSizeChange )
 
189
{
 
190
  SetBoolValue("supports_paper_size_change", aSupportsPaperSizeChange);
 
191
}
 
192
 
 
193
/* Set number of paper size records and the records itself */
 
194
void nsPrinterFeatures::SetNumPaperSizeRecords( PRInt32 aCount )
 
195
{
 
196
  SetIntValue("paper.count", aCount);          
 
197
}
 
198
 
 
199
void nsPrinterFeatures::SetPaperRecord(PRInt32 aIndex, const char *aPaperName, PRInt32 aWidthMM, PRInt32 aHeightMM, PRBool aIsInch)
 
200
{
 
201
  SetCharValue(nsPrintfCString(256, "paper.%d.name",      aIndex).get(), aPaperName);
 
202
  SetIntValue( nsPrintfCString(256, "paper.%d.width_mm",  aIndex).get(), aWidthMM);
 
203
  SetIntValue( nsPrintfCString(256, "paper.%d.height_mm", aIndex).get(), aHeightMM);
 
204
  SetBoolValue(nsPrintfCString(256, "paper.%d.is_inch",   aIndex).get(), aIsInch);
 
205
}
 
206
 
 
207
void nsPrinterFeatures::SetCanChangeOrientation( PRBool aCanSetOrientation )
 
208
{
 
209
  SetBoolValue("can_change_orientation", aCanSetOrientation);
 
210
}
 
211
 
 
212
void nsPrinterFeatures::SetSupportsOrientationChange( PRBool aSupportsOrientationChange )
 
213
{
 
214
  SetBoolValue("supports_orientation_change", aSupportsOrientationChange);
 
215
}
 
216
 
 
217
void nsPrinterFeatures::SetNumOrientationRecords( PRInt32 aCount )
 
218
{
 
219
  SetIntValue("orientation.count", aCount);          
 
220
}
 
221
 
 
222
void nsPrinterFeatures::SetOrientationRecord( PRInt32 aIndex, const char *aOrientationName )
 
223
{
 
224
  SetCharValue(nsPrintfCString(256, "orientation.%d.name", aIndex).get(), aOrientationName);
 
225
}
 
226
 
 
227
void nsPrinterFeatures::SetCanChangePlex( PRBool aCanSetPlex )
 
228
{
 
229
  SetBoolValue("can_change_plex", aCanSetPlex);
 
230
}
 
231
 
 
232
void nsPrinterFeatures::SetSupportsPlexChange( PRBool aSupportsPlexChange )
 
233
{
 
234
  SetBoolValue("supports_plex_change", aSupportsPlexChange);
 
235
}
 
236
 
 
237
void nsPrinterFeatures::SetNumPlexRecords( PRInt32 aCount )
 
238
{
 
239
  SetIntValue("plex.count", aCount);          
 
240
}
 
241
 
 
242
void nsPrinterFeatures::SetPlexRecord( PRInt32 aIndex, const char *aPlexName )
 
243
{
 
244
  SetCharValue(nsPrintfCString(256, "plex.%d.name", aIndex).get(), aPlexName);
 
245
}
 
246
 
 
247
void nsPrinterFeatures::SetCanChangeSpoolerCommand( PRBool aCanSetSpoolerCommand )
 
248
{
 
249
  SetBoolValue("can_change_spoolercommand", aCanSetSpoolerCommand);
 
250
}
 
251
 
 
252
void nsPrinterFeatures::SetSupportsSpoolerCommandChange( PRBool aSupportSpoolerCommandChange )
 
253
{
 
254
  SetBoolValue("supports_spoolercommand_change", aSupportSpoolerCommandChange);
 
255
}
 
256
 
 
257
void nsPrinterFeatures::SetCanChangeNumCopies( PRBool aCanSetNumCopies )
 
258
{
 
259
  SetBoolValue("can_change_num_copies", aCanSetNumCopies);
 
260
}
 
261
 
 
262
void nsPrinterFeatures::SetMultipleConcurrentDeviceContextsSupported( PRBool aCanUseMultipleInstances )
 
263
{
 
264
  SetBoolValue("can_use_multiple_devicecontexts_concurrently", aCanUseMultipleInstances);
 
265
}
 
266
 
 
267
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
268
 
 
269
//---------------
 
270
// static members
 
271
GlobalPrinters GlobalPrinters::mGlobalPrinters;
 
272
nsStringArray* GlobalPrinters::mGlobalPrinterList = nsnull;
 
273
int            GlobalPrinters::mGlobalNumPrinters = 0;
 
274
//---------------
 
275
 
 
276
nsDeviceContextSpecXlib::nsDeviceContextSpecXlib()
 
277
{
 
278
  DO_PR_DEBUG_LOG(("nsDeviceContextSpecXlib::nsDeviceContextSpecXlib()\n"));
 
279
}
 
280
 
 
281
nsDeviceContextSpecXlib::~nsDeviceContextSpecXlib()
 
282
{
 
283
  DO_PR_DEBUG_LOG(("nsDeviceContextSpecXlib::~nsDeviceContextSpecXlib()\n"));
 
284
}
 
285
 
 
286
/* Use both PostScript and Xprint module */
 
287
#if defined(USE_XPRINT) && defined(USE_POSTSCRIPT)
 
288
NS_IMPL_ISUPPORTS3(nsDeviceContextSpecXlib,
 
289
                   nsIDeviceContextSpec,
 
290
                   nsIDeviceContextSpecPS,
 
291
                   nsIDeviceContextSpecXp)
 
292
/* Use only PostScript module */
 
293
#elif !defined(USE_XPRINT) && defined(USE_POSTSCRIPT)
 
294
NS_IMPL_ISUPPORTS2(nsDeviceContextSpecXlib,
 
295
                   nsIDeviceContextSpec,
 
296
                   nsIDeviceContextSpecPS)
 
297
/* Use only Xprint module module */
 
298
#elif defined(USE_XPRINT) && !defined(USE_POSTSCRIPT)
 
299
NS_IMPL_ISUPPORTS2(nsDeviceContextSpecXlib,
 
300
                   nsIDeviceContextSpec,
 
301
                   nsIDeviceContextSpecXp)
 
302
/* Both Xprint and PostScript module are missing */
 
303
#elif !defined(USE_XPRINT) && !defined(USE_POSTSCRIPT)
 
304
NS_IMPL_ISUPPORTS1(nsDeviceContextSpecXlib,
 
305
                   nsIDeviceContextSpec)
 
306
#else
 
307
#error "This should not happen"
 
308
#endif
 
309
 
 
310
/** -------------------------------------------------------
 
311
 *  Initialize the nsDeviceContextSpecXlib
 
312
 *  @update   dc 2/15/98
 
313
 *  @update   syd 3/2/99
 
314
 *
 
315
 * gisburn: Please note that this function exists as 1:1 copy in other
 
316
 * toolkits including:
 
317
 * - GTK+-toolkit:
 
318
 *   file:     mozilla/gfx/src/gtk/nsDeviceContextSpecG.cpp
 
319
 *   function: NS_IMETHODIMP nsDeviceContextSpecXlib::Init()
 
320
 * - Xlib-toolkit: 
 
321
 *   file:     mozilla/gfx/src/xlib/nsDeviceContextSpecXlib.cpp 
 
322
 *   function: NS_IMETHODIMP nsDeviceContextSpecXlib::Init()
 
323
 * - Qt-toolkit:
 
324
 *   file:     mozilla/gfx/src/qt/nsDeviceContextSpecQT.cpp
 
325
 *   function: NS_IMETHODIMP nsDeviceContextSpecQT::Init()
 
326
 * 
 
327
 * ** Please update the other toolkits when changing this function.
 
328
 */
 
329
NS_IMETHODIMP nsDeviceContextSpecXlib::Init(nsIPrintSettings *aPS)
 
330
{
 
331
  DO_PR_DEBUG_LOG(("nsDeviceContextSpecXlib::Init(aPS=%p)\n", aPS));
 
332
  nsresult rv = NS_ERROR_FAILURE;
 
333
 
 
334
  mPrintSettings = aPS;
 
335
 
 
336
  // if there is a current selection then enable the "Selection" radio button
 
337
  rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
 
338
  if (NS_FAILED(rv)) {
 
339
    return rv;
 
340
  }
 
341
 
 
342
  GlobalPrinters::GetInstance()->FreeGlobalPrinters();
 
343
 
 
344
  if (aPS) {
 
345
    PRBool     reversed       = PR_FALSE;
 
346
    PRBool     color          = PR_FALSE;
 
347
    PRBool     tofile         = PR_FALSE;
 
348
    PRInt16    printRange     = nsIPrintSettings::kRangeAllPages;
 
349
    PRInt32    orientation    = NS_PORTRAIT;
 
350
    PRInt32    fromPage       = 1;
 
351
    PRInt32    toPage         = 1;
 
352
    PRUnichar *command        = nsnull;
 
353
    PRInt32    copies         = 1;
 
354
    PRUnichar *printer        = nsnull;
 
355
    PRUnichar *papername      = nsnull;
 
356
    PRUnichar *plexname       = nsnull;
 
357
    PRUnichar *printfile      = nsnull;
 
358
    double     dleft          = 0.5;
 
359
    double     dright         = 0.5;
 
360
    double     dtop           = 0.5;
 
361
    double     dbottom        = 0.5; 
 
362
 
 
363
    aPS->GetPrinterName(&printer);
 
364
    aPS->GetPrintReversed(&reversed);
 
365
    aPS->GetPrintInColor(&color);
 
366
    aPS->GetPaperName(&papername);
 
367
    aPS->GetPlexName(&plexname);
 
368
    aPS->GetOrientation(&orientation);
 
369
    aPS->GetPrintCommand(&command);
 
370
    aPS->GetPrintRange(&printRange);
 
371
    aPS->GetToFileName(&printfile);
 
372
    aPS->GetPrintToFile(&tofile);
 
373
    aPS->GetStartPageRange(&fromPage);
 
374
    aPS->GetEndPageRange(&toPage);
 
375
    aPS->GetNumCopies(&copies);
 
376
    aPS->GetMarginTop(&dtop);
 
377
    aPS->GetMarginLeft(&dleft);
 
378
    aPS->GetMarginBottom(&dbottom);
 
379
    aPS->GetMarginRight(&dright);
 
380
 
 
381
    if (printfile)
 
382
      PL_strncpyz(mPath,      NS_ConvertUCS2toUTF8(printfile).get(), sizeof(mPath));
 
383
    if (command)
 
384
      PL_strncpyz(mCommand,   NS_ConvertUCS2toUTF8(command).get(),   sizeof(mCommand));  
 
385
    if (printer) 
 
386
      PL_strncpyz(mPrinter,   NS_ConvertUCS2toUTF8(printer).get(),   sizeof(mPrinter));        
 
387
    if (papername) 
 
388
      PL_strncpyz(mPaperName, NS_ConvertUCS2toUTF8(papername).get(), sizeof(mPaperName));  
 
389
    if (plexname) 
 
390
      PL_strncpyz(mPlexName,  NS_ConvertUCS2toUTF8(plexname).get(),  sizeof(mPlexName));  
 
391
 
 
392
    DO_PR_DEBUG_LOG(("margins:   %5.2f,%5.2f,%5.2f,%5.2f\n", dtop, dleft, dbottom, dright));
 
393
    DO_PR_DEBUG_LOG(("printRange %d\n",   printRange));
 
394
    DO_PR_DEBUG_LOG(("fromPage   %d\n",   fromPage));
 
395
    DO_PR_DEBUG_LOG(("toPage     %d\n",   toPage));
 
396
    DO_PR_DEBUG_LOG(("tofile     %d\n",   tofile));
 
397
    DO_PR_DEBUG_LOG(("printfile  '%s'\n", printfile? NS_ConvertUCS2toUTF8(printfile).get():"<NULL>"));
 
398
    DO_PR_DEBUG_LOG(("command    '%s'\n", command? NS_ConvertUCS2toUTF8(command).get():"<NULL>"));
 
399
    DO_PR_DEBUG_LOG(("printer    '%s'\n", printer? NS_ConvertUCS2toUTF8(printer).get():"<NULL>"));
 
400
    DO_PR_DEBUG_LOG(("papername  '%s'\n", papername? NS_ConvertUCS2toUTF8(papername).get():"<NULL>"));
 
401
    DO_PR_DEBUG_LOG(("plexname   '%s'\n", plexname? NS_ConvertUCS2toUTF8(plexname).get():"<NULL>"));
 
402
 
 
403
    mTop         = dtop;
 
404
    mBottom      = dbottom;
 
405
    mLeft        = dleft;
 
406
    mRight       = dright;
 
407
    mFpf         = !reversed;
 
408
    mGrayscale   = !color;
 
409
    mOrientation = orientation;
 
410
    mToPrinter   = !tofile;
 
411
    mCopies      = copies;
 
412
  }
 
413
 
 
414
  return rv;
 
415
}
 
416
 
 
417
NS_IMETHODIMP nsDeviceContextSpecXlib::GetToPrinter(PRBool &aToPrinter)
 
418
{
 
419
  aToPrinter = mToPrinter;
 
420
  return NS_OK;
 
421
}
 
422
 
 
423
NS_IMETHODIMP nsDeviceContextSpecXlib::GetPrinterName ( const char **aPrinter )
 
424
{
 
425
   *aPrinter = mPrinter;
 
426
   return NS_OK;
 
427
}
 
428
 
 
429
NS_IMETHODIMP nsDeviceContextSpecXlib::GetCopies ( int &aCopies )
 
430
{
 
431
   aCopies = mCopies;
 
432
   return NS_OK;
 
433
}
 
434
 
 
435
NS_IMETHODIMP nsDeviceContextSpecXlib::GetFirstPageFirst(PRBool &aFpf)      
 
436
{
 
437
  aFpf = mFpf;
 
438
  return NS_OK;
 
439
}
 
440
 
 
441
NS_IMETHODIMP nsDeviceContextSpecXlib::GetGrayscale(PRBool &aGrayscale)      
 
442
{
 
443
  aGrayscale = mGrayscale;
 
444
  return NS_OK;
 
445
}
 
446
 
 
447
NS_IMETHODIMP nsDeviceContextSpecXlib::GetLandscape(PRBool &aLandscape)
 
448
{
 
449
  aLandscape = (mOrientation == NS_LANDSCAPE);
 
450
  return NS_OK;
 
451
}
 
452
 
 
453
NS_IMETHODIMP nsDeviceContextSpecXlib::GetTopMargin(float &aValue)      
 
454
{
 
455
  aValue = mTop;
 
456
  return NS_OK;
 
457
}
 
458
 
 
459
NS_IMETHODIMP nsDeviceContextSpecXlib::GetBottomMargin(float &aValue)      
 
460
{
 
461
  aValue = mBottom;
 
462
  return NS_OK;
 
463
}
 
464
 
 
465
NS_IMETHODIMP nsDeviceContextSpecXlib::GetRightMargin(float &aValue)      
 
466
{
 
467
  aValue = mRight;
 
468
  return NS_OK;
 
469
}
 
470
 
 
471
NS_IMETHODIMP nsDeviceContextSpecXlib::GetLeftMargin(float &aValue)      
 
472
{
 
473
  aValue = mLeft;
 
474
  return NS_OK;
 
475
}
 
476
 
 
477
NS_IMETHODIMP nsDeviceContextSpecXlib::GetCommand(const char **aCommand)      
 
478
{
 
479
  *aCommand = mCommand;
 
480
  return NS_OK;
 
481
}
 
482
 
 
483
NS_IMETHODIMP nsDeviceContextSpecXlib::GetPath(const char **aPath)      
 
484
{
 
485
  *aPath = mPath;
 
486
  return NS_OK;
 
487
}
 
488
 
 
489
NS_IMETHODIMP nsDeviceContextSpecXlib::GetUserCancelled(PRBool &aCancel)     
 
490
{
 
491
  aCancel = mCancel;
 
492
  return NS_OK;
 
493
}
 
494
 
 
495
NS_IMETHODIMP nsDeviceContextSpecXlib::GetPaperName( const char **aPaperName )
 
496
{
 
497
  *aPaperName = mPaperName;
 
498
  return NS_OK;
 
499
}
 
500
 
 
501
NS_IMETHODIMP nsDeviceContextSpecXlib::GetPlexName( const char **aPlexName )
 
502
{
 
503
  *aPlexName = mPlexName;
 
504
  return NS_OK;
 
505
}
 
506
 
 
507
NS_IMETHODIMP nsDeviceContextSpecXlib::GetPageSizeInTwips(PRInt32 *aWidth, PRInt32 *aHeight)
 
508
{
 
509
  return mPrintSettings->GetPageSizeInTwips(aWidth, aHeight);
 
510
}
 
511
 
 
512
NS_IMETHODIMP nsDeviceContextSpecXlib::GetPrintMethod(PrintMethod &aMethod)
 
513
{
 
514
  return GetPrintMethod(mPrinter, aMethod);
 
515
}
 
516
 
 
517
/* static !! */
 
518
nsresult nsDeviceContextSpecXlib::GetPrintMethod(const char *aPrinter, PrintMethod &aMethod)
 
519
{
 
520
#if defined(USE_POSTSCRIPT) && defined(USE_XPRINT)
 
521
  /* printer names for the PostScript module alwas start with 
 
522
   * the NS_POSTSCRIPT_DRIVER_NAME string */
 
523
  if (strncmp(aPrinter, NS_POSTSCRIPT_DRIVER_NAME, 
 
524
              NS_POSTSCRIPT_DRIVER_NAME_LEN) != 0)
 
525
    aMethod = pmXprint;
 
526
  else
 
527
    aMethod = pmPostScript;
 
528
  return NS_OK;
 
529
#elif defined(USE_XPRINT)
 
530
  aMethod = pmXprint;
 
531
  return NS_OK;
 
532
#elif defined(USE_POSTSCRIPT)
 
533
  aMethod = pmPostScript;
 
534
  return NS_OK;
 
535
#else
 
536
  return NS_ERROR_UNEXPECTED;
 
537
#endif
 
538
}
 
539
 
 
540
NS_IMETHODIMP nsDeviceContextSpecXlib::ClosePrintManager()
 
541
{
 
542
  return NS_OK;
 
543
}
 
544
 
 
545
/* Get prefs for printer
 
546
 * Search order:
 
547
 * - Get prefs per printer name and module name
 
548
 * - Get prefs per printer name
 
549
 * - Get prefs per module name
 
550
 * - Get prefs
 
551
 */
 
552
static
 
553
nsresult CopyPrinterCharPref(nsIPref *pref, const char *modulename, const char *printername, const char *prefname, char **return_buf)
 
554
{
 
555
  DO_PR_DEBUG_LOG(("CopyPrinterCharPref('%s', '%s', '%s')\n", modulename, printername, prefname));
 
556
 
 
557
  NS_ENSURE_ARG_POINTER(return_buf);
 
558
 
 
559
  nsXPIDLCString name;
 
560
  nsresult rv = NS_ERROR_FAILURE;
 
561
 
 
562
  if (printername && modulename) {
 
563
    /* Get prefs per printer name and module name */
 
564
    name = nsPrintfCString(512, "print.%s.printer_%s.%s", modulename, printername, prefname);
 
565
    DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
 
566
    rv = pref->CopyCharPref(name, return_buf);
 
567
  }
 
568
  
 
569
  if (NS_FAILED(rv)) { 
 
570
    if (printername) {
 
571
      /* Get prefs per printer name */
 
572
      name = nsPrintfCString(512, "print.printer_%s.%s", printername, prefname);
 
573
      DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
 
574
      rv = pref->CopyCharPref(name, return_buf);
 
575
    }
 
576
 
 
577
    if (NS_FAILED(rv)) {
 
578
      if (modulename) {
 
579
        /* Get prefs per module name */
 
580
        name = nsPrintfCString(512, "print.%s.%s", modulename, prefname);
 
581
        DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
 
582
        rv = pref->CopyCharPref(name, return_buf);
 
583
      }
 
584
      
 
585
      if (NS_FAILED(rv)) {
 
586
        /* Get prefs */
 
587
        name = nsPrintfCString(512, "print.%s", prefname);
 
588
        DO_PR_DEBUG_LOG(("trying to get '%s'\n", name.get()));
 
589
        rv = pref->CopyCharPref(name, return_buf);
 
590
      }
 
591
    }
 
592
  }
 
593
 
 
594
#ifdef PR_LOG  
 
595
  if (NS_SUCCEEDED(rv)) {
 
596
    DO_PR_DEBUG_LOG(("CopyPrinterCharPref returning '%s'.\n", *return_buf));
 
597
  }
 
598
  else
 
599
  {
 
600
    DO_PR_DEBUG_LOG(("CopyPrinterCharPref failure.\n"));
 
601
  }
 
602
#endif /* PR_LOG */
 
603
 
 
604
  return rv;
 
605
}
 
606
 
 
607
//  Printer Enumerator
 
608
nsPrinterEnumeratorXlib::nsPrinterEnumeratorXlib()
 
609
{
 
610
}
 
611
 
 
612
NS_IMPL_ISUPPORTS1(nsPrinterEnumeratorXlib, nsIPrinterEnumerator)
 
613
 
 
614
NS_IMETHODIMP nsPrinterEnumeratorXlib::EnumeratePrinters(PRUint32* aCount, PRUnichar*** aResult)
 
615
{
 
616
  NS_ENSURE_ARG(aCount);
 
617
  NS_ENSURE_ARG_POINTER(aResult);
 
618
 
 
619
  if (aCount) 
 
620
    *aCount = 0;
 
621
  else 
 
622
    return NS_ERROR_NULL_POINTER;
 
623
  
 
624
  if (aResult) 
 
625
    *aResult = nsnull;
 
626
  else 
 
627
    return NS_ERROR_NULL_POINTER;
 
628
  
 
629
  nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
 
630
  if (NS_FAILED(rv)) {
 
631
    return rv;
 
632
  }
 
633
 
 
634
  PRInt32 numPrinters = GlobalPrinters::GetInstance()->GetNumPrinters();
 
635
 
 
636
  PRUnichar** array = (PRUnichar**) nsMemory::Alloc(numPrinters * sizeof(PRUnichar*));
 
637
  if (!array && numPrinters > 0) {
 
638
    GlobalPrinters::GetInstance()->FreeGlobalPrinters();
 
639
    return NS_ERROR_OUT_OF_MEMORY;
 
640
  }
 
641
  
 
642
  int count = 0;
 
643
  while( count < numPrinters )
 
644
  {
 
645
    PRUnichar *str = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(count));
 
646
 
 
647
    if (!str) {
 
648
      for (int i = count - 1; i >= 0; i--) 
 
649
        nsMemory::Free(array[i]);
 
650
      
 
651
      nsMemory::Free(array);
 
652
 
 
653
      GlobalPrinters::GetInstance()->FreeGlobalPrinters();
 
654
      return NS_ERROR_OUT_OF_MEMORY;
 
655
    }
 
656
    array[count++] = str;
 
657
    
 
658
  }
 
659
  *aCount = count;
 
660
  *aResult = array;
 
661
  GlobalPrinters::GetInstance()->FreeGlobalPrinters();
 
662
 
 
663
  return NS_OK;
 
664
}
 
665
 
 
666
/* readonly attribute wstring defaultPrinterName; */
 
667
NS_IMETHODIMP nsPrinterEnumeratorXlib::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName)
 
668
{
 
669
  DO_PR_DEBUG_LOG(("nsPrinterEnumeratorXlib::GetDefaultPrinterName()\n"));
 
670
  NS_ENSURE_ARG_POINTER(aDefaultPrinterName);
 
671
 
 
672
  GlobalPrinters::GetInstance()->GetDefaultPrinterName(aDefaultPrinterName);
 
673
 
 
674
  DO_PR_DEBUG_LOG(("GetDefaultPrinterName(): default printer='%s'.\n", NS_ConvertUCS2toUTF8(*aDefaultPrinterName).get()));
 
675
  return NS_OK;
 
676
}
 
677
 
 
678
/* void initPrintSettingsFromPrinter (in wstring aPrinterName, in nsIPrintSettings aPrintSettings); */
 
679
NS_IMETHODIMP nsPrinterEnumeratorXlib::InitPrintSettingsFromPrinter(const PRUnichar *aPrinterName, nsIPrintSettings *aPrintSettings)
 
680
{
 
681
  DO_PR_DEBUG_LOG(("nsPrinterEnumeratorXlib::InitPrintSettingsFromPrinter()"));
 
682
  nsresult rv;
 
683
 
 
684
  NS_ENSURE_ARG_POINTER(aPrinterName);
 
685
  NS_ENSURE_ARG_POINTER(aPrintSettings);
 
686
  
 
687
  NS_ENSURE_TRUE(*aPrinterName, NS_ERROR_FAILURE);
 
688
  NS_ENSURE_TRUE(aPrintSettings, NS_ERROR_FAILURE);
 
689
 
 
690
  nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID, &rv);
 
691
  if (NS_FAILED(rv))
 
692
    return rv;
 
693
 
 
694
  nsXPIDLCString fullPrinterName, /* Full name of printer incl. driver-specific prefix */ 
 
695
                 printerName;     /* "Stripped" name of printer */
 
696
  fullPrinterName.Assign(NS_ConvertUCS2toUTF8(aPrinterName));
 
697
  printerName.Assign(NS_ConvertUCS2toUTF8(aPrinterName));
 
698
  DO_PR_DEBUG_LOG(("printerName='%s'\n", printerName.get()));
 
699
  
 
700
  PrintMethod type = pmInvalid;
 
701
  rv = nsDeviceContextSpecXlib::GetPrintMethod(printerName, type);
 
702
  if (NS_FAILED(rv))
 
703
    return rv;
 
704
 
 
705
#ifdef USE_POSTSCRIPT
 
706
  /* "Demangle" postscript printer name */
 
707
  if (type == pmPostScript) {
 
708
    /* Strip the leading NS_POSTSCRIPT_DRIVER_NAME from |printerName|,
 
709
     * e.g. turn "PostScript/foobar" to "foobar" */
 
710
    printerName.Cut(0, NS_POSTSCRIPT_DRIVER_NAME_LEN);
 
711
  }
 
712
#endif /* USE_POSTSCRIPT */
 
713
 
 
714
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
715
  /* Defaults to FALSE */
 
716
  pPrefs->SetBoolPref(nsPrintfCString(256, PRINTERFEATURES_PREF ".%s.has_special_printerfeatures", fullPrinterName.get()).get(), PR_FALSE);
 
717
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
718
 
 
719
  
 
720
  /* Set filename */
 
721
  nsXPIDLCString filename;
 
722
  if (NS_FAILED(CopyPrinterCharPref(pPrefs, nsnull, printerName, "filename", getter_Copies(filename)))) {
 
723
    const char *path;
 
724
  
 
725
    if (!(path = PR_GetEnv("PWD")))
 
726
      path = PR_GetEnv("HOME");
 
727
  
 
728
    if (path)
 
729
      filename = nsPrintfCString(PATH_MAX, "%s/mozilla.ps", path);
 
730
    else
 
731
      filename.Assign("mozilla.ps");  
 
732
  }  
 
733
  DO_PR_DEBUG_LOG(("Setting default filename to '%s'\n", filename.get()));
 
734
  aPrintSettings->SetToFileName(NS_ConvertUTF8toUCS2(filename).get());
 
735
 
 
736
  aPrintSettings->SetIsInitializedFromPrinter(PR_TRUE);
 
737
 
 
738
#ifdef USE_XPRINT
 
739
  if (type == pmXprint) {
 
740
    DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for Xprint printer\n"));
 
741
 
 
742
    /* Setup the capabilties list of Mozilla's Xprint print module */
 
743
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
744
    nsPrinterFeatures printerFeatures(fullPrinterName);
 
745
 
 
746
    printerFeatures.SetSupportsPaperSizeChange(PR_TRUE);
 
747
    printerFeatures.SetSupportsOrientationChange(PR_TRUE);
 
748
    printerFeatures.SetSupportsPlexChange(PR_TRUE);
 
749
    printerFeatures.SetSupportsSpoolerCommandChange(PR_FALSE); /* won't work by design and very good reasons! */
 
750
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ 
 
751
    
 
752
    /* Setup the capabilties list of this specific printer */
 
753
 
 
754
    Display   *pdpy;
 
755
    XPContext  pcontext;
 
756
    if (XpuGetPrinter(printerName, &pdpy, &pcontext) != 1)
 
757
      return NS_ERROR_GFX_PRINTER_NAME_NOT_FOUND;
 
758
      
 
759
    XpuSupportedFlags supported_doc_attrs = XpuGetSupportedDocAttributes(pdpy, pcontext);
 
760
 
 
761
    /* Setup orientation stuff */
 
762
    XpuOrientationList  olist;
 
763
    int                 ocount;
 
764
    XpuOrientationRec  *default_orientation;
 
765
 
 
766
    /* Setup plex stuff */
 
767
    XpuPlexList         plexlist;
 
768
    int                 plexcount;
 
769
    XpuPlexRec         *default_plex;
 
770
 
 
771
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
772
    PRBool canSetOrientation = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_CONTENT_ORIENTATION);
 
773
    printerFeatures.SetCanChangeOrientation(canSetOrientation);
 
774
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
775
      
 
776
    /* Get list of supported orientations */
 
777
    olist = XpuGetOrientationList(pdpy, pcontext, &ocount);
 
778
    if (olist) {
 
779
      default_orientation = &olist[0]; /* First entry is the default one */
 
780
    
 
781
      if (!PL_strcasecmp(default_orientation->orientation, "portrait")) {
 
782
        DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n"));
 
783
        aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
 
784
      }
 
785
      else if (!PL_strcasecmp(default_orientation->orientation, "landscape")) {
 
786
        DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n"));
 
787
        aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);
 
788
      }  
 
789
      else {
 
790
        DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", default_orientation->orientation));
 
791
      }
 
792
 
 
793
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
794
      int i;
 
795
      for( i = 0 ; i < ocount ; i++ )
 
796
      {
 
797
        XpuOrientationRec *curr = &olist[i];
 
798
        printerFeatures.SetOrientationRecord(i, curr->orientation);
 
799
      }
 
800
      printerFeatures.SetNumOrientationRecords(ocount);
 
801
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
802
   
 
803
      XpuFreeOrientationList(olist);
 
804
    }  
 
805
 
 
806
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
807
    PRBool canSetPlexMode = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_PLEX);
 
808
    printerFeatures.SetCanChangePlex(canSetPlexMode);
 
809
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
810
 
 
811
    /* Get list of supported plex modes */
 
812
    plexlist = XpuGetPlexList(pdpy, pcontext, &plexcount);
 
813
    if (plexlist) {
 
814
      default_plex = &plexlist[0]; /* First entry is the default one */
 
815
    
 
816
      DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", default_plex->plex));
 
817
      aPrintSettings->SetPlexName(NS_ConvertUTF8toUCS2(default_plex->plex).get());
 
818
 
 
819
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
820
      int i;
 
821
      for( i = 0 ; i < plexcount ; i++ )
 
822
      {
 
823
        XpuPlexRec *curr = &plexlist[i];
 
824
        printerFeatures.SetPlexRecord(i, curr->plex);
 
825
      }
 
826
      printerFeatures.SetNumPlexRecords(plexcount);
 
827
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
828
   
 
829
      XpuFreePlexList(plexlist);
 
830
    }  
 
831
 
 
832
    /* Setup Number of Copies */
 
833
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
834
    PRBool canSetNumCopies = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_COPY_COUNT);
 
835
    printerFeatures.SetCanChangeNumCopies(canSetNumCopies);
 
836
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
837
    long numCopies;
 
838
    if( XpuGetOneLongAttribute(pdpy, pcontext, XPDocAttr, "copy-count", &numCopies) != 1 )
 
839
    {
 
840
      /* Fallback on failure */
 
841
      numCopies = 1;
 
842
    }
 
843
    aPrintSettings->SetNumCopies(numCopies);
 
844
 
 
845
    /* Setup paper size stuff */
 
846
    XpuMediumSourceSizeList mlist;
 
847
    int                     mcount;
 
848
    XpuMediumSourceSizeRec *default_medium;
 
849
    
 
850
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
851
    PRBool canSetPaperSize = MAKE_PR_BOOL(supported_doc_attrs & XPUATTRIBUTESUPPORTED_DEFAULT_MEDIUM);
 
852
    printerFeatures.SetCanChangePaperSize(canSetPaperSize);
 
853
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
854
    
 
855
    mlist = XpuGetMediumSourceSizeList(pdpy, pcontext, &mcount);
 
856
    if (mlist) {
 
857
      nsXPIDLCString papername;
 
858
 
 
859
      default_medium = &mlist[0]; /* First entry is the default one */
 
860
      double total_width  = default_medium->ma1 + default_medium->ma2,
 
861
             total_height = default_medium->ma3 + default_medium->ma4;
 
862
 
 
863
      /* Either "paper" or "tray/paper" */
 
864
      papername.Truncate();
 
865
      if (default_medium->tray_name) {
 
866
        papername.Append(default_medium->tray_name);
 
867
        papername.Append("/");
 
868
      }
 
869
      papername.Append(default_medium->medium_name);
 
870
 
 
871
      DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g/%g mm)\n", papername.get(), total_width, total_height));
 
872
      aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined);
 
873
      aPrintSettings->SetPaperSizeUnit(nsIPrintSettings::kPaperSizeMillimeters);
 
874
      aPrintSettings->SetPaperWidth(total_width);
 
875
      aPrintSettings->SetPaperHeight(total_height);
 
876
      aPrintSettings->SetPaperName(NS_ConvertUTF8toUCS2(papername).get());     
 
877
 
 
878
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
879
      int i;
 
880
      for( i = 0 ; i < mcount ; i++ )
 
881
      {
 
882
        XpuMediumSourceSizeRec *curr = &mlist[i];
 
883
        double total_width  = curr->ma1 + curr->ma2,
 
884
               total_height = curr->ma3 + curr->ma4;
 
885
 
 
886
        papername.Truncate();
 
887
        if (curr->tray_name) {
 
888
          papername.Append(curr->tray_name);
 
889
          papername.Append("/");
 
890
        }
 
891
        papername.Append(curr->medium_name);
 
892
 
 
893
        printerFeatures.SetPaperRecord(i, papername, PRInt32(total_width), PRInt32(total_height), PR_FALSE);
 
894
      }
 
895
      printerFeatures.SetNumPaperSizeRecords(mcount);
 
896
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
897
 
 
898
      XpuFreeMediumSourceSizeList(mlist);
 
899
    }
 
900
 
 
901
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
902
    /* Xprint does not allow the client to set a spooler command. 
 
903
     * Job spooling is the job of the server side (=Xprt) */
 
904
    printerFeatures.SetCanChangeSpoolerCommand(PR_FALSE);
 
905
 
 
906
    /* Mozilla's Xprint support allows multiple nsIDeviceContext instances
 
907
     * be used in parallel */
 
908
    printerFeatures.SetMultipleConcurrentDeviceContextsSupported(PR_TRUE);
 
909
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
910
 
 
911
    XpuClosePrinterDisplay(pdpy, pcontext);
 
912
    
 
913
    return NS_OK;    
 
914
  }
 
915
  else
 
916
#endif /* USE_XPRINT */
 
917
 
 
918
#ifdef USE_POSTSCRIPT
 
919
  if (type == pmPostScript) {
 
920
    DO_PR_DEBUG_LOG(("InitPrintSettingsFromPrinter() for PostScript printer\n"));
 
921
 
 
922
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
923
    nsPrinterFeatures printerFeatures(fullPrinterName);
 
924
 
 
925
    printerFeatures.SetSupportsPaperSizeChange(PR_TRUE);
 
926
    printerFeatures.SetSupportsOrientationChange(PR_TRUE);
 
927
    printerFeatures.SetSupportsPlexChange(PR_FALSE);
 
928
    printerFeatures.SetSupportsSpoolerCommandChange(PR_TRUE);
 
929
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */ 
 
930
      
 
931
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
932
    printerFeatures.SetCanChangeOrientation(PR_TRUE);
 
933
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
934
 
 
935
    nsXPIDLCString orientation;
 
936
    if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "orientation", getter_Copies(orientation)))) {
 
937
      if (!PL_strcasecmp(orientation, "portrait")) {
 
938
        DO_PR_DEBUG_LOG(("setting default orientation to 'portrait'\n"));
 
939
        aPrintSettings->SetOrientation(nsIPrintSettings::kPortraitOrientation);
 
940
      }
 
941
      else if (!PL_strcasecmp(orientation, "landscape")) {
 
942
        DO_PR_DEBUG_LOG(("setting default orientation to 'landscape'\n"));
 
943
        aPrintSettings->SetOrientation(nsIPrintSettings::kLandscapeOrientation);  
 
944
      }
 
945
      else {
 
946
        DO_PR_DEBUG_LOG(("Unknown default orientation '%s'\n", orientation.get()));
 
947
      }
 
948
    }
 
949
 
 
950
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
951
    printerFeatures.SetOrientationRecord(0, "portrait");
 
952
    printerFeatures.SetOrientationRecord(1, "landscape");
 
953
    printerFeatures.SetNumOrientationRecords(2);
 
954
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
955
 
 
956
    /* PostScript module does not support changing the plex mode... */
 
957
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
958
    printerFeatures.SetCanChangePlex(PR_FALSE);
 
959
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
960
    DO_PR_DEBUG_LOG(("setting default plex to '%s'\n", "default"));
 
961
    aPrintSettings->SetPlexName(NS_LITERAL_STRING("default").get());
 
962
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
963
    printerFeatures.SetPlexRecord(0, "default");
 
964
    printerFeatures.SetNumPlexRecords(1);
 
965
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
966
   
 
967
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
968
    printerFeatures.SetCanChangePaperSize(PR_TRUE);
 
969
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
970
    nsXPIDLCString papername;
 
971
    if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "paper_size", getter_Copies(papername)))) {
 
972
      nsPaperSizePS paper;
 
973
      
 
974
      if (paper.Find(papername)) {
 
975
        DO_PR_DEBUG_LOG(("setting default paper size to '%s' (%g mm/%g mm)\n",
 
976
              paper.Name(), paper.Width_mm(), paper.Height_mm()));
 
977
        aPrintSettings->SetPaperSizeType(nsIPrintSettings::kPaperSizeDefined);
 
978
        aPrintSettings->SetPaperSizeUnit(paper.IsMetric() ?
 
979
            (int)nsIPrintSettings::kPaperSizeMillimeters :
 
980
            (int)nsIPrintSettings::kPaperSizeInches);
 
981
        aPrintSettings->SetPaperWidth(paper.Width_mm());
 
982
        aPrintSettings->SetPaperHeight(paper.Height_mm());
 
983
        aPrintSettings->SetPaperName(NS_ConvertASCIItoUCS2(paper.Name()).get());
 
984
      }
 
985
      else {
 
986
        DO_PR_DEBUG_LOG(("Unknown paper size '%s' given.\n", papername.get()));
 
987
      }
 
988
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
989
      paper.First();
 
990
      int count = 0;
 
991
      while (!paper.AtEnd())
 
992
      {
 
993
        printerFeatures.SetPaperRecord(count++, paper.Name(),
 
994
            (int)paper.Width_mm(), (int)paper.Height_mm(), !paper.IsMetric());
 
995
        paper.Next();
 
996
      }
 
997
      printerFeatures.SetNumPaperSizeRecords(count);
 
998
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
999
    }
 
1000
 
 
1001
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
1002
    printerFeatures.SetCanChangeSpoolerCommand(PR_TRUE);
 
1003
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
1004
 
 
1005
    nsXPIDLCString command;
 
1006
    if (NS_SUCCEEDED(CopyPrinterCharPref(pPrefs, "postscript", printerName, "print_command", getter_Copies(command)))) {
 
1007
      DO_PR_DEBUG_LOG(("setting default print command to '%s'\n", command.get()));
 
1008
      aPrintSettings->SetPrintCommand(NS_ConvertUTF8toUCS2(command).get());
 
1009
    }
 
1010
    
 
1011
#ifdef SET_PRINTER_FEATURES_VIA_PREFS
 
1012
    printerFeatures.SetCanChangeNumCopies(PR_TRUE);   
 
1013
#endif /* SET_PRINTER_FEATURES_VIA_PREFS */
 
1014
 
 
1015
    return NS_OK;    
 
1016
  }
 
1017
#endif /* USE_POSTSCRIPT */
 
1018
 
 
1019
  return NS_ERROR_UNEXPECTED;
 
1020
}
 
1021
 
 
1022
NS_IMETHODIMP nsPrinterEnumeratorXlib::DisplayPropertiesDlg(const PRUnichar *aPrinter, nsIPrintSettings *aPrintSettings)
 
1023
{
 
1024
  return NS_OK;
 
1025
}
 
1026
 
 
1027
//----------------------------------------------------------------------
 
1028
nsresult GlobalPrinters::InitializeGlobalPrinters ()
 
1029
{
 
1030
  if (PrintersAreAllocated()) {
 
1031
    return NS_OK;
 
1032
  }
 
1033
 
 
1034
  mGlobalNumPrinters = 0;
 
1035
  mGlobalPrinterList = new nsStringArray();
 
1036
  if (!mGlobalPrinterList) 
 
1037
    return NS_ERROR_OUT_OF_MEMORY;
 
1038
      
 
1039
#ifdef USE_XPRINT   
 
1040
  XPPrinterList plist = XpuGetPrinterList(nsnull, &mGlobalNumPrinters);
 
1041
  
 
1042
  if (plist && (mGlobalNumPrinters > 0))
 
1043
  {  
 
1044
    int i;
 
1045
    for(  i = 0 ; i < mGlobalNumPrinters ; i++ )
 
1046
    {
 
1047
      mGlobalPrinterList->AppendString(nsString(NS_ConvertASCIItoUCS2(plist[i].name)));
 
1048
    }
 
1049
    
 
1050
    XpuFreePrinterList(plist);
 
1051
  }
 
1052
#endif /* USE_XPRINT */
 
1053
 
 
1054
#ifdef USE_POSTSCRIPT
 
1055
  nsCOMPtr<nsIPref> pPrefs = do_GetService(NS_PREF_CONTRACTID);
 
1056
  PRBool psPrintModuleEnabled = PR_TRUE;
 
1057
 
 
1058
  const char *val = PR_GetEnv("MOZILLA_POSTSCRIPT_ENABLED");
 
1059
  if (val) {
 
1060
    if (val[0] == '0' || !strcasecmp(val, "false"))
 
1061
      psPrintModuleEnabled = PR_FALSE;
 
1062
  }
 
1063
  else
 
1064
  {
 
1065
    if (pPrefs) {
 
1066
      if (NS_FAILED(pPrefs->GetBoolPref("print.postscript.enabled", &psPrintModuleEnabled))) {
 
1067
        psPrintModuleEnabled = PR_TRUE;
 
1068
      }
 
1069
    }
 
1070
  }
 
1071
 
 
1072
  if (psPrintModuleEnabled) {
 
1073
    /* Get the list of PostScript-module printers */
 
1074
    char   *printerList           = nsnull;
 
1075
    PRBool  added_default_printer = PR_FALSE; /* Did we already add the default printer ? */
 
1076
 
 
1077
    /* The env var MOZILLA_POSTSCRIPT_PRINTER_LIST can "override" the prefs */
 
1078
    printerList = PR_GetEnv("MOZILLA_POSTSCRIPT_PRINTER_LIST");
 
1079
 
 
1080
    if (!printerList) {
 
1081
      if (pPrefs) {
 
1082
        (void) pPrefs->CopyCharPref("print.printer_list", &printerList);
 
1083
      }
 
1084
    }  
 
1085
 
 
1086
    if (printerList) {
 
1087
      char       *tok_lasts;
 
1088
      const char *name;
 
1089
 
 
1090
      /* PL_strtok_r() will modify the string - copy it! */
 
1091
      printerList = strdup(printerList);
 
1092
      if (!printerList)
 
1093
        return NS_ERROR_OUT_OF_MEMORY;    
 
1094
 
 
1095
      for( name = PL_strtok_r(printerList, " ", &tok_lasts) ; 
 
1096
           name != nsnull ; 
 
1097
           name = PL_strtok_r(nsnull, " ", &tok_lasts) )
 
1098
      {
 
1099
        /* Is this the "default" printer ? */
 
1100
        if (!strcmp(name, "default"))
 
1101
          added_default_printer = PR_TRUE;
 
1102
 
 
1103
        mGlobalPrinterList->AppendString(
 
1104
          nsString(NS_ConvertASCIItoUCS2(NS_POSTSCRIPT_DRIVER_NAME)) + 
 
1105
          nsString(NS_ConvertASCIItoUCS2(name)));
 
1106
        mGlobalNumPrinters++;      
 
1107
      }
 
1108
 
 
1109
      free(printerList);
 
1110
    }
 
1111
 
 
1112
    /* Add an entry for the default printer (see nsPostScriptObj.cpp) if we
 
1113
     * did not add it already... */
 
1114
    if (!added_default_printer)
 
1115
    {
 
1116
      mGlobalPrinterList->AppendString(
 
1117
        nsString(NS_ConvertASCIItoUCS2(NS_POSTSCRIPT_DRIVER_NAME "default")));
 
1118
      mGlobalNumPrinters++;
 
1119
    }
 
1120
  }
 
1121
#endif /* USE_POSTSCRIPT */  
 
1122
      
 
1123
  /* If there are no printers available after all checks, return an error */
 
1124
  if (mGlobalNumPrinters == 0)
 
1125
  {
 
1126
    /* Make sure we do not cache an empty printer list */
 
1127
    FreeGlobalPrinters();
 
1128
 
 
1129
#ifdef USE_XPRINT
 
1130
    /* Check if there are actually any Xprint servers available */
 
1131
    if (!XpuXprintServersAvailable()) {
 
1132
      return NS_ERROR_GFX_PRINTER_XPRINT_NO_XPRINT_SERVERS_FOUND;
 
1133
    }
 
1134
#endif /* USE_XPRINT */
 
1135
 
 
1136
    return NS_ERROR_GFX_PRINTER_NO_PRINTER_AVAILABLE;
 
1137
  }
 
1138
 
 
1139
  return NS_OK;
 
1140
}
 
1141
 
 
1142
//----------------------------------------------------------------------
 
1143
void GlobalPrinters::FreeGlobalPrinters()
 
1144
{
 
1145
  if (mGlobalPrinterList) {
 
1146
    delete mGlobalPrinterList;
 
1147
    mGlobalPrinterList = nsnull;
 
1148
    mGlobalNumPrinters = 0;
 
1149
  }  
 
1150
}
 
1151
 
 
1152
void 
 
1153
GlobalPrinters::GetDefaultPrinterName(PRUnichar **aDefaultPrinterName)
 
1154
{
 
1155
  *aDefaultPrinterName = nsnull;
 
1156
  
 
1157
  PRBool allocate = (GlobalPrinters::GetInstance()->PrintersAreAllocated() == PR_FALSE);
 
1158
  
 
1159
  if (allocate) {
 
1160
    nsresult rv = GlobalPrinters::GetInstance()->InitializeGlobalPrinters();
 
1161
    if (NS_FAILED(rv)) {
 
1162
      return;
 
1163
    }
 
1164
  }
 
1165
  NS_ASSERTION(GlobalPrinters::GetInstance()->PrintersAreAllocated(), "no GlobalPrinters");
 
1166
 
 
1167
  if (GlobalPrinters::GetInstance()->GetNumPrinters() == 0)
 
1168
    return;
 
1169
  
 
1170
  *aDefaultPrinterName = ToNewUnicode(*GlobalPrinters::GetInstance()->GetStringAt(0));
 
1171
 
 
1172
  if (allocate) {  
 
1173
    GlobalPrinters::GetInstance()->FreeGlobalPrinters();
 
1174
  }  
 
1175
}
 
1176