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