]> git.pld-linux.org Git - packages/libreoffice.git/blame - openoffice-print-cups.patch
- up
[packages/libreoffice.git] / openoffice-print-cups.patch
CommitLineData
06d21470 1Index: vcl/unx/source/gdi/makefile.mk
2===================================================================
3RCS file: /cvs/gsl/vcl/unx/source/gdi/makefile.mk,v
4retrieving revision 1.9
5diff -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"
18Index: vcl/unx/inc/salprn.h
19===================================================================
20RCS file: /cvs/gsl/vcl/unx/inc/salprn.h,v
21retrieving revision 1.9
22diff -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+}
1445Index: vcl/util/makefile.mk
1446===================================================================
1447RCS file: /cvs/gsl/vcl/util/makefile.mk,v
1448retrieving revision 1.46.2.3
1449diff -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.286578 seconds and 4 git commands to generate.