]>
Commit | Line | Data |
---|---|---|
06d21470 | 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 |