]> Pileus Git - ~andy/gtk/blob - modules/printbackends/papi/gtkprintbackendpapi.c
6a40f56e362fa92d8c3a26753868fc5c9d898c30
[~andy/gtk] / modules / printbackends / papi / gtkprintbackendpapi.c
1 /* GTK - The GIMP Toolkit
2  * gtkprintbackendpapi.c: Default implementation of GtkPrintBackend 
3  * for printing to papi 
4  * Copyright (C) 2003, Red Hat, Inc.
5  * Copyright (C) 2009, Sun Microsystems, Inc.
6  *
7  * This library is free software; you can redistribute it and/or
8  * modify it under the terms of the GNU Lesser General Public
9  * License as published by the Free Software Foundation; either
10  * version 2 of the License, or (at your option) any later version.
11  *
12  * This library is distributed in the hope that it will be useful,
13  * but WITHOUT ANY WARRANTY; without even the implied warranty of
14  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
15  * Lesser General Public License for more details.
16  *
17  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library. If not, see <http://www.gnu.org/licenses/>.
19  */
20
21 #include <unistd.h>
22 #include <sys/types.h>
23 #include <sys/stat.h>
24 #include <fcntl.h>
25 #include <stdlib.h>
26 #include <string.h>
27 #include <papi.h>
28
29 #include <config.h>
30 #include <errno.h>
31 #include <cairo.h>
32 #include <cairo-ps.h>
33
34 #include <glib/gi18n-lib.h>
35
36 #include "gtk.h"
37 #include "gtkprintbackendpapi.h"
38 #include "gtkprinterpapi.h"
39 #include "gtkprinter-private.h"
40
41 typedef struct _GtkPrintBackendPapiClass GtkPrintBackendPapiClass;
42
43 #define GTK_PRINT_BACKEND_PAPI_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), GTK_TYPE_PRINT_BACKEND_PAPI, GtkPrintBackendPapiClass))
44 #define GTK_IS_PRINT_BACKEND_PAPI_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), GTK_TYPE_PRINT_BACKEND_PAPI))
45 #define GTK_PRINT_BACKEND_PAPI_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), GTK_TYPE_PRINT_BACKEND_PAPI, GtkPrintBackendPapiClass))
46
47 #define _PAPI_MAX_CHUNK_SIZE 8192
48
49 static GType print_backend_papi_type = 0;
50
51 struct _GtkPrintBackendPapiClass
52 {
53   GtkPrintBackendClass parent_class;
54 };
55
56 struct _GtkPrintBackendPapi
57 {
58   GtkPrintBackend parent_instance;
59
60   char *default_printer;  
61 };
62
63 typedef struct {
64   GtkPrinter *printer;
65 } _PrinterStatus;
66
67 static GObjectClass *backend_parent_class;
68
69 static void                 gtk_print_backend_papi_class_init      (GtkPrintBackendPapiClass *class);
70 static void                 gtk_print_backend_papi_init            (GtkPrintBackendPapi      *impl);
71 static void                 gtk_print_backend_papi_finalize        (GObject                  *object);
72 static void                 gtk_print_backend_papi_dispose         (GObject                  *object);
73 static void                 papi_request_printer_list              (GtkPrintBackend          *print_backend);
74 static gboolean             papi_get_printer_list                  (GtkPrintBackendPapi      *papi_backend);
75 static void                 papi_printer_request_details           (GtkPrinter               *printer);
76 static GtkPrintCapabilities papi_printer_get_capabilities          (GtkPrinter               *printer);
77 static void                 papi_printer_get_settings_from_options (GtkPrinter               *printer,
78                                                                    GtkPrinterOptionSet       *options,
79                                                                    GtkPrintSettings          *settings);
80 static GtkPrinterOptionSet *papi_printer_get_options               (GtkPrinter               *printer,
81                                                                    GtkPrintSettings          *settings,
82                                                                    GtkPageSetup              *page_setup,
83                                                                    GtkPrintCapabilities       capabilities);
84 static void                 papi_printer_prepare_for_print         (GtkPrinter               *printer,
85                                                                    GtkPrintJob               *print_job,
86                                                                    GtkPrintSettings          *settings,
87                                                                    GtkPageSetup              *page_setup);
88 static cairo_surface_t *    papi_printer_create_cairo_surface      (GtkPrinter               *printer,
89                                                                    GtkPrintSettings          *settings,
90                                                                    gdouble                   width,
91                                                                    gdouble                   height,
92                                                                    GIOChannel                *cache_io);
93 static void                 gtk_print_backend_papi_print_stream    (GtkPrintBackend          *print_backend,
94                                                                    GtkPrintJob               *job,
95                                                                    GIOChannel                *data_io,
96                                                                    GtkPrintJobCompleteFunc   callback,
97                                                                    gpointer                  user_data,
98                                                                    GDestroyNotify            dnotify);
99
100 static gboolean             papi_display_printer_status            (gpointer user_data);
101 static void                 papi_display_printer_status_done       (gpointer user_data);
102
103 static void
104 gtk_print_backend_papi_register_type (GTypeModule *module)
105 {
106   const GTypeInfo print_backend_papi_info =
107   {
108     sizeof (GtkPrintBackendPapiClass),
109     NULL,               /* base_init */
110     NULL,               /* base_finalize */
111     (GClassInitFunc) gtk_print_backend_papi_class_init,
112     NULL,               /* class_finalize */
113     NULL,               /* class_data */
114     sizeof (GtkPrintBackendPapi),
115     0,          /* n_preallocs */
116     (GInstanceInitFunc) gtk_print_backend_papi_init,
117   };
118
119   print_backend_papi_type = g_type_module_register_type (module,
120                                                         GTK_TYPE_PRINT_BACKEND,
121                                                         "GtkPrintBackendPapi",
122                                                         &print_backend_papi_info, 0);
123 }
124
125 G_MODULE_EXPORT void 
126 pb_module_init (GTypeModule *module)
127 {
128   gtk_print_backend_papi_register_type (module);
129   gtk_printer_papi_register_type (module);
130 }
131
132 G_MODULE_EXPORT void 
133 pb_module_exit (void)
134 {
135
136 }
137   
138 G_MODULE_EXPORT GtkPrintBackend * 
139 pb_module_create (void)
140 {
141   return gtk_print_backend_papi_new ();
142 }
143
144 /*
145  * GtkPrintBackendPapi
146  */
147 GType
148 gtk_print_backend_papi_get_type (void)
149 {
150   return print_backend_papi_type;
151 }
152
153 /**
154  * gtk_print_backend_papi_new:
155  *
156  * Creates a new #GtkPrintBackendPapi object. #GtkPrintBackendPapi
157  * implements the #GtkPrintBackend interface with direct access to
158  * the filesystem using Unix/Linux API calls
159  *
160  * Return value: the new #GtkPrintBackendPapi object
161  **/
162 GtkPrintBackend *
163 gtk_print_backend_papi_new (void)
164 {
165   return g_object_new (GTK_TYPE_PRINT_BACKEND_PAPI, NULL);
166 }
167
168 static void
169 gtk_print_backend_papi_class_init (GtkPrintBackendPapiClass *class)
170 {
171   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
172   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);
173   
174   backend_parent_class = g_type_class_peek_parent (class);
175
176   gobject_class->finalize = gtk_print_backend_papi_finalize;
177   gobject_class->dispose = gtk_print_backend_papi_dispose;
178
179   backend_class->request_printer_list = papi_request_printer_list;
180   backend_class->printer_request_details = papi_printer_request_details;
181   backend_class->printer_get_capabilities = papi_printer_get_capabilities;
182   backend_class->printer_get_options = papi_printer_get_options;
183   backend_class->printer_get_settings_from_options = papi_printer_get_settings_from_options;
184   backend_class->printer_prepare_for_print = papi_printer_prepare_for_print;
185   backend_class->printer_create_cairo_surface = papi_printer_create_cairo_surface;
186   backend_class->print_stream = gtk_print_backend_papi_print_stream;
187 }
188
189 static cairo_status_t
190 _cairo_write (void                *closure,
191               const unsigned char *data,
192               unsigned int         length)
193 {
194   GIOChannel *io = (GIOChannel *)closure;
195   gsize written;
196   GError *error = NULL;
197
198   GTK_NOTE (PRINTING,
199             g_print ("PAPI Backend: Writting %i byte chunk to temp file\n", length));
200
201   while (length > 0) 
202     {
203       g_io_channel_write_chars (io, (char *)data, length, &written, &error);
204
205       if (error != NULL)
206         {
207           GTK_NOTE (PRINTING,
208                      g_print ("PAPI Backend: Error writting to temp file, %s\n", error->message));
209
210           g_error_free (error);
211           return CAIRO_STATUS_WRITE_ERROR;
212         }    
213
214       GTK_NOTE (PRINTING,
215                 g_print ("PAPI Backend: Wrote %i bytes to temp file\n", written));
216
217       data += written;
218       length -= written;
219     }
220
221   return CAIRO_STATUS_SUCCESS;
222 }
223
224 static cairo_surface_t *
225 papi_printer_create_cairo_surface (GtkPrinter       *printer,
226                                   GtkPrintSettings *settings,
227                                   gdouble           width, 
228                                   gdouble           height,
229                                   GIOChannel       *cache_io)
230 {
231   cairo_surface_t *surface;
232   
233   surface = cairo_ps_surface_create_for_stream (_cairo_write, cache_io, width, height);
234
235   cairo_surface_set_fallback_resolution (surface,
236                                          2.0 * gtk_print_settings_get_printer_lpi (settings),
237                                          2.0 * gtk_print_settings_get_printer_lpi (settings));
238
239   return surface;
240 }
241
242 typedef struct {
243   GtkPrintBackend *backend;
244   GtkPrintJobCompleteFunc callback;
245   GtkPrintJob *job;
246   gpointer user_data;
247   GDestroyNotify dnotify;
248
249   papi_service_t service;
250   papi_stream_t stream;
251 } _PrintStreamData;
252
253 static void
254 papi_print_cb (GtkPrintBackendPapi *print_backend,
255               GError             *error,
256               gpointer            user_data)
257 {
258   _PrintStreamData *ps = (_PrintStreamData *) user_data;
259
260   if (ps->callback)
261     ps->callback (ps->job, ps->user_data, error);
262
263   if (ps->dnotify)
264     ps->dnotify (ps->user_data);
265
266   gtk_print_job_set_status (ps->job, 
267                             error ? GTK_PRINT_STATUS_FINISHED_ABORTED 
268                                   : GTK_PRINT_STATUS_FINISHED);
269
270   if (ps->job)
271     g_object_unref (ps->job);
272   
273   g_free (ps);
274 }
275
276 static gboolean
277 papi_write (GIOChannel   *source,
278            GIOCondition  con,
279            gpointer      user_data)
280 {
281   gchar buf[_PAPI_MAX_CHUNK_SIZE];
282   gsize bytes_read;
283   GError *error;
284   GIOStatus status;
285   _PrintStreamData *ps = (_PrintStreamData *) user_data;
286   papi_job_t job = NULL;
287
288   error = NULL;
289   status = g_io_channel_read_chars (source,
290                                     buf,
291                                     _PAPI_MAX_CHUNK_SIZE,
292                                     &bytes_read,
293                                     &error);
294
295   /* Keep writing to PAPI input stream while there are data */
296   if (status != G_IO_STATUS_ERROR)
297   {
298      papiJobStreamWrite (ps->service, ps->stream, buf, bytes_read);
299   }
300   
301   /* Finish reading input stream data. Closing the stream and handle to service */
302   if (bytes_read == 0) {
303      papiJobStreamClose (ps->service, ps->stream, &job);
304      ps->stream = NULL;
305      papiJobFree (job);
306      papiServiceDestroy (ps->service);
307      ps->service = NULL;
308   }
309
310   if (error != NULL || status == G_IO_STATUS_EOF)
311     {
312       papi_print_cb (GTK_PRINT_BACKEND_PAPI (ps->backend), 
313                     error, user_data);
314
315       if (error)
316         g_error_free (error);
317
318       if (error != NULL)
319         {
320           GTK_NOTE (PRINTING,
321                     g_print ("PAPI Backend: %s\n", error->message));
322
323           g_error_free (error);
324         } 
325
326       return FALSE;
327     }
328
329   GTK_NOTE (PRINTING,
330             g_print ("PAPI Backend: Writting %i byte chunk to papi pipe\n", bytes_read));
331
332   return TRUE;
333 }
334
335 static void
336 gtk_print_backend_papi_print_stream (GtkPrintBackend        *print_backend,
337                                     GtkPrintJob            *job,
338                                     GIOChannel             *data_io,
339                                     GtkPrintJobCompleteFunc callback,
340                                     gpointer                user_data,
341                                     GDestroyNotify          dnotify)
342 {
343   GError *print_error = NULL;
344   GtkPrinterPapi *printer;
345   _PrintStreamData *ps;
346   GtkPrintSettings *settings;
347   gint argc;  
348   gint in_fd;
349   gchar **argv = NULL; 
350   const gchar *title;
351   char *prtnm = NULL;
352   GtkPrintDuplex val;
353   papi_status_t pstatus = NULL;
354   papi_attribute_t **attrs = NULL;
355   papi_job_ticket_t *ticket = NULL;
356   
357   printer = GTK_PRINTER_PAPI (gtk_print_job_get_printer (job));
358   settings = gtk_print_job_get_settings (job);
359
360   /* FIXME - the title should be set as the job-name */
361   title = gtk_print_job_get_title (job);
362
363   ps = g_new0 (_PrintStreamData, 1);
364   ps->callback = callback;
365   ps->user_data = user_data;
366   ps->dnotify = dnotify;
367   ps->job = g_object_ref (job);
368   ps->service = NULL;
369   ps->stream = NULL;
370
371    /* This cannot be queried yet with the current API */
372   papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "document-format", "application/postscript");
373   val =  gtk_print_settings_get_duplex (settings) ;
374   if (val == GTK_PRINT_DUPLEX_HORIZONTAL)
375     papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "Duplex", "DuplexNoTumble");
376   else if (val == GTK_PRINT_DUPLEX_VERTICAL)
377     papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "Duplex", "DuplexTumble");
378
379   if (job->num_copies > 1) 
380     {
381       papiAttributeListAddInteger (&attrs, PAPI_ATTR_EXCL, "copies", job->num_copies); 
382     }
383
384   prtnm = strdup (gtk_printer_get_name (GTK_PRINTER(printer)));
385
386   if (papiServiceCreate (&(ps->service), prtnm, NULL, NULL, NULL,
387                          PAPI_ENCRYPT_NEVER, NULL) != PAPI_OK)
388     return;
389
390   pstatus = papiJobStreamOpen (ps->service, prtnm, attrs, ticket, &(ps->stream));
391   if (pstatus != PAPI_OK)
392     {
393       papiServiceDestroy (ps->service);
394       ps->service = NULL;
395       return;
396     }
397
398   /* Everything set up fine, so get ready to wait for input data stream */
399   g_io_add_watch (data_io,
400                   G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
401                   (GIOFunc) papi_write,
402                   ps);
403 }
404
405
406 static void
407 _papi_set_default_printer (GtkPrintBackendPapi *backend)
408 {
409   char *def_printer = NULL;
410   char *_default_attr[] = { "printer-name", NULL };
411   papi_service_t service = NULL;
412   papi_printer_t default_printer = NULL;
413   papi_attribute_t **attrs = NULL;
414
415   if (papiServiceCreate (&service, NULL, NULL, NULL, NULL, PAPI_ENCRYPT_NEVER,
416                           NULL) != PAPI_OK)
417     return;
418
419   if (papiPrinterQuery (service, "_default", _default_attr, NULL, 
420                         &default_printer) == PAPI_OK)  
421     {
422       if (default_printer != NULL)  
423         {
424           attrs = papiPrinterGetAttributeList (default_printer);
425
426           if (attrs != NULL)
427             if (papiAttributeListGetString (attrs, NULL, "printer-name", 
428                                             &def_printer) == PAPI_OK) 
429               {
430                 backend->default_printer = strdup (def_printer);
431               }
432         }
433     }
434
435   papiPrinterFree (default_printer);
436   papiServiceDestroy (service);
437 }
438
439 static void
440 gtk_print_backend_papi_init (GtkPrintBackendPapi *backend)
441 {
442   _papi_set_default_printer (backend);
443 }
444
445 static void
446 gtk_print_backend_papi_finalize (GObject *object)
447 {
448   GtkPrintBackendPapi *backend_papi;
449
450   GTK_NOTE (PRINTING,
451             g_print ("PAPI Backend: finalizing PAPI backend module\n"));
452
453   backend_papi = GTK_PRINT_BACKEND_PAPI (object);
454
455   g_free (backend_papi->default_printer);
456   backend_papi->default_printer = NULL;
457
458   backend_parent_class->finalize (object);
459 }
460
461
462 static void
463 gtk_print_backend_papi_dispose (GObject *object)
464 {
465   GtkPrintBackendPapi *backend_papi;
466
467   GTK_NOTE (PRINTING,
468             g_print ("PAPI Backend: %s\n", G_STRFUNC));
469
470   backend_papi = GTK_PRINT_BACKEND_PAPI (object);
471
472   backend_parent_class->dispose (object);
473 }
474
475 char **
476 get_all_list(papi_service_t svc)
477 {
478         papi_status_t status;
479         papi_printer_t printer = NULL;
480         char *attr[] = { "member-names", NULL };
481         char **names = NULL;
482
483         status = papiPrinterQuery(svc, "_all", attr, NULL, &printer);
484         if ((status == PAPI_OK) && (printer != NULL)) {
485                 papi_attribute_t **attributes =
486                                         papiPrinterGetAttributeList(printer);
487                 if (attributes != NULL) {
488                         void *iter = NULL;
489                         char *member = NULL;
490
491                         for (status = papiAttributeListGetString(attributes,
492                                                 &iter, "member-names", &member);
493                                 status == PAPI_OK;
494                                 status = papiAttributeListGetString(attributes,
495                                                 &iter, NULL, &member))
496                                         list_append(&names, strdup(member));
497                 }
498                 papiPrinterFree(printer);
499         }
500
501         return (names);
502 }
503
504 static char **
505 get_printers_list(papi_service_t svc)
506 {
507         papi_status_t status;
508         papi_printer_t *printers = NULL;
509         char *keys[] = { "printer-name", "printer-uri-supported", NULL };
510         char **names = NULL;
511
512         status = papiPrintersList(svc, keys, NULL, &printers);
513         if ((status == PAPI_OK) && (printers != NULL)) {
514                 int i;
515
516                 for (i = 0; printers[i] != NULL; i++) {
517                         papi_attribute_t **attributes =
518                                 papiPrinterGetAttributeList(printers[i]);
519                         char *name = NULL;
520                         
521                         (void) papiAttributeListGetString(attributes, NULL,
522                                                         "printer-name", &name);
523                         if ((name != NULL) && (strcmp(name, "_default") != 0))
524                                 list_append(&names, strdup(name));
525                 }
526                 papiPrinterListFree(printers);
527         }
528     
529         return (names);
530 }
531
532 static void
533 papi_request_printer_list (GtkPrintBackend *backend)
534 {
535   GtkPrintBackendPapi *papi_backend;
536
537   papi_backend = GTK_PRINT_BACKEND_PAPI (backend);
538
539   /* Get the list of printers using papi API */
540   papi_get_printer_list (papi_backend); 
541 }
542
543 static gboolean
544 papi_get_printer_list (GtkPrintBackendPapi *papi_backend)
545 {
546   int i;
547   const char *attributes[] =  /* Attributes we're interested in */
548     {
549       "printer-name",
550       "printer-uri-supported",
551       NULL
552     };
553   papi_status_t status, status2;
554   papi_service_t service = NULL;
555   char **printers = NULL;
556   GtkPrinter *printer;
557   GtkPrinterPapi *papi_printer;
558   GList *current_printer_list;
559   GtkPrintBackend *backend = GTK_PRINT_BACKEND (papi_backend);
560   
561   if ((status = papiServiceCreate (&service, NULL, NULL, NULL, NULL,
562                 PAPI_ENCRYPT_NEVER, NULL)) != PAPI_OK)
563     return FALSE; 
564
565   if ((printers = get_all_list (service)) == NULL) 
566     {
567       printers = get_printers_list (service);
568     }
569
570   if (printers == NULL) 
571     {
572       papiServiceDestroy (service);
573       return FALSE;
574     }
575
576   for (i = 0; printers[i] != NULL; i++) 
577     {
578       GtkPrinter *printer;
579       char *name = NULL, *url = NULL;
580       papi_attribute_t **attrs = NULL;
581
582           printer = gtk_print_backend_find_printer (backend, printers[i]);
583
584           if (!printer) 
585             {
586               /* skip null printer name just in case */
587               if (printers[i] == NULL)
588                 continue;
589
590               /* skip the alias _default and _all printers */
591               if (strcmp(printers[i], "_default")==0 || strcmp(printers[i], "_all")==0)
592                 continue;       
593
594               papi_printer = gtk_printer_papi_new (printers[i], backend);
595               printer = GTK_PRINTER (papi_printer);
596
597               /* Only marked default printer to not have details so that
598                  the request_details method will be called  at start up
599                */
600
601               if (papi_backend->default_printer != NULL)
602                 if (strcmp (printers[i], papi_backend->default_printer)==0)
603                   {
604                     gtk_printer_set_is_default (printer, TRUE);
605                   }     
606
607               gtk_printer_set_icon_name (printer, "printer");
608               gtk_print_backend_add_printer (backend, printer);
609               gtk_printer_set_is_active (printer, TRUE);
610
611               /* gtk_printer_set_has_details (printer, TRUE); */
612             }
613           else 
614             g_object_ref (printer);
615
616       if (!gtk_printer_is_active (printer))
617         {
618           gtk_printer_set_is_active (printer, TRUE);
619           gtk_printer_set_is_new (printer, TRUE);
620         }
621
622       if (gtk_printer_is_new (printer))
623         {
624           g_signal_emit_by_name (backend, "printer-added", printer);
625           gtk_printer_set_is_new (printer, FALSE);
626         }
627
628       g_object_unref (printer);
629     }
630
631   free (printers);
632   papiServiceDestroy (service);
633
634   /* To set that the list of printers added is complete */
635   gtk_print_backend_set_list_done (backend); 
636
637   return TRUE;
638 }
639
640 static void
641 update_printer_status (GtkPrinter *printer)
642 {
643   GtkPrintBackend *backend;
644   GtkPrinterPapi *papi_printer;
645   gboolean status_changed = FALSE;
646
647   backend = gtk_printer_get_backend (printer);
648   papi_printer = GTK_PRINTER_PAPI (printer);
649
650   /* if (status_changed) */
651     g_signal_emit_by_name (GTK_PRINT_BACKEND (backend),
652                            "printer-status-changed", printer);
653
654 }
655
656
657 static GtkPrinterOptionSet *
658 papi_printer_get_options (GtkPrinter           *printer,
659                           GtkPrintSettings     *settings,
660                           GtkPageSetup         *page_setup,
661                           GtkPrintCapabilities  capabilities)
662 {
663   GtkPrinterOptionSet *set;
664   GtkPrinterOption *option;
665   int i;
666   char *print_at[] = { "now", "on-hold" };
667   char *n_up[] = {"1"};
668
669   /* Update the printer status before the printer options are displayed */
670   update_printer_status (printer); 
671
672   set = gtk_printer_option_set_new ();
673
674   /* non-ppd related settings */
675
676   /* This maps to number-up-supported in PAPI. FIXME 
677    * number-up-default is the default value. 
678    * number-up-supported is the list of number of able to print per page 
679    */
680   option = gtk_printer_option_new ("gtk-n-up", "Pages Per Sheet", GTK_PRINTER_OPTION_TYPE_PICKONE);
681   gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up),
682                                          n_up, n_up);
683   gtk_printer_option_set (option, "1");
684   gtk_printer_option_set_add (set, option);
685   g_object_unref (option);
686
687   /* This maps to job-priority-supported and job-priority-default in PAPI - FIXME*/
688   
689   /* This relates to job-sheets-supported in PAPI  FIXME*/
690   
691   /* This relates to job-hold-until-supported in PAPI */
692   option = gtk_printer_option_new ("gtk-print-time", "Print at", GTK_PRINTER_OPTION_TYPE_PICKONE);
693   gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (print_at),
694                                          print_at, print_at);
695   gtk_printer_option_set (option, "now");
696   gtk_printer_option_set_add (set, option);
697   g_object_unref (option);
698   
699   return set;
700 }
701
702 static void
703 papi_printer_get_settings_from_options (GtkPrinter          *printer,
704                                        GtkPrinterOptionSet *options,
705                                        GtkPrintSettings    *settings)
706 {
707   GtkPrinterOption *option;
708
709   option = gtk_printer_option_set_lookup (options, "gtk-n-up");
710   if (option)
711      gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_NUMBER_UP, option->value);
712
713 }
714
715 static void
716 papi_printer_prepare_for_print (GtkPrinter       *printer,
717                                GtkPrintJob      *print_job,
718                                GtkPrintSettings *settings,
719                                GtkPageSetup     *page_setup)
720 {
721   GtkPageSet page_set;
722   double scale;
723   GtkPaperSize *papersize = NULL;
724   char *ppd_paper_name;
725
726   print_job->print_pages = gtk_print_settings_get_print_pages (settings);
727   print_job->page_ranges = NULL;
728   print_job->num_page_ranges = 0;
729   
730   if (print_job->print_pages == GTK_PRINT_PAGES_RANGES)
731     print_job->page_ranges =
732       gtk_print_settings_get_page_ranges (settings,
733                                           &print_job->num_page_ranges);
734   
735   print_job->collate = gtk_print_settings_get_collate (settings);
736   print_job->reverse = gtk_print_settings_get_reverse (settings);
737   print_job->num_copies = gtk_print_settings_get_n_copies (settings);
738  
739   scale = gtk_print_settings_get_scale (settings);
740   if (scale != 100.0)
741     print_job->scale = scale/100.0;
742
743   papersize = gtk_page_setup_get_paper_size (page_setup);
744   ppd_paper_name = gtk_paper_size_get_ppd_name (papersize);
745
746   page_set = gtk_print_settings_get_page_set (settings);
747   if (page_set == GTK_PAGE_SET_EVEN)
748     print_job->page_set = GTK_PAGE_SET_EVEN;
749   else if (page_set == GTK_PAGE_SET_ODD)
750     print_job->page_set = GTK_PAGE_SET_ODD;
751   else
752     print_job->page_set = GTK_PAGE_SET_ALL;
753
754   print_job->rotate_to_orientation = TRUE;
755
756 }
757
758 gboolean
759 is_local_printer (gchar *printer_uri)
760 {
761   if (strncmp (printer_uri, "lpsched:", 8) == 0)
762     return TRUE;
763   else
764     return FALSE;
765 }
766
767 void
768 merge_ppd_data (papi_attribute_t ***attributes, gchar *ppdfile)
769 {
770   get_ppd_attrs (attributes, ppdfile);
771 }
772
773
774 static void
775 papi_display_printer_status_done (gpointer user_data)
776 {
777   GtkPrinter *printer = (GtkPrinter *) user_data;
778   GtkPrinterPapi *papi_printer;
779
780   g_signal_emit_by_name (printer, "details-acquired", TRUE); 
781   papi_printer = GTK_PRINTER_PAPI (printer);
782   return;
783 }
784
785 #define IDLE 3
786 #define PROCESSING 4
787 #define STOPPED 5
788 static gboolean
789 papi_display_printer_status (gpointer user_data)
790 {
791   GtkPrinter *printer = (GtkPrinter *) user_data;
792   GtkPrinterPapi *papi_printer;
793   gchar *loc, *printer_uri, *ppdfile;
794   int state;
795   papi_service_t service;
796   papi_attribute_t **attrs = NULL;
797   papi_printer_t current_printer = NULL;
798   static int count = 0;
799
800   papi_printer = GTK_PRINTER_PAPI (printer);
801   if (papiServiceCreate (&service, NULL, NULL, NULL, NULL, PAPI_ENCRYPT_NEVER,
802                           NULL) != PAPI_OK)
803     return G_SOURCE_REMOVE;
804
805   if (papiPrinterQuery (service, papi_printer->printer_name, NULL, NULL,
806                         &current_printer) != PAPI_OK) 
807     {
808        /* SUN_BRANDING */
809        gtk_printer_set_state_message (printer, _("printer offline"));
810     }
811
812   if (current_printer != NULL)
813     {
814         attrs = papiPrinterGetAttributeList (current_printer);
815     }
816
817   if (papiAttributeListGetString (attrs, NULL, "printer-info", &loc) == PAPI_OK)
818     {
819         gtk_printer_set_location (printer, loc);
820     }
821
822   if (papiAttributeListGetInteger (attrs, NULL, "printer-state", &state) == PAPI_OK)
823     {
824       switch (state) 
825         {
826           /* SUN_BRANDING */
827           case IDLE: gtk_printer_set_state_message (printer, _("ready to print"));
828                      break;
829           /* SUN_BRANDING */
830           case PROCESSING: gtk_printer_set_state_message (printer, _("processing job"));
831                            break;
832
833           /* SUN_BRANDING */
834           case STOPPED: gtk_printer_set_state_message (printer, _("paused"));
835                         break;
836           /* SUN_BRANDING */
837           default: gtk_printer_set_state_message (printer, _("unknown"));
838                    break;
839         }
840     }
841
842   papiPrinterFree (current_printer);
843   papiServiceDestroy (service);
844   gtk_printer_set_has_details (printer, TRUE);
845
846   return G_SOURCE_REMOVE;
847 }
848
849 static void  
850 papi_printer_request_details (GtkPrinter *printer)
851 {
852   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, papi_display_printer_status, printer, papi_display_printer_status_done); 
853 }
854
855
856 static GtkPrintCapabilities
857 papi_printer_get_capabilities (GtkPrinter *printer)
858 {
859   return GTK_PRINT_CAPABILITY_COPIES | GTK_PRINT_CAPABILITY_PAGE_SET ; 
860 }
861