]> git.pld-linux.org Git - packages/libreoffice.git/blob - openoffice-print-cups.patch
- DON'T hardcode java paths!
[packages/libreoffice.git] / openoffice-print-cups.patch
1 Index: vcl/unx/source/gdi/makefile.mk
2 ===================================================================
3 RCS file: /cvs/gsl/vcl/unx/source/gdi/makefile.mk,v
4 retrieving revision 1.9
5 diff -u -p -u -r1.9 makefile.mk
6 --- vcl/unx/source/gdi/makefile.mk      27 Aug 2002 14:52:35 -0000      1.9
7 +++ vcl/unx/source/gdi/makefile.mk      29 May 2003 15:44:36 -0000
8 @@ -103,7 +103,8 @@ SLOFILES=   \
9  CFLAGS+=-D_USE_PRINT_EXTENSION_=1
10  SLOFILES+=$(SLO)$/xprintext.obj
11  .ELSE
12 -SLOFILES+=$(SLO)$/salprnpsp.obj
13 +CFLAGS+= `pkg-config --cflags libgnomecups-1.0`
14 +SLOFILES+=$(SLO)$/salprncups.obj
15  .ENDIF
16  
17  .IF "$(OS)"=="SOLARIS"
18 Index: vcl/unx/inc/salprn.h
19 ===================================================================
20 RCS file: /cvs/gsl/vcl/unx/inc/salprn.h,v
21 retrieving revision 1.9
22 diff -u -p -u -r1.9 salprn.h
23 --- vcl/unx/inc/salprn.h        13 Nov 2002 20:24:03 -0000      1.9
24 +++ vcl/unx/inc/salprn.h        2 Jun 2003 11:56:15 -0000
25 @@ -85,8 +85,10 @@ struct SalInfoPrinterData
26  
27  struct SalPrinterData
28  {
29 +       ULONG                            m_nError;
30         String                                  m_aFileName;
31         String                                  m_aTmpFile;
32 +       String                                  m_aJobName;
33         String                                  m_aFaxNr;
34         bool                                    m_bFax:1;
35         bool                                    m_bPdf:1;
36 @@ -95,7 +97,8 @@ struct SalPrinterData
37         ::psp::PrinterJob               m_aPrintJob;
38         ::psp::JobData                  m_aJobData;
39         ::psp::PrinterGfx               m_aPrinterGfx;
40 -    ULONG                                      m_nCopies;
41 +  ULONG                                        m_nCopies;
42 +       bool isPrintToFile() { return m_aFileName.Len() > 0; }
43  };
44  
45  class Timer;
46 --- /dev/null   2003-01-30 10:24:37.000000000 +0000
47 +++ vcl/unx/source/gdi/salprncups.cxx   2003-05-29 16:48:01.000000000 +0100
48 @@ -0,0 +1,1396 @@
49 +/*************************************************************************
50 + *
51 + *  $RCSfile$
52 + *
53 + *  $Revision$
54 + *
55 + *  last change: $Author$ $Date$
56 + *
57 + *  The Contents of this file are made available subject to the terms of
58 + *  either of the following licenses
59 + *
60 + *         - GNU Lesser General Public License Version 2.1
61 + *         - Sun Industry Standards Source License Version 1.1
62 + *
63 + *  Sun Microsystems Inc., October, 2000
64 + *
65 + *  GNU Lesser General Public License Version 2.1
66 + *  =============================================
67 + *  Copyright 2000 by Sun Microsystems, Inc.
68 + *  901 San Antonio Road, Palo Alto, CA 94303, USA
69 + *
70 + *  This library is free software; you can redistribute it and/or
71 + *  modify it under the terms of the GNU Lesser General Public
72 + *  License version 2.1, as published by the Free Software Foundation.
73 + *
74 + *  This library is distributed in the hope that it will be useful,
75 + *  but WITHOUT ANY WARRANTY; without even the implied warranty of
76 + *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
77 + *  Lesser General Public License for more details.
78 + *
79 + *  You should have received a copy of the GNU Lesser General Public
80 + *  License along with this library; if not, write to the Free Software
81 + *  Foundation, Inc., 59 Temple Place, Suite 330, Boston,
82 + *  MA  02111-1307  USA
83 + *
84 + *
85 + *  Sun Industry Standards Source License Version 1.1
86 + *  =================================================
87 + *  The contents of this file are subject to the Sun Industry Standards
88 + *  Source License Version 1.1 (the "License"); You may not use this file
89 + *  except in compliance with the License. You may obtain a copy of the
90 + *  License at http://www.openoffice.org/license.html.
91 + *
92 + *  Software provided under this License is provided on an "AS IS" basis,
93 + *  WITHOUT WARRANTY OF ANY KIND, EITHER EXPRESSED OR IMPLIED, INCLUDING,
94 + *  WITHOUT LIMITATION, WARRANTIES THAT THE SOFTWARE IS FREE OF DEFECTS,
95 + *  MERCHANTABLE, FIT FOR A PARTICULAR PURPOSE, OR NON-INFRINGING.
96 + *  See the License for the specific provisions governing your rights and
97 + *  obligations concerning the Software.
98 + *
99 + *  The Initial Developer of the Original Code is: Sun Microsystems, Inc.
100 + *
101 + *  Copyright: 2000 by Sun Microsystems, Inc.
102 + *
103 + *  All Rights Reserved.
104 + *
105 + *  Contributor(s): _______________________________________
106 + *
107 + *
108 + ************************************************************************/
109 +
110 +/**
111 +  this file implements the sal printer interface ( SalPrinter, SalInfoPrinter
112 +  and some printer relevant methods of SalInstance and SalGraphicsData )
113 +
114 +  as aunderlying library the printer features of psprint are used.
115 +
116 +  The query methods of a SalInfoPrinter are implemented by querying psprint
117 +
118 +  The job methods of a SalPrinter are implemented by calling psprint
119 +  printer job functions.
120 + */
121 +
122 +#include <salunx.h>
123 +#include <unistd.h>
124 +#include <sys/wait.h>
125 +
126 +#ifndef _SV_JOBSET_H
127 +#include <jobset.h>
128 +#endif
129 +#ifndef _SV_SALINST_HXX
130 +#include <salinst.hxx>
131 +#endif
132 +#ifndef _SV_SALPRN_HXX
133 +#include <salprn.hxx>
134 +#endif
135 +#ifndef _SV_SALGDI_HXX
136 +#include <salgdi.hxx>
137 +#endif
138 +#ifndef _SV_PRINT_H
139 +#include <print.h>
140 +#endif
141 +#ifndef _SV_SALPTYPE_HXX
142 +#include <salptype.hxx>
143 +#endif
144 +#ifndef _SV_SALFRAME_HXX
145 +#include <salframe.hxx>
146 +#endif
147 +#ifndef _SV_SALDATA_HXX
148 +#include <saldata.hxx>
149 +#endif
150 +
151 +#include <sys/types.h>
152 +#include <sys/stat.h>
153 +#include <fcntl.h>
154 +#include <stdio.h>
155 +
156 +#include <glib.h>
157 +
158 +#include <psprint/printerinfomanager.hxx>
159 +
160 +#ifndef _PSPRINT_JOBDATA_HXX_
161 +#include <psprint/jobdata.hxx>
162 +#endif
163 +
164 +#include <libgnomecups/gnome-cups-init.h>
165 +#include <libgnomecups/gnome-cups-printer.h>
166 +
167 +static bool cups_debug = false;
168 +
169 +namespace cups { };
170 +
171 +using namespace cups;
172 +using namespace psp;
173 +using namespace rtl;
174 +using namespace osl;
175 +
176 +namespace cups {
177 +
178 +  class PrinterInfoManagerCups : ::psp::PrinterInfoManager
179 +  {
180 +    PrinterInfoManagerCups();
181 +    void initialize ();
182 +
183 +    ::psp::JobData  m_aGlobalDefaults;
184 +    ::rtl::OUString m_aDefaultPrinter;
185 +    GList          *m_aPrinterList;
186 +    ::std::hash_map< ::rtl::OUString, ::psp::JobData, ::rtl::OUStringHash > m_aJobDataCache;
187 +
188 +  private:
189 +    void mergeToJobData    ( ::psp::JobData &rJobInfo, const PPDParser *pParser );
190 +    void mergeCupsSettings ( ::psp::JobData &rJobInfo );
191 +  public:
192 +    String          m_aGlobalDriverName;
193 +    static PrinterInfoManagerCups& getCups();
194 +
195 +    bool isBuiltinGeneric() { return m_aPrinterList == NULL; };
196 +
197 +    void                   listPrinters           ( ::std::list< ::rtl::OUString >& rList ) const;
198 +    ::psp::JobData         getJobInfo             ( const ::rtl::OUString& rPrinter );
199 +    SalPrinterQueueInfo   *getSalPrinterQueueInfo ( const ::rtl::OUString& rPrinter );
200 +    bool                   checkPrintersChanged   ();
201 +    GnomeCupsPrinter      *getGnomePrinter        ( const ::rtl::OUString& rPrinter );
202 +    GnomeCupsPrinter      *getGnomePrinter        ( SalPrinterQueueInfo *aQueueInfo )
203 +    { return getGnomePrinter ( aQueueInfo->maPrinterName ); }
204 +    const ::rtl::OUString& getDefaultPrinter      () const
205 +    { return m_aDefaultPrinter; }
206 +    virtual const PPDParser *getParserForPrinter( ::rtl::OUString rPrinter );
207 +    virtual ::std::hash_map< fontID, fontID > *getFontSubstitutesForPrinter( ::rtl::OUString rPrinter );
208 +    virtual FILE *getPipeToPrinter( ::rtl::OUString rPrinter );
209 +  };
210 +
211 +  PrinterInfoManagerCups& PrinterInfoManagerCups::getCups()
212 +  {
213 +    static PrinterInfoManagerCups aManager;
214 +    set( &aManager );
215 +    return aManager;
216 +  }
217 +
218 +  extern "C" {
219 +    static gboolean
220 +    gcups_password_cb (const char           *prompt,
221 +                      char                **username,
222 +                      char                **password,
223 +                      GnomeCupsAuthContext *ctxt)
224 +    {
225 +      fprintf( stderr, "No authentication yet\n" );
226 +      return FALSE;
227 +    }
228 +  }
229 +
230 +  PrinterInfoManagerCups::PrinterInfoManagerCups()
231 +  {
232 +    static bool cups_initialized = false;
233 +    if (!cups_initialized) {
234 +      cups_initialized = true;
235 +      gnome_cups_init( gcups_password_cb );
236 +      if (g_getenv ("CUPS_DEBUG") &&
237 +         atoi (g_getenv ("CUPS_DEBUG")))
238 +             cups_debug = true;
239 +    }
240 +    initialize ();
241 +  }
242 +
243 +  const ::psp::PPDParser *
244 +  PrinterInfoManagerCups::getParserForPrinter( ::rtl::OUString rPrinter )
245 +  {
246 +    return getJobInfo( rPrinter ).m_pParser;
247 +  }
248 +
249 +  ::std::hash_map< fontID, fontID > *
250 +  PrinterInfoManagerCups::getFontSubstitutesForPrinter( ::rtl::OUString rPrinter )
251 +  { // font mapping tables are a terrible idea.
252 +    return NULL;
253 +  }
254 +
255 +  FILE *
256 +  PrinterInfoManagerCups::getPipeToPrinter( ::rtl::OUString rPrinter )
257 +  { // we always print to a file
258 +    return NULL;
259 +  }
260 +
261 +  bool PrinterInfoManagerCups::checkPrintersChanged()
262 +  {
263 +    bool different = false;
264 +    GList *printers;
265 +
266 +    /* gnome-cups does timeout polling */
267 +    printers = gnome_cups_get_printers ();
268 +    if (g_list_length (printers) != g_list_length (m_aPrinterList))
269 +      different = true;
270 +    else {
271 +      GList *l1, *l2;
272 +      for (l2 = m_aPrinterList, l1 = printers;
273 +          l1 && l2; l1 = l1->next, l2 = l2->next) {
274 +       if (strcmp ((char *) l1->data, (char *) l2->data)) {
275 +         different = true;
276 +         break;
277 +       }
278 +      }
279 +    }
280 +
281 +    if (different)
282 +      initialize ();
283 +  
284 +    return different;
285 +  }
286 +
287 +  void PrinterInfoManagerCups::initialize()
288 +  {
289 +    rtl_TextEncoding aEncoding = osl_getThreadTextEncoding();
290 +    OUString aPrinterPath( getPrinterPath() );
291 +    m_aJobDataCache.clear();
292 +
293 +    // first initialize the global defaults
294 +    m_aGlobalDefaults = JobData();
295 +    m_aGlobalDriverName = String( RTL_CONSTASCII_USTRINGPARAM( "CUPS" ) );
296 +    
297 +    // g_warning ("We need to parse SGEN43.PS ... - how can we ship that ?");
298 +    // need a parser for the PPDContext. generic printer should do.
299 +    m_aGlobalDefaults.m_pParser = PPDParser::getParser
300 +      ( String( RTL_CONSTASCII_USTRINGPARAM( "SGENPRT" ) ) );
301 +    m_aGlobalDefaults.m_aContext.setParser( m_aGlobalDefaults.m_pParser );
302 +
303 +    if( ! m_aGlobalDefaults.m_pParser )
304 +      {
305 +        fprintf( stderr, "Error: no SGENPRT available, shutting down psprint...\n" );
306 + //       return;
307 +      }
308 +
309 +    char *prnt;
310 +    if (!(prnt = gnome_cups_get_default()))
311 +      prnt = g_strdup("GenericPostscript");
312 +    m_aDefaultPrinter = OUString( prnt, strlen( prnt ), RTL_TEXTENCODING_UTF8 );
313 +    g_free( prnt );
314 +
315 +    gnome_cups_printer_list_free( m_aPrinterList );
316 +    m_aPrinterList = gnome_cups_get_printers();
317 +  }
318 +
319 +  void
320 +  PrinterInfoManagerCups::listPrinters( ::std::list< OUString >& rList ) const
321 +  {
322 +    GList *l;
323 +
324 +    rList.clear();
325 +    if (m_aPrinterList)
326 +      {
327 +       for (l = m_aPrinterList; l; l = l->next)
328 +         rList.push_back( OUString( (char *)l->data,
329 +                                    strlen( (char *) l->data ),
330 +                                    RTL_TEXTENCODING_UTF8 ) );
331 +      }
332 +    else
333 +      {
334 +       rList.push_back( ::rtl::OUString::createFromAscii( "GenericPostscript" ) );
335 +      }
336 +  }
337 +
338 +  GnomeCupsPrinter *
339 +  PrinterInfoManagerCups::getGnomePrinter ( const ::rtl::OUString& rPrinter )
340 +  {
341 +    if (isBuiltinGeneric())
342 +      return NULL;
343 +    else
344 +      {
345 +       OString name = OUStringToOString( rPrinter, RTL_TEXTENCODING_UTF8 );
346 +       return gnome_cups_printer_get (name.getStr());
347 +      }
348 +  }
349 +
350 +  SalPrinterQueueInfo*
351 +  PrinterInfoManagerCups::getSalPrinterQueueInfo ( const ::rtl::OUString& rPrinter )
352 +  {
353 +    GnomeCupsPrinter *printer = getGnomePrinter( rPrinter );
354 +
355 +    OString name = OUStringToOString( rPrinter, RTL_TEXTENCODING_UTF8 );
356 +    //    fprintf (stderr, "Add printer '%s'\n", name.getStr());
357 +
358 +    SalPrinterQueueInfo* pInfo = new SalPrinterQueueInfo;
359 +    pInfo->maPrinterName  = OUString (rPrinter);
360 +    pInfo->maDriver       = m_aGlobalDriverName;
361 +    pInfo->maLocation     = String
362 +      ( printer ? gnome_cups_printer_get_location( printer ) : "", RTL_TEXTENCODING_UTF8);
363 +    pInfo->maComment      = String
364 +      ( printer ? gnome_cups_printer_get_description (printer) : "", RTL_TEXTENCODING_UTF8);
365 +    pInfo->mpSysData      = NULL;
366 +    pInfo->mnJobs         = printer ? gnome_cups_printer_get_job_count (printer) : 0;
367 +
368 +    gnome_cups_printer_unref( printer );
369 +
370 +    return pInfo;
371 +  }
372 +
373 +  
374 +  void
375 +  PrinterInfoManagerCups::mergeToJobData ( ::psp::JobData  &rJobInfo,
376 +                                          const PPDParser *pParser )
377 +  {
378 +    rJobInfo.m_pParser = pParser;
379 +    rJobInfo.m_aContext.setParser( pParser );
380 +
381 +    // merge the ppd context keys if the printer has the same keys and values
382 +    // this is a bit tricky, since it involves mixing two PPDs
383 +    // without constraints which might end up badly
384 +    // this feature should be use with caution
385 +    // it is mainly to select default paper sizes for new printers
386 +    for( int nPPDValueModified = 0; nPPDValueModified < m_aGlobalDefaults.m_aContext.countValuesModified(); nPPDValueModified++ )
387 +      {
388 +       const PPDKey* pDefKey = m_aGlobalDefaults.m_aContext.getModifiedKey( nPPDValueModified );
389 +       const PPDValue* pDefValue = m_aGlobalDefaults.m_aContext.getValue( pDefKey );
390 +       const PPDKey* pPrinterKey = pDefKey ? rJobInfo.m_pParser->getKey( pDefKey->getKey() ) : NULL;
391 +       if( pDefKey && pPrinterKey )
392 +         // at least the options exist in both PPDs
393 +         {
394 +           if( pDefValue )
395 +             {
396 +               const PPDValue* pPrinterValue = pPrinterKey->getValue( pDefValue->m_aOption );
397 +               if( pPrinterValue )
398 +                                // the printer has a corresponding option for the key
399 +                 rJobInfo.m_aContext.setValue( pPrinterKey, pPrinterValue );
400 +             }
401 +           else
402 +             rJobInfo.m_aContext.setValue( pPrinterKey, NULL );
403 +         }
404 +      }
405 +  }
406 +
407 +  void
408 +  PrinterInfoManagerCups::mergeCupsSettings( ::psp::JobData &rJobInfo )
409 +  {
410 +    GnomeCupsPrinter *printer;
411 +
412 +    printer = getGnomePrinter( rJobInfo.m_aPrinterName );
413 +
414 +    if( cups_debug ) {
415 +      gnome_cups_printer_force_refresh( printer, GNOME_CUPS_PRINTER_REFRESH_OPTIONS );
416 +      g_warning ("Forced printer option refresh");
417 +    }
418 +
419 +    // Set the local cups options
420 +    if (printer)
421 +      {
422 +       if (cups_debug)
423 +         g_warning ("Refreshing user options ...");
424 +
425 +        GList *user_options = gnome_cups_printer_get_options (printer);
426 +       
427 +       for (GList *l = user_options; l; l = l->next)
428 +          {
429 +            GnomeCupsPrinterOptionChoice *opt = (GnomeCupsPrinterOptionChoice *) l->data;
430 +
431 +           char *value = gnome_cups_printer_get_option_value (printer, opt->value);
432 +
433 +           if (cups_debug)
434 +             g_warning (" '%s' -> '%s'", opt->value, value);
435 +
436 +           if (!opt->text || !value)
437 +              continue;
438 +
439 +           const PPDKey* pKey;
440 +
441 +           pKey = rJobInfo.m_pParser->getKey( String::CreateFromAscii( opt->value ) );
442 +           if (pKey) {
443 +                   const PPDValue* pValue;
444 +
445 +                   pValue = pKey->getValue( String( value, RTL_TEXTENCODING_UTF8 ) );
446 +
447 +                   if (pValue)
448 +                     rJobInfo.m_aContext.setValue( pKey, pValue );
449 +
450 +                   else if (cups_debug)
451 +                     g_warning ("No value '%s'", value);
452 +
453 +           } else if (cups_debug)
454 +              g_warning ("No key '%s'", opt->value);
455 +         }
456 +       gnome_cups_printer_option_list_free (user_options);
457 +
458 +       gnome_cups_printer_unref( printer );
459 +    }
460 +    else if (cups_debug)
461 +      g_warning ("No printer");
462 +  }
463 +
464 +  ::psp::JobData
465 +  PrinterInfoManagerCups::getJobInfo( const ::rtl::OUString& rPrinter )
466 +  {
467 +    ::std::hash_map< OUString, ::psp::JobData, OUStringHash >::const_iterator it = m_aJobDataCache.find( rPrinter );
468 +
469 +    if (it != m_aJobDataCache.end()) {
470 +      ::psp::JobData aJobInfo = it->second;
471 +      mergeCupsSettings( aJobInfo );
472 +
473 +      return aJobInfo;
474 +    }
475 +
476 +    ::psp::JobData aJobInfo = m_aGlobalDefaults;
477 +
478 +    OString name = OUStringToOString( rPrinter, RTL_TEXTENCODING_UTF8 );
479 +
480 +    aJobInfo.m_aPrinterName = OUString (rPrinter);
481 +
482 +    const char *v;
483 +    if( cups_debug && (v = g_getenv( "PPD_DO" )) && atoi( v ) )
484 +      g_warning ("--- ppd parsing disabled ---");
485 +    else
486 +      {
487 +        GnomeCupsPrinter *printer = NULL;
488 +       GnomeCupsPPDFile *ppd_file = NULL;
489 +       char             *ppd_fname = NULL;
490 +       const PPDParser  *pParser = NULL;
491 +
492 +       if ( ( printer   = getGnomePrinter( rPrinter ) ) &&
493 +            ( ppd_file  = gnome_cups_printer_get_ppd_file( printer ) ) &&
494 +            ( ppd_fname = gnome_cups_ppd_file_get_name( ppd_file ) ) &&
495 +            ( pParser   = PPDParser::getParser ( String( ppd_fname, RTL_TEXTENCODING_UTF8 ) ) ) &&
496 +            pParser )
497 +         {
498 +           if (cups_debug)
499 +             g_warning ("---- parse ppd ...----");
500 +           mergeToJobData (aJobInfo, pParser);
501 +         }
502 +       else if (cups_debug)
503 +         g_warning ("---- failed to parse ppd '%s' ----", ppd_fname);
504 +
505 +       g_free( ppd_fname );
506 +       gnome_cups_ppd_file_release( ppd_file );
507 +       gnome_cups_printer_unref( printer );
508 +      }
509 +
510 +    mergeCupsSettings( aJobInfo );
511 +
512 +
513 +    m_aJobDataCache[ rPrinter ] = aJobInfo;
514 +
515 +    return aJobInfo;
516 +  }
517 +
518 +} /* namespace cups */
519 +
520 +inline int PtTo10Mu( int nPoints ) { return (int)(((double)nPoints)*35.27777778)+0.5; }
521 +
522 +inline int TenMuToPt( int nUnits ) { return (int)(((double)nUnits)/35.27777778)+0.5; }
523 +
524 +static struct
525 +{
526 +       int                     width;
527 +       int                     height;
528 +       const char*     name;
529 +       int                     namelength;
530 +       Paper           paper;
531 +} aPaperTab[] =
532 +{
533 +       { 29700, 42000, "A3",                   2,      PAPER_A3                },
534 +       { 21000, 29700, "A4",                   2,      PAPER_A4                },
535 +       { 14800, 21000, "A5",                   2,      PAPER_A5                },
536 +       { 25000, 35300, "B4",                   2,      PAPER_B4                },
537 +       { 17600, 25000, "B5",                   2,      PAPER_B5                },
538 +       { 21600, 27900, "Letter",               6,      PAPER_LETTER    },
539 +       { 21600, 35600, "Legal",                5,      PAPER_LEGAL             },
540 +       { 27900, 43100, "Tabloid",              7,      PAPER_TABLOID   },
541 +       { 0, 0,                 "USER",                 4,      PAPER_USER              }
542 +};
543 +
544 +static Paper getPaperType( const String& rPaperName )
545 +{
546 +       ByteString aPaper( rPaperName, RTL_TEXTENCODING_ISO_8859_1 );
547 +       for( int i = 0; i < sizeof( aPaperTab )/sizeof( aPaperTab[0] ); i++ )
548 +       {
549 +               if( ! strcmp( aPaper.GetBuffer(), aPaperTab[i].name ) )
550 +                       return aPaperTab[i].paper;
551 +       }
552 +       return PAPER_USER;
553 +}
554 +
555 +static void copyJobDataToJobSetup( ImplJobSetup* pJobSetup, JobData& rData )
556 +{
557 +
558 +  pJobSetup->meOrientation = (Orientation)(rData.m_eOrientation == orientation::Landscape ?
559 +                                          ORIENTATION_LANDSCAPE : ORIENTATION_PORTRAIT);
560 +
561 +  // copy page size
562 +  String aPaper;
563 +  int width, height;
564 +       
565 +  rData.m_aContext.getPageSize( aPaper, width, height );
566 +  pJobSetup->mePaperFormat = getPaperType( aPaper );
567 +  pJobSetup->mnPaperWidth  = 0;
568 +  pJobSetup->mnPaperHeight = 0;
569 +  if( pJobSetup->mePaperFormat == PAPER_USER )
570 +    {
571 +      // transform to 100dth mm
572 +      width  = PtTo10Mu( width );
573 +      height = PtTo10Mu( height );
574 +
575 +      if( rData.m_eOrientation == psp::orientation::Portrait )
576 +        {
577 +         pJobSetup->mnPaperWidth  = width;
578 +         pJobSetup->mnPaperHeight = height;
579 +        }
580 +      else
581 +        {
582 +         pJobSetup->mnPaperWidth  = height;
583 +         pJobSetup->mnPaperHeight = width;
584 +        }
585 +    }
586 +
587 +  // copy input slot
588 +  const PPDKey* pKey;
589 +  const PPDValue* pValue;
590 +  ::std::list< const PPDValue* > aValues;
591 +  ::std::list< const PPDValue* >::iterator it;
592 +
593 +  pKey   = rData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) );
594 +  pValue = rData.m_aContext.getValue( pKey );
595 +  rData.m_aContext.getUnconstrainedValues( pKey, aValues );
596 +  pJobSetup->mnPaperBin = 0xffff;
597 +  if ( pKey && pValue )
598 +  {
599 +        for( pJobSetup->mnPaperBin = 0;
600 +             pValue != pKey->getValue( pJobSetup->mnPaperBin ) &&
601 +                 pJobSetup->mnPaperBin < pKey->countValues();
602 +             pJobSetup->mnPaperBin++ )
603 +            ;
604 +        if( pJobSetup->mnPaperBin >= pKey->countValues() || pValue == pKey->getDefaultValue() )
605 +               pJobSetup->mnPaperBin = 0xffff;
606 +  }
607 +  for( it = aValues.begin(); it != aValues.end(); ++it, pJobSetup->mnPaperBin++ )
608 +    if( *it == pValue )
609 +      break;
610 +  if( it == aValues.end() )
611 +    pJobSetup->mnPaperBin = 0xffff;
612 +       
613 +  // copy the whole context
614 +  if( pJobSetup->mpDriverData )
615 +    rtl_freeMemory( pJobSetup->mpDriverData );
616 +
617 +  int nBytes;
618 +  void* pBuffer = NULL;
619 +  if( rData.getStreamBuffer( pBuffer, nBytes ) )
620 +    {
621 +      pJobSetup->mnDriverDataLen = nBytes;
622 +      pJobSetup->mpDriverData = (BYTE*)pBuffer;
623 +    }
624 +  else
625 +    {
626 +      pJobSetup->mnDriverDataLen = 0;
627 +      pJobSetup->mpDriverData = NULL;
628 +    }
629 +}
630 +
631 +/*
632 + *     SalInstance
633 + */
634 +
635 +// -----------------------------------------------------------------------
636 +
637 +SalInfoPrinter* SalInstance::CreateInfoPrinter(
638 +       SalPrinterQueueInfo *pQueueInfo,
639 +       ImplJobSetup        *pJobSetup )
640 +{
641 +  maInstData.mbPrinterInit = true;
642 +
643 +  SalInfoPrinter* pPrinter = new SalInfoPrinter;
644 +  PrinterInfoManagerCups& rManager( PrinterInfoManagerCups::getCups() );
645 +  ::psp::JobData aJobInfo = rManager.getJobInfo( pQueueInfo->maPrinterName );
646 +
647 +  pPrinter->maPrinterData.m_aJobData = aJobInfo;
648 +  pPrinter->maPrinterData.m_aPrinterGfx.Init( pPrinter->maPrinterData.m_aJobData );
649 +
650 +  if( pJobSetup )
651 +    {
652 +      if( pJobSetup->mpDriverData )
653 +       JobData::constructFromStreamBuffer( pJobSetup->mpDriverData,
654 +                                           pJobSetup->mnDriverDataLen,
655 +                                           aJobInfo );
656 +
657 +      pJobSetup->mnSystem      = JOBSETUP_SYSTEM_UNIX;
658 +      pJobSetup->maPrinterName = pQueueInfo->maPrinterName;
659 +      pJobSetup->maDriver      = rManager.m_aGlobalDriverName;
660 +      copyJobDataToJobSetup( pJobSetup, aJobInfo );
661 +    }
662 +       
663 +  return pPrinter;
664 +}
665 +
666 +// -----------------------------------------------------------------------
667 +
668 +void SalInstance::DestroyInfoPrinter( SalInfoPrinter* pPrinter )
669 +{
670 +  delete pPrinter;
671 +}
672 +
673 +// -----------------------------------------------------------------------
674 +
675 +SalPrinter* SalInstance::CreatePrinter( SalInfoPrinter* pInfoPrinter )
676 +{
677 +  maInstData.mbPrinterInit = true;
678 +  // create and initialize SalPrinter
679 +  SalPrinter* pPrinter = new SalPrinter;
680 +  pPrinter->maPrinterData.m_aJobData = pInfoPrinter->maPrinterData.m_aJobData;
681 +       
682 +  return pPrinter;
683 +}
684 +
685 +// -----------------------------------------------------------------------
686 +
687 +void SalInstance::DestroyPrinter( SalPrinter* pPrinter )
688 +{
689 +  delete pPrinter;
690 +}
691 +
692 +// -----------------------------------------------------------------------
693 +
694 +void SalInstance::GetPrinterQueueInfo( ImplPrnQueueList* pList )
695 +{
696 +  maInstData.mbPrinterInit = true;
697 +  PrinterInfoManagerCups& rManager( PrinterInfoManagerCups::getCups() );
698 +  ::std::list< OUString > aPrinters;
699 +  rManager.listPrinters( aPrinters );
700 +
701 +  for( ::std::list< OUString >::iterator it = aPrinters.begin(); it != aPrinters.end(); ++it ) {
702 +    SalPrinterQueueInfo *pInfo = rManager.getSalPrinterQueueInfo( *it );
703 +    GetPrinterQueueState( pInfo );
704 +    pList->Add( pInfo );
705 +  }
706 +}
707 +
708 +// -----------------------------------------------------------------------
709 +
710 +void SalInstance::DeletePrinterQueueInfo( SalPrinterQueueInfo* pInfo )
711 +{
712 +  delete pInfo;
713 +}
714 +
715 +// -----------------------------------------------------------------------
716 +
717 +void SalInstance::GetPrinterQueueState( SalPrinterQueueInfo* pInfo )
718 +{
719 +  if (!pInfo)
720 +    return;
721 +
722 +  GnomeCupsPrinter *printer;
723 +  printer = PrinterInfoManagerCups::getCups().getGnomePrinter( pInfo );
724 +  if (!printer)
725 +    {
726 +      pInfo->mnStatus = QUEUE_STATUS_READY;
727 +      return;
728 +    }
729 +
730 +  switch (gnome_cups_printer_get_state (printer)) {
731 +  case IPP_PRINTER_IDLE:
732 +    pInfo->mnStatus = QUEUE_STATUS_READY;
733 +    break;
734 +  case IPP_PRINTER_PROCESSING:
735 +    pInfo->mnStatus = QUEUE_STATUS_PROCESSING;
736 +    break;
737 +  case IPP_PRINTER_STOPPED:
738 +  default:
739 +    pInfo->mnStatus = QUEUE_STATUS_ERROR;
740 +
741 +    GList *l, *reasons = gnome_cups_printer_get_state_reasons (printer);
742 +    if (!reasons || !reasons->data)
743 +      break;
744 +
745 +    pInfo->mnStatus = 0;
746 +    for (l = reasons; l; l = l->next) {
747 +      GnomeCupsPrinterReason *reason = (GnomeCupsPrinterReason *) reasons->data;
748 +    
749 +#define MAP_STATUS(str,en) \
750 +      if (!strcmp (reason->keyword, (str))) \
751 +        pInfo->mnStatus |= QUEUE_STATUS_##en;
752 +
753 +      /* cf. RFC 2911.txt 4.4.12 */
754 +      MAP_STATUS ("stopping", PENDING_DELETION);
755 +      MAP_STATUS ("timed-out", ERROR);
756 +      MAP_STATUS ("media-empty", PAPER_PROBLEM);
757 +      MAP_STATUS ("connecting-to-device", IO_ACTIVE);
758 +      MAP_STATUS ("output-tray-area-full", OUTPUT_BIN_FULL);
759 +      MAP_STATUS ("marker-supply-low", TONER_LOW);
760 +      MAP_STATUS ("marker-supply-empty", NO_TONER);
761 +      MAP_STATUS ("developer-low", TONER_LOW);
762 +      MAP_STATUS ("developer-empty", NO_TONER);
763 +      MAP_STATUS ("marker-waste-full", USER_INTERVENTION);
764 +      MAP_STATUS ("door-open", DOOR_OPEN);
765 +      MAP_STATUS ("cover-open", DOOR_OPEN);
766 +      MAP_STATUS ("interlock-open", DOOR_OPEN);
767 +      MAP_STATUS ("input-tray-missing", DOOR_OPEN);
768 +      MAP_STATUS ("output-tray-missing", DOOR_OPEN);
769 +      MAP_STATUS ("none", ERROR); // ?
770 +      MAP_STATUS ("other", ERROR);
771 +      MAP_STATUS ("paused", PAUSED);
772 +      MAP_STATUS ("moving-to-paused", PAUSED);
773 +      MAP_STATUS ("shutdown", OFFLINE);
774 +      MAP_STATUS ("media-jam", PAPER_JAM);
775 +      MAP_STATUS ("media-needed", PAPER_OUT);
776 +      MAP_STATUS ("media-low", READY); // PAPER_PROBLEM
777 +      MAP_STATUS ("output-tray-area-almost-full", READY); // OUTPUT_BIN_FULL
778 +      MAP_STATUS ("marker-waste-almost-full", READY); // USER_INTERVENTION
779 +#undef MAP_STATUS
780 +    }
781 +
782 +    if ( !pInfo->mnStatus )
783 +      pInfo->mnStatus = QUEUE_STATUS_ERROR;
784 +
785 +    gnome_cups_printer_free_reasons( reasons );
786 +    break;
787 +  }
788 +  gnome_cups_printer_unref( printer );
789 +}
790 +
791 +// -----------------------------------------------------------------------
792 +
793 +String SalInstance::GetDefaultPrinter()
794 +{
795 +    maInstData.mbPrinterInit = true;
796 +       PrinterInfoManagerCups& rManager( PrinterInfoManagerCups::getCups() );
797 +       return rManager.getDefaultPrinter();
798 +}
799 +
800 +// =======================================================================
801 +
802 +SalInfoPrinter::SalInfoPrinter()
803 +{
804 +       maPrinterData.m_pGraphics = NULL;
805 +       m_bPapersInit = false;
806 +}
807 +
808 +// -----------------------------------------------------------------------
809 +
810 +SalInfoPrinter::~SalInfoPrinter()
811 +{
812 +  if( maPrinterData.m_pGraphics )
813 +    {
814 +      delete maPrinterData.m_pGraphics;
815 +      maPrinterData.m_pGraphics = NULL;
816 +    }
817 +}
818 +
819 +// -----------------------------------------------------------------------
820 +
821 +
822 +void SalInfoPrinter::InitPaperFormats( const ImplJobSetup* pSetupData )
823 +{
824 +    m_aPaperFormats.clear();
825 +    m_bPapersInit = true;
826 +
827 +    if( maPrinterData.m_aJobData.m_pParser )
828 +    {
829 +        const PPDKey* pKey = maPrinterData.m_aJobData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
830 +        if( pKey )
831 +        {
832 +            int nValues = pKey->countValues();
833 +            for( int i = 0; i < nValues; i++ )
834 +            {
835 +                const PPDValue* pValue = pKey->getValue( i );
836 +                vcl::PaperInfo aInfo;
837 +                aInfo.m_aPaperName = pValue->m_aOptionTranslation;
838 +                if( ! aInfo.m_aPaperName.Len() )
839 +                    aInfo.m_aPaperName = pValue->m_aOption;
840 +                int nWidth = 0, nHeight = 0;
841 +                maPrinterData.m_aJobData.m_pParser->getPaperDimension( pValue->m_aOption, nWidth, nHeight );
842 +                aInfo.m_nPaperWidth = (unsigned long)((PtTo10Mu( nWidth )+50)/100);
843 +                aInfo.m_nPaperHeight = (unsigned long)((PtTo10Mu( nHeight )+50)/100);
844 +                m_aPaperFormats.push_back( aInfo );
845 +            }
846 +        }
847 +    }
848 +}
849 +
850 +// -----------------------------------------------------------------------
851 +
852 +int SalInfoPrinter::GetLandscapeAngle( const ImplJobSetup* pSetupData )
853 +{
854 +    return 900;
855 +}
856 +
857 +// -----------------------------------------------------------------------
858 +
859 +SalGraphics* SalInfoPrinter::GetGraphics()
860 +{
861 +  // return a valid pointer only once
862 +  // the reasoning behind this is that we could have different
863 +  // SalGraphics that can run in multiple threads
864 +  // (future plans)
865 +  SalGraphics* pRet = NULL;
866 +  if( ! maPrinterData.m_pGraphics )
867 +    {
868 +      maPrinterData.m_pGraphics = new SalGraphics;
869 +      maPrinterData.m_pGraphics->maGraphicsData.m_pJobData     = &maPrinterData.m_aJobData;
870 +      maPrinterData.m_pGraphics->maGraphicsData.m_pPrinterGfx  = &maPrinterData.m_aPrinterGfx;
871 +      maPrinterData.m_pGraphics->maGraphicsData.bPrinter_       = TRUE;
872 +      pRet = maPrinterData.m_pGraphics;
873 +    }
874 +  return pRet;
875 +}
876 +
877 +// -----------------------------------------------------------------------
878 +
879 +void SalInfoPrinter::ReleaseGraphics( SalGraphics* pGraphics )
880 +{
881 +  if( pGraphics == maPrinterData.m_pGraphics )
882 +    {
883 +      delete pGraphics;
884 +      maPrinterData.m_pGraphics = NULL;
885 +    }
886 +}
887 +
888 +// -----------------------------------------------------------------------
889 +
890 +#include <stdio.h>
891 +
892 +BOOL SalInfoPrinter::Setup( SalFrame* pFrame, ImplJobSetup* pJobSetup )
893 +{
894 +  if( ! pFrame || ! pJobSetup )
895 +    return FALSE;
896 +
897 +  OString str = OUStringToOString (maPrinterData.m_aJobData.m_aPrinterName, RTL_TEXTENCODING_UTF8);
898 +  const char *argv[] = { "gnome-cups-manager", "--properties", NULL, NULL };
899 +  argv [2] = str.getStr ();
900 +  BOOL success;
901 +
902 +  if (cups_debug)
903 +    fprintf (stderr, "Setup ... [ properties on '%s' ]\n", str.getStr ());
904 +
905 +  success = g_spawn_async (NULL, (gchar **)argv,
906 +                          NULL, G_SPAWN_SEARCH_PATH,
907 +                          NULL, NULL, NULL, NULL);
908 +
909 +  return success;
910 +}
911 +
912 +// -----------------------------------------------------------------------
913 +
914 +// This function gets the driver data and puts it into pJobSetup
915 +// If pJobSetup->mpDriverData is NOT NULL, then the independend
916 +// data should be merged into the driver data
917 +// If pJobSetup->mpDriverData IS NULL, then the driver defaults
918 +// should be merged into the independent data
919 +BOOL SalInfoPrinter::SetPrinterData( ImplJobSetup* pJobSetup )
920 +{
921 +  if (cups_debug)
922 +    fprintf (stderr, "--- re-fetch data from cupsd ---\n");
923 +  if( pJobSetup->mpDriverData )
924 +    return SetData( ~0, pJobSetup );
925 +
926 +  copyJobDataToJobSetup( pJobSetup, maPrinterData.m_aJobData );
927 +  return TRUE;
928 +}
929 +
930 +// -----------------------------------------------------------------------
931 +
932 +// This function merges the independ driver data
933 +// and sets the new independ data in pJobSetup
934 +// Only the data must be changed, where the bit
935 +// in nGetDataFlags is set
936 +BOOL SalInfoPrinter::SetData(
937 +       ULONG nSetDataFlags,
938 +       ImplJobSetup* pJobSetup )
939 +{
940 +  JobData aData;
941 +  JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
942 +
943 +  if( aData.m_pParser )
944 +    {
945 +      const PPDKey* pKey;
946 +      const PPDValue* pValue;
947 +
948 +      // merge papersize if necessary
949 +      if( nSetDataFlags & SAL_JOBSET_PAPERSIZE )
950 +       {
951 +         int nWidth, nHeight;
952 +         if( pJobSetup->meOrientation == ORIENTATION_PORTRAIT )
953 +            {
954 +             nWidth    = pJobSetup->mnPaperWidth;
955 +             nHeight   = pJobSetup->mnPaperHeight;
956 +            }
957 +         else
958 +            {
959 +             nWidth    = pJobSetup->mnPaperHeight;
960 +             nHeight   = pJobSetup->mnPaperWidth;
961 +            }
962 +         String aPaper;
963 +         if( pJobSetup->mePaperFormat == PAPER_USER )
964 +           aPaper = aData.m_pParser->matchPaper(
965 +                                                TenMuToPt( pJobSetup->mnPaperWidth ),
966 +                                                TenMuToPt( pJobSetup->mnPaperHeight ) );
967 +         else
968 +           aPaper = String( ByteString( aPaperTab[ pJobSetup->mePaperFormat ].name ), RTL_TEXTENCODING_ISO_8859_1 );
969 +         pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "PageSize" ) ) );
970 +         pValue = pKey ? pKey->getValue( aPaper ) : NULL;
971 +         if( ! ( pKey && pValue && aData.m_aContext.setValue( pKey, pValue, false ) == pValue ) )
972 +           return FALSE;
973 +       }
974 +
975 +      // merge paperbin if necessary
976 +      if( nSetDataFlags & SAL_JOBSET_PAPERBIN )
977 +       {
978 +         pKey = aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) );
979 +         if( pKey )
980 +           {
981 +             int nPaperBin = pJobSetup->mnPaperBin;
982 +             if( nPaperBin == 0xffff )
983 +               pValue = pKey->getDefaultValue();
984 +             else
985 +               pValue = pKey->getValue( pJobSetup->mnPaperBin );
986 +
987 +                // may fail due to constraints;
988 +                // real paper bin is copied back to jobsetup in that case
989 +               aData.m_aContext.setValue( pKey, pValue );
990 +           }
991 +         // if printer has no InputSlot key simply ignore this setting
992 +         // (e.g. SGENPRT has no InputSlot)
993 +       }
994 +
995 +      // merge orientation if necessary
996 +      if( nSetDataFlags & SAL_JOBSET_ORIENTATION )
997 +       aData.m_eOrientation = pJobSetup->meOrientation == ORIENTATION_LANDSCAPE ? orientation::Landscape : orientation::Portrait;
998 +
999 +      maPrinterData.m_aJobData = aData;
1000 +      copyJobDataToJobSetup( pJobSetup, aData );
1001 +      return TRUE;
1002 +    }
1003 +
1004 +  return FALSE;
1005 +}
1006 +
1007 +// -----------------------------------------------------------------------
1008 +
1009 +void SalInfoPrinter::GetPageInfo(
1010 +       const ImplJobSetup* pJobSetup,
1011 +       long& rOutWidth, long& rOutHeight,
1012 +       long& rPageOffX, long& rPageOffY,
1013 +       long& rPageWidth, long& rPageHeight )
1014 +{
1015 +  if( ! pJobSetup )
1016 +    return;
1017 +
1018 +  JobData aData;
1019 +  JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
1020 +
1021 +  // get the selected page size
1022 +  if( aData.m_pParser )
1023 +    {
1024 +      String aPaper;
1025 +      int width, height;
1026 +      int left = 0, top = 0, right = 0, bottom = 0;
1027 +      int nDPI = aData.m_aContext.getRenderResolution();
1028 +
1029 +
1030 +      if( aData.m_eOrientation == psp::orientation::Portrait )
1031 +        {
1032 +         aData.m_aContext.getPageSize( aPaper, width, height );
1033 +         aData.m_pParser->getMargins( aPaper, left, right, top, bottom );
1034 +        }
1035 +      else
1036 +        {
1037 +         aData.m_aContext.getPageSize( aPaper, height, width );
1038 +         aData.m_pParser->getMargins( aPaper, bottom, top, left, right );
1039 +        }
1040 +      rPageWidth       = width * nDPI / 72;
1041 +      rPageHeight      = height * nDPI / 72;
1042 +      rPageOffX        = left * nDPI / 72;
1043 +      rPageOffY        = top * nDPI / 72;
1044 +      rOutWidth        = ( width  - left - right ) * nDPI / 72;
1045 +      rOutHeight       = ( height - top  - bottom ) * nDPI / 72;
1046 +
1047 +      if( cups_debug )
1048 +        g_warning ("SalInfoPrinter:: GetPageInfo ... margins: %ld %ld %ld %ld",
1049 +                  rPageOffX, rPageOffY, rPageWidth - rOutWidth, rPageHeight - rOutHeight);
1050 +    }
1051 +}
1052 +
1053 +// -----------------------------------------------------------------------
1054 +
1055 +ULONG SalInfoPrinter::GetPaperBinCount( const ImplJobSetup* pJobSetup )
1056 +{
1057 +  if( ! pJobSetup )
1058 +    return 0;
1059 +
1060 +  JobData aData;
1061 +  JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
1062 +
1063 +  const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ): NULL;
1064 +
1065 +  return pKey ? pKey->countValues() : 0;
1066 +}
1067 +
1068 +// -----------------------------------------------------------------------
1069 +
1070 +String SalInfoPrinter::GetPaperBinName( const ImplJobSetup* pJobSetup, ULONG nPaperBin )
1071 +{
1072 +  JobData aData;
1073 +  JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, aData );
1074 +
1075 +  String aRet;
1076 +  if( aData.m_pParser )
1077 +    {
1078 +      const PPDKey* pKey = aData.m_pParser ? aData.m_pParser->getKey( String( RTL_CONSTASCII_USTRINGPARAM( "InputSlot" ) ) ): NULL;
1079 +      if( nPaperBin == 0xffff || !pKey )
1080 +       aRet = aData.m_pParser->getDefaultInputSlot();
1081 +      else
1082 +       {
1083 +            const PPDValue* pValue = pKey->getValue( nPaperBin );
1084 +            if( pValue )
1085 +                aRet = pValue->m_aOptionTranslation.Len() ? pValue->m_aOptionTranslation : pValue->m_aOption;
1086 +       }
1087 +    }
1088 +
1089 +  return aRet;
1090 +}
1091 +
1092 +// -----------------------------------------------------------------------
1093 +
1094 +ULONG SalInfoPrinter::GetCapabilities( const ImplJobSetup* pJobSetup, USHORT nType )
1095 +{
1096 +  /* FIXME: surely we can do better here */
1097 +  switch( nType )
1098 +    {
1099 +    case PRINTER_CAPABILITIES_SUPPORTDIALOG:
1100 +      return 1;
1101 +    case PRINTER_CAPABILITIES_COPIES:
1102 +      return 0xffff;
1103 +    case PRINTER_CAPABILITIES_COLLATECOPIES:
1104 +      return 0;
1105 +    case PRINTER_CAPABILITIES_SETORIENTATION:
1106 +      return 1;
1107 +    case PRINTER_CAPABILITIES_SETPAPERBIN:
1108 +      return 1;
1109 +    case PRINTER_CAPABILITIES_SETPAPERSIZE:
1110 +      return 1;
1111 +    case PRINTER_CAPABILITIES_SETPAPER:
1112 +      return 0;
1113 +    case PRINTER_CAPABILITIES_FAX:
1114 +      return 0;
1115 +    default: break;
1116 +    };
1117 +  return 0;
1118 +}
1119 +
1120 +// =======================================================================
1121 +
1122 +/*
1123 + *     SalPrinter
1124 + */
1125 +
1126 +SalPrinter::SalPrinter()
1127 +{
1128 +}
1129 +
1130 +// -----------------------------------------------------------------------
1131 +
1132 +SalPrinter::~SalPrinter()
1133 +{
1134 +}
1135 +
1136 +// -----------------------------------------------------------------------
1137 +
1138 +static inline String getTmpName()
1139 +{
1140 +  int fd;
1141 +  String ret;
1142 +  char  *tmp_name;
1143 +
1144 +  tmp_name = g_strdup_printf( "%s/ooo-ps-XXXXXX",
1145 +                             g_get_tmp_dir() );
1146 +
1147 +  if ((fd = g_mkstemp (tmp_name)))
1148 +    close (fd);
1149 +  else
1150 +  {
1151 +    g_warning ("Failed to create tmpfile '%s'", tmp_name);
1152 +    return ret;
1153 +  }
1154 +
1155 +  ret = String( ByteString( tmp_name ), RTL_TEXTENCODING_UTF8 );
1156 +
1157 +  g_free (tmp_name);
1158 +
1159 +  return ret;
1160 +}
1161 +
1162 +BOOL SalPrinter::StartJob(
1163 +       const XubString* pFileName,
1164 +       const XubString& rJobName,
1165 +       const XubString& rAppName,
1166 +       ULONG nCopies, BOOL bCollate,
1167 +       ImplJobSetup* pJobSetup )
1168 +{
1169 +  int nMode = 0;
1170 +  vcl_sal::PrinterUpdate::jobStarted();
1171 +
1172 +  maPrinterData.m_bFax     = false;
1173 +  maPrinterData.m_bPdf      = false;
1174 +  maPrinterData.m_aFileName = pFileName ? *pFileName : String();
1175 +  maPrinterData.m_aJobName  = rJobName;
1176 +  maPrinterData.m_aTmpFile  = String();
1177 +  maPrinterData.m_nCopies   = nCopies;
1178 +
1179 +  JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen,
1180 +                                     maPrinterData.m_aJobData );
1181 +  if( maPrinterData.m_nCopies > 1 )
1182 +    // in case user did not do anything (m_nCopies=1)
1183 +    // take the default from jobsetup
1184 +    maPrinterData.m_aJobData.m_nCopies = maPrinterData.m_nCopies;
1185 +
1186 +  maPrinterData.m_aTmpFile = getTmpName();
1187 +  if (!maPrinterData.m_aTmpFile.Len())
1188 +    return FALSE;
1189 +
1190 +  String printTo;
1191 +  if (maPrinterData.isPrintToFile ())
1192 +    {
1193 +      ::std::hash_map< ::rtl::OUString, ::rtl::OUString, ::rtl::OUStringHash >::const_iterator it;
1194 +      it = pJobSetup->maValueMap.find( ::rtl::OUString::createFromAscii( "Filter#" ) );
1195 +      nMode = S_IRUSR | S_IWUSR;
1196 +      if( it != pJobSetup->maValueMap.end() )
1197 +       {
1198 +         OUString aFilter = it->second;
1199 +         maPrinterData.m_bPdf = !aFilter.compareToAscii( "PDF" );
1200 +       }
1201 +
1202 +      if (maPrinterData.m_bPdf)
1203 +       printTo = maPrinterData.m_aTmpFile;
1204 +      else
1205 +       printTo = maPrinterData.m_aFileName;
1206 +    }
1207 +  else
1208 +    printTo = maPrinterData.m_aTmpFile;
1209 +
1210 +  maPrinterData.m_aPrinterGfx.Init( maPrinterData.m_aJobData );
1211 +
1212 +  // FIXME: race
1213 +  if (PrinterInfoManagerCups::getCups().isBuiltinGeneric() &&
1214 +      !maPrinterData.m_aFileName.Len())
1215 +    {
1216 +#ifdef SAL_PRINTER_ERROR_NO_PRINTER
1217 +      maPrinterData.m_nError = SAL_PRINTER_ERROR_NO_PRINTER; 
1218 +      return FALSE;
1219 +#else
1220 +      g_warning ("Can't print with generic printer");
1221 +#endif
1222 +    }
1223 +
1224 +  return maPrinterData.m_aPrintJob.StartJob
1225 +       ( printTo, nMode, rJobName, rAppName, maPrinterData.m_aJobData,
1226 +         &maPrinterData.m_aPrinterGfx ) ? TRUE : FALSE;
1227 +}
1228 +
1229 +// -----------------------------------------------------------------------
1230 +
1231 +BOOL SalPrinter::EndJob()
1232 +{
1233 +  BOOL bSuccess = maPrinterData.m_aPrintJob.EndJob();
1234 +  BOOL bUnlink = FALSE;
1235 +  OString aTmpName = OUStringToOString
1236 +         ( maPrinterData.m_aTmpFile, RTL_TEXTENCODING_UTF8 );
1237 +
1238 +  if( bSuccess )
1239 +    {
1240 +      if (maPrinterData.isPrintToFile ())
1241 +       {
1242 +         if (maPrinterData.m_bPdf) 
1243 +           {
1244 +             if (cups_debug)
1245 +                g_warning ("Print to PDF...");
1246 +             String aCommandLine = String( RTL_CONSTASCII_USTRINGPARAM(
1247 +               "/usr/bin/gs -q -dNOPAUSE -sDEVICE=pdfwrite -sOutputFile=\"(OUTFILE)\" (INFILE)" ) );
1248 +
1249 +             if (g_getenv ("SAL_PDF_CONVERT_CMD"))
1250 +               aCommandLine.AssignAscii (g_getenv ("SAL_PDF_CONVERT_CMD"));
1251 +
1252 +#define REPLACE(a,b) \
1253 +             while( aCommandLine.SearchAndReplace( String( RTL_CONSTASCII_USTRINGPARAM( a ) ), b ) != STRING_NOTFOUND );
1254 +
1255 +             REPLACE ("(OUTFILE)", maPrinterData.m_aFileName);
1256 +             REPLACE ("(INFILE)",  maPrinterData.m_aTmpFile);
1257 +         
1258 +             OString aSystemCmd = OUStringToOString ( aCommandLine, RTL_TEXTENCODING_UTF8 );
1259 +             gint exit_status = 0;
1260 +             if (!g_spawn_command_line_sync (aSystemCmd.getStr (), NULL, NULL, &exit_status, NULL))
1261 +               bSuccess = FALSE;
1262 +             else
1263 +               bSuccess = !exit_status;
1264 +           }
1265 +         else if (cups_debug)
1266 +            g_warning ("Print to PS file...");
1267 +       }
1268 +      else
1269 +       {
1270 +         OString aJobTitle = OUStringToOString
1271 +           ( maPrinterData.m_aJobName, RTL_TEXTENCODING_UTF8 );
1272 +
1273 +         if (cups_debug)
1274 +           g_warning( "Printing file '%s' name '%s' to '%s'",
1275 +                      (const sal_Char *)aTmpName,
1276 +                      (const sal_Char *)OUStringToOString
1277 +                              ( maPrinterData.m_aJobName, RTL_TEXTENCODING_UTF8 ),
1278 +                      (const sal_Char *)OUStringToOString
1279 +                               ( maPrinterData.m_aJobData.m_aPrinterName, RTL_TEXTENCODING_UTF8 ) );
1280 +         
1281 +         GError *error = NULL;
1282 +         GList  *print_options = NULL;
1283 +         GnomeCupsPrinter *printer;
1284 +
1285 +         printer = PrinterInfoManagerCups::getCups().getGnomePrinter
1286 +               ( maPrinterData.m_aJobData.m_aPrinterName );
1287 +
1288 +#ifdef USE_CUPS_OPTIONS
1289 +         gnome_cups_printer_force_refresh
1290 +               ( printer, GNOME_CUPS_PRINTER_REFRESH_OPTIONS );
1291 +         print_options = gnome_cups_printer_get_options( printer );
1292 +#endif   
1293 +         bSuccess = gnome_cups_printer_print_file
1294 +               ( printer, (const sal_Char *) aTmpName,
1295 +                 (const sal_Char *) aJobTitle, print_options, &error) != 0;
1296 +
1297 +         if (!bSuccess) {
1298 +           if (cups_debug)
1299 +             g_warning ("Error printing '%s' ... (0x%x)",
1300 +                        aTmpName.getStr(), error ? error->code : -1);
1301 +           // We can map the IPP status type in error->code but
1302 +           // since we can only map it to 2 errors, why bother
1303 +           maPrinterData.m_nError = PRINTER_GENERALERROR;
1304 +         }
1305 +
1306 +#ifdef USE_CUPS_OPTIONS
1307 +         gnome_cups_printer_option_list_free( print_options );
1308 +#endif
1309 +
1310 +         gnome_cups_printer_unref( printer );
1311 +       }
1312 +    }
1313 +  else if (cups_debug)
1314 +    g_warning ("Internal printing was not a success");
1315 +
1316 +  if (maPrinterData.m_aTmpFile.Len())
1317 +  {
1318 +    if (cups_debug)
1319 +      g_warning ("Unlinking tmpfile");
1320 +    unlink( (const sal_Char *) aTmpName );
1321 +  }
1322 +
1323 +  vcl_sal::PrinterUpdate::jobEnded();
1324 +
1325 +  if (cups_debug)
1326 +    g_warning ("::EndJob returns %d", bSuccess);
1327 +  return bSuccess;
1328 +}
1329 +
1330 +// -----------------------------------------------------------------------
1331 +
1332 +BOOL SalPrinter::AbortJob()
1333 +{
1334 +    BOOL bAbort = maPrinterData.m_aPrintJob.AbortJob() ? TRUE : FALSE;
1335 +    vcl_sal::PrinterUpdate::jobEnded();
1336 +       return bAbort;
1337 +}
1338 +
1339 +// -----------------------------------------------------------------------
1340 +
1341 +SalGraphics* SalPrinter::StartPage( ImplJobSetup* pJobSetup, BOOL bNewJobData )
1342 +{
1343 +  JobData::constructFromStreamBuffer( pJobSetup->mpDriverData, pJobSetup->mnDriverDataLen, maPrinterData.m_aJobData );
1344 +  maPrinterData.m_pGraphics = new SalGraphics();
1345 +  maPrinterData.m_pGraphics->maGraphicsData.m_pJobData      = &maPrinterData.m_aJobData;
1346 +  maPrinterData.m_pGraphics->maGraphicsData.m_pPrinterGfx   = &maPrinterData.m_aPrinterGfx;
1347 +  maPrinterData.m_pGraphics->maGraphicsData.bPrinter_       = true;
1348 +  maPrinterData.m_pGraphics->maGraphicsData.m_pPhoneNr      = maPrinterData.m_bFax ? &maPrinterData.m_aFaxNr : NULL;
1349 +  maPrinterData.m_pGraphics->maGraphicsData.m_bSwallowFaxNo = maPrinterData.m_bSwallowFaxNo;
1350 +  if( maPrinterData.m_nCopies > 1 )
1351 +    // in case user did not do anything (m_nCopies=1)
1352 +    // take the default from jobsetup
1353 +    maPrinterData.m_aJobData.m_nCopies = maPrinterData.m_nCopies;
1354 +
1355 +  maPrinterData.m_aPrintJob.StartPage( maPrinterData.m_aJobData, bNewJobData ? sal_True : sal_False );
1356 +  maPrinterData.m_aPrinterGfx.Init( maPrinterData.m_aPrintJob );
1357 +
1358 +  return maPrinterData.m_pGraphics;
1359 +}
1360 +
1361 +// -----------------------------------------------------------------------
1362 +
1363 +BOOL SalPrinter::EndPage()
1364 +{
1365 +  sal_Bool bResult = maPrinterData.m_aPrintJob.EndPage();
1366 +  maPrinterData.m_aPrinterGfx.Clear();
1367 +  return bResult ? TRUE : FALSE;
1368 +}
1369 +
1370 +// -----------------------------------------------------------------------
1371 +
1372 +ULONG SalPrinter::GetErrorCode()
1373 +{
1374 +  return maPrinterData.m_nError;
1375 +}
1376 +
1377 +/*
1378 + *  vcl::PrinterUpdate
1379 + */
1380 +
1381 +Timer* vcl_sal::PrinterUpdate::pPrinterUpdateTimer = NULL;
1382 +int vcl_sal::PrinterUpdate::nActiveJobs = 0;
1383 +
1384 +void vcl_sal::PrinterUpdate::doUpdate()
1385 +{
1386 +  ::cups::PrinterInfoManagerCups& rManager( ::cups::PrinterInfoManagerCups::getCups() );
1387 +  if( rManager.checkPrintersChanged() )
1388 +    {
1389 +      SalFrame* pFrame = GetSalData()->pFirstFrame_;
1390 +      while( pFrame )
1391 +        {
1392 +         pFrame->maFrameData.Call( SALEVENT_PRINTERCHANGED, NULL );
1393 +         pFrame = pFrame->maFrameData.GetNextFrame();
1394 +        }
1395 +    }
1396 +}
1397 +
1398 +// -----------------------------------------------------------------------
1399 +
1400 +IMPL_STATIC_LINK( vcl_sal::PrinterUpdate, UpdateTimerHdl, void*, pDummy )
1401 +{
1402 +  if( nActiveJobs < 1 )
1403 +    {
1404 +      doUpdate();
1405 +      delete pPrinterUpdateTimer;
1406 +      pPrinterUpdateTimer = NULL;
1407 +    }
1408 +  else
1409 +    pPrinterUpdateTimer->Start();
1410 +    
1411 +  return 0;
1412 +}
1413 +
1414 +// -----------------------------------------------------------------------
1415 +
1416 +void vcl_sal::PrinterUpdate::update()
1417 +{
1418 +  if( nActiveJobs < 1 )
1419 +    doUpdate();
1420 +  else if( ! pPrinterUpdateTimer )
1421 +    {
1422 +      pPrinterUpdateTimer = new Timer();
1423 +      pPrinterUpdateTimer->SetTimeout( 500 );
1424 +      pPrinterUpdateTimer->SetTimeoutHdl( STATIC_LINK( NULL, vcl_sal::PrinterUpdate, UpdateTimerHdl ) );
1425 +      pPrinterUpdateTimer->Start();
1426 +    }
1427 +}
1428 +
1429 +// -----------------------------------------------------------------------
1430 +
1431 +void vcl_sal::PrinterUpdate::jobEnded()
1432 +{
1433 +  nActiveJobs--;
1434 +  if( nActiveJobs < 1 )
1435 +    {
1436 +      if( pPrinterUpdateTimer )
1437 +        {
1438 +         pPrinterUpdateTimer->Stop();
1439 +         delete pPrinterUpdateTimer;
1440 +         pPrinterUpdateTimer = NULL;
1441 +         doUpdate();
1442 +        }
1443 +    }
1444 +}
1445 Index: vcl/util/makefile.mk
1446 ===================================================================
1447 RCS file: /cvs/gsl/vcl/util/makefile.mk,v
1448 retrieving revision 1.46.2.3
1449 diff -u -p -u -r1.46.2.3 makefile.mk
1450 --- vcl/util/makefile.mk        31 Jul 2003 15:28:43 -0000      1.46.2.3
1451 +++ vcl/util/makefile.mk        29 Aug 2003 14:34:04 -0000
1452 @@ -275,6 +275,8 @@ SHL1STDLIBS += -framework Cocoa
1453  
1454  .IF "$(GUIBASE)"=="unx"
1455  
1456 +SHL1STDLIBS += `pkg-config --libs libgnomecups-1.0`
1457 +
1458  .IF "$(WITH_LIBSN)"=="YES"
1459  SHL1STDLIBS+=$(LIBSN_LIBS)
1460  .ENDIF
This page took 0.173322 seconds and 3 git commands to generate.