]> Pileus Git - ~andy/gtk/blob - modules/printbackends/papi/gtkprintbackendpapi.c
Merge branch 'master' into client-side-windows
[~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   static 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   /* TODO: DPI from settings object? */
238   cairo_surface_set_fallback_resolution (surface, 300, 300);
239
240   return surface;
241 }
242
243 typedef struct {
244   GtkPrintBackend *backend;
245   GtkPrintJobCompleteFunc callback;
246   GtkPrintJob *job;
247   gpointer user_data;
248   GDestroyNotify dnotify;
249
250   papi_service_t service;
251   papi_stream_t stream;
252 } _PrintStreamData;
253
254 static void
255 papi_print_cb (GtkPrintBackendPapi *print_backend,
256               GError             *error,
257               gpointer            user_data)
258 {
259   _PrintStreamData *ps = (_PrintStreamData *) user_data;
260
261   if (ps->callback)
262     ps->callback (ps->job, ps->user_data, error);
263
264   if (ps->dnotify)
265     ps->dnotify (ps->user_data);
266
267   gtk_print_job_set_status (ps->job, 
268                             error ? GTK_PRINT_STATUS_FINISHED_ABORTED 
269                                   : GTK_PRINT_STATUS_FINISHED);
270
271   if (ps->job)
272     g_object_unref (ps->job);
273   
274   g_free (ps);
275 }
276
277 static gboolean
278 papi_write (GIOChannel   *source,
279            GIOCondition  con,
280            gpointer      user_data)
281 {
282   gchar buf[_PAPI_MAX_CHUNK_SIZE];
283   gsize bytes_read;
284   GError *error;
285   GIOStatus status;
286   _PrintStreamData *ps = (_PrintStreamData *) user_data;
287   papi_job_t job = NULL;
288
289   error = NULL;
290   status = g_io_channel_read_chars (source,
291                                     buf,
292                                     _PAPI_MAX_CHUNK_SIZE,
293                                     &bytes_read,
294                                     &error);
295
296   /* Keep writing to PAPI input stream while there are data */
297   if (status != G_IO_STATUS_ERROR)
298   {
299      papiJobStreamWrite (ps->service, ps->stream, buf, bytes_read);
300   }
301   
302   /* Finish reading input stream data. Closing the stream and handle to service */
303   if (bytes_read == 0) {
304      papiJobStreamClose (ps->service, ps->stream, &job);
305      ps->stream = NULL;
306      papiJobFree (job);
307      papiServiceDestroy (ps->service);
308      ps->service = NULL;
309   }
310
311   if (error != NULL || status == G_IO_STATUS_EOF)
312     {
313       papi_print_cb (GTK_PRINT_BACKEND_PAPI (ps->backend), 
314                     error, user_data);
315
316       if (error)
317         g_error_free (error);
318
319       if (error != NULL)
320         {
321           GTK_NOTE (PRINTING,
322                     g_print ("PAPI Backend: %s\n", error->message));
323
324           g_error_free (error);
325         } 
326
327       return FALSE;
328     }
329
330   GTK_NOTE (PRINTING,
331             g_print ("PAPI Backend: Writting %i byte chunk to papi pipe\n", bytes_read));
332
333   return TRUE;
334 }
335
336 static void
337 gtk_print_backend_papi_print_stream (GtkPrintBackend        *print_backend,
338                                     GtkPrintJob            *job,
339                                     GIOChannel             *data_io,
340                                     GtkPrintJobCompleteFunc callback,
341                                     gpointer                user_data,
342                                     GDestroyNotify          dnotify)
343 {
344   GError *print_error = NULL;
345   GtkPrinterPapi *printer;
346   _PrintStreamData *ps;
347   GtkPrintSettings *settings;
348   gint argc;  
349   gint in_fd;
350   gchar **argv = NULL; 
351   const gchar *title;
352   char *prtnm = NULL;
353   GtkPrintDuplex val;
354   papi_status_t pstatus = NULL;
355   papi_attribute_t **attrs = NULL;
356   papi_job_ticket_t *ticket = NULL;
357   
358   printer = GTK_PRINTER_PAPI (gtk_print_job_get_printer (job));
359   settings = gtk_print_job_get_settings (job);
360
361   /* FIXME - the title should be set as the job-name */
362   title = gtk_print_job_get_title (job);
363
364   ps = g_new0 (_PrintStreamData, 1);
365   ps->callback = callback;
366   ps->user_data = user_data;
367   ps->dnotify = dnotify;
368   ps->job = g_object_ref (job);
369   ps->service = NULL;
370   ps->stream = NULL;
371
372    /* This cannot be queried yet with the current API */
373   papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "document-format", "application/postscript");
374   val =  gtk_print_settings_get_duplex (settings) ;
375   if (val == GTK_PRINT_DUPLEX_HORIZONTAL)
376     papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "Duplex", "DuplexNoTumble");
377   else if (val == GTK_PRINT_DUPLEX_VERTICAL)
378     papiAttributeListAddString (&attrs, PAPI_ATTR_EXCL, "Duplex", "DuplexTumble");
379
380   if (job->num_copies > 1) 
381     {
382       papiAttributeListAddInteger (&attrs, PAPI_ATTR_EXCL, "copies", job->num_copies); 
383     }
384
385   prtnm = strdup (gtk_printer_get_name (GTK_PRINTER(printer)));
386
387   if (papiServiceCreate (&(ps->service), prtnm, NULL, NULL, NULL,
388                          PAPI_ENCRYPT_NEVER, NULL) != PAPI_OK)
389     return;
390
391   pstatus = papiJobStreamOpen (ps->service, prtnm, attrs, ticket, &(ps->stream));
392   if (pstatus != PAPI_OK)
393     {
394       papiServiceDestroy (ps->service);
395       ps->service = NULL;
396       return;
397     }
398
399   /* Everything set up fine, so get ready to wait for input data stream */
400   g_io_add_watch (data_io,
401                   G_IO_IN | G_IO_PRI | G_IO_ERR | G_IO_HUP,
402                   (GIOFunc) papi_write,
403                   ps);
404 }
405
406
407 static void
408 _papi_set_default_printer (GtkPrintBackendPapi *backend)
409 {
410   char *def_printer = NULL;
411   char *_default_attr[] = { "printer-name", NULL };
412   papi_service_t service = NULL;
413   papi_printer_t default_printer = NULL;
414   papi_attribute_t **attrs = NULL;
415
416   if (papiServiceCreate (&service, NULL, NULL, NULL, NULL, PAPI_ENCRYPT_NEVER,
417                           NULL) != PAPI_OK)
418     return;
419
420   if (papiPrinterQuery (service, "_default", _default_attr, NULL, 
421                         &default_printer) == PAPI_OK)  
422     {
423       if (default_printer != NULL)  
424         {
425           attrs = papiPrinterGetAttributeList (default_printer);
426
427           if (attrs != NULL)
428             if (papiAttributeListGetString (attrs, NULL, "printer-name", 
429                                             &def_printer) == PAPI_OK) 
430               {
431                 backend->default_printer = strdup (def_printer);
432               }
433         }
434     }
435
436   papiPrinterFree (default_printer);
437   papiServiceDestroy (service);
438 }
439
440 static void
441 gtk_print_backend_papi_init (GtkPrintBackendPapi *backend)
442 {
443   _papi_set_default_printer (backend);
444 }
445
446 static void
447 gtk_print_backend_papi_finalize (GObject *object)
448 {
449   GtkPrintBackendPapi *backend_papi;
450
451   GTK_NOTE (PRINTING,
452             g_print ("PAPI Backend: finalizing PAPI backend module\n"));
453
454   backend_papi = GTK_PRINT_BACKEND_PAPI (object);
455
456   g_free (backend_papi->default_printer);
457   backend_papi->default_printer = NULL;
458
459   backend_parent_class->finalize (object);
460 }
461
462
463 static void
464 gtk_print_backend_papi_dispose (GObject *object)
465 {
466   GtkPrintBackendPapi *backend_papi;
467
468   GTK_NOTE (PRINTING,
469             g_print ("PAPI Backend: %s\n", G_STRFUNC));
470
471   backend_papi = GTK_PRINT_BACKEND_PAPI (object);
472
473   backend_parent_class->dispose (object);
474 }
475
476 char **
477 get_all_list(papi_service_t svc)
478 {
479         papi_status_t status;
480         papi_printer_t printer = NULL;
481         char *attr[] = { "member-names", NULL };
482         char **names = NULL;
483
484         status = papiPrinterQuery(svc, "_all", attr, NULL, &printer);
485         if ((status == PAPI_OK) && (printer != NULL)) {
486                 papi_attribute_t **attributes =
487                                         papiPrinterGetAttributeList(printer);
488                 if (attributes != NULL) {
489                         void *iter = NULL;
490                         char *member = NULL;
491
492                         for (status = papiAttributeListGetString(attributes,
493                                                 &iter, "member-names", &member);
494                                 status == PAPI_OK;
495                                 status = papiAttributeListGetString(attributes,
496                                                 &iter, NULL, &member))
497                                         list_append(&names, strdup(member));
498                 }
499                 papiPrinterFree(printer);
500         }
501
502         return (names);
503 }
504
505 static char **
506 get_printers_list(papi_service_t svc)
507 {
508         papi_status_t status;
509         papi_printer_t *printers = NULL;
510         char *keys[] = { "printer-name", "printer-uri-supported", NULL };
511         char **names = NULL;
512
513         status = papiPrintersList(svc, keys, NULL, &printers);
514         if ((status == PAPI_OK) && (printers != NULL)) {
515                 int i;
516
517                 for (i = 0; printers[i] != NULL; i++) {
518                         papi_attribute_t **attributes =
519                                 papiPrinterGetAttributeList(printers[i]);
520                         char *name = NULL;
521                         
522                         (void) papiAttributeListGetString(attributes, NULL,
523                                                         "printer-name", &name);
524                         if ((name != NULL) && (strcmp(name, "_default") != 0))
525                                 list_append(&names, strdup(name));
526                 }
527                 papiPrinterListFree(printers);
528         }
529     
530         return (names);
531 }
532
533 static void
534 papi_request_printer_list (GtkPrintBackend *backend)
535 {
536   GtkPrintBackendPapi *papi_backend;
537
538   papi_backend = GTK_PRINT_BACKEND_PAPI (backend);
539
540   /* Get the list of printers using papi API */
541   papi_get_printer_list (papi_backend); 
542 }
543
544 static gboolean
545 papi_get_printer_list (GtkPrintBackendPapi *papi_backend)
546 {
547   int i;
548   const char *attributes[] =  /* Attributes we're interested in */
549     {
550       "printer-name",
551       "printer-uri-supported",
552       NULL
553     };
554   papi_status_t status, status2;
555   papi_service_t service = NULL;
556   char **printers = NULL;
557   GtkPrinter *printer;
558   GtkPrinterPapi *papi_printer;
559   GList *current_printer_list;
560   GtkPrintBackend *backend = GTK_PRINT_BACKEND (papi_backend);
561   
562   if ((status = papiServiceCreate (&service, NULL, NULL, NULL, NULL,
563                 PAPI_ENCRYPT_NEVER, NULL)) != PAPI_OK)
564     return FALSE; 
565
566   if ((printers = get_all_list (service)) == NULL) 
567     {
568       printers = get_printers_list (service);
569     }
570
571   if (printers == NULL) 
572     {
573       papiServiceDestroy (service);
574       return FALSE;
575     }
576
577   for (i = 0; printers[i] != NULL; i++) 
578     {
579       GtkPrinter *printer;
580       char *name = NULL, *url = NULL;
581       papi_attribute_t **attrs = NULL;
582
583           printer = gtk_print_backend_find_printer (backend, printers[i]);
584
585           if (!printer) 
586             {
587               /* skip null printer name just in case */
588               if (printers[i] == NULL)
589                 continue;
590
591               /* skip the alias _default and _all printers */
592               if (strcmp(printers[i], "_default")==0 || strcmp(printers[i], "_all")==0)
593                 continue;       
594
595               papi_printer = gtk_printer_papi_new (printers[i], backend);
596               printer = GTK_PRINTER (papi_printer);
597
598               /* Only marked default printer to not have details so that
599                  the request_details method will be called  at start up
600                */
601
602               if (papi_backend->default_printer != NULL)
603                 if (strcmp (printers[i], papi_backend->default_printer)==0)
604                   {
605                     gtk_printer_set_is_default (printer, TRUE);
606                   }     
607
608               gtk_printer_set_icon_name (printer, "gtk-print");
609               gtk_print_backend_add_printer (backend, printer);
610               gtk_printer_set_is_active (printer, TRUE);
611
612               /* gtk_printer_set_has_details (printer, TRUE); */
613             }
614           else 
615             g_object_ref (printer);
616
617       if (!gtk_printer_is_active (printer))
618         {
619           gtk_printer_set_is_active (printer, TRUE);
620           gtk_printer_set_is_new (printer, TRUE);
621         }
622
623       if (gtk_printer_is_new (printer))
624         {
625           g_signal_emit_by_name (backend, "printer-added", printer);
626           gtk_printer_set_is_new (printer, FALSE);
627         }
628
629       g_object_unref (printer);
630     }
631
632   free (printers);
633   papiServiceDestroy (service);
634
635   /* To set that the list of printers added is complete */
636   gtk_print_backend_set_list_done (backend); 
637
638   return TRUE;
639 }
640
641 static void
642 update_printer_status (GtkPrinter *printer)
643 {
644   GtkPrintBackend *backend;
645   GtkPrinterPapi *papi_printer;
646   gboolean status_changed = FALSE;
647
648   backend = gtk_printer_get_backend (printer);
649   papi_printer = GTK_PRINTER_PAPI (printer);
650
651   /* if (status_changed) */
652     g_signal_emit_by_name (GTK_PRINT_BACKEND (backend),
653                            "printer-status-changed", printer);
654
655 }
656
657
658 static GtkPrinterOptionSet *
659 papi_printer_get_options (GtkPrinter           *printer,
660                           GtkPrintSettings     *settings,
661                           GtkPageSetup         *page_setup,
662                           GtkPrintCapabilities  capabilities)
663 {
664   GtkPrinterOptionSet *set;
665   GtkPrinterOption *option;
666   int i;
667   char *print_at[] = { "now", "on-hold" };
668   char *n_up[] = {"1"};
669
670   /* Update the printer status before the printer options are displayed */
671   update_printer_status (printer); 
672
673   set = gtk_printer_option_set_new ();
674
675   /* non-ppd related settings */
676
677   /* This maps to number-up-supported in PAPI. FIXME 
678    * number-up-default is the default value. 
679    * number-up-supported is the list of number of able to print per page 
680    */
681   option = gtk_printer_option_new ("gtk-n-up", "Pages Per Sheet", GTK_PRINTER_OPTION_TYPE_PICKONE);
682   gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (n_up),
683                                          n_up, n_up);
684   gtk_printer_option_set (option, "1");
685   gtk_printer_option_set_add (set, option);
686   g_object_unref (option);
687
688   /* This maps to job-priority-supported and job-priority-default in PAPI - FIXME*/
689   
690   /* This relates to job-sheets-supported in PAPI  FIXME*/
691   
692   /* This relates to job-hold-until-supported in PAPI */
693   option = gtk_printer_option_new ("gtk-print-time", "Print at", GTK_PRINTER_OPTION_TYPE_PICKONE);
694   gtk_printer_option_choices_from_array (option, G_N_ELEMENTS (print_at),
695                                          print_at, print_at);
696   gtk_printer_option_set (option, "now");
697   gtk_printer_option_set_add (set, option);
698   g_object_unref (option);
699   
700   return set;
701 }
702
703 static void
704 papi_printer_get_settings_from_options (GtkPrinter          *printer,
705                                        GtkPrinterOptionSet *options,
706                                        GtkPrintSettings    *settings)
707 {
708   GtkPrinterOption *option;
709
710   option = gtk_printer_option_set_lookup (options, "gtk-n-up");
711   if (option)
712      gtk_print_settings_set (settings, GTK_PRINT_SETTINGS_NUMBER_UP, option->value);
713
714 }
715
716 static void
717 papi_printer_prepare_for_print (GtkPrinter       *printer,
718                                GtkPrintJob      *print_job,
719                                GtkPrintSettings *settings,
720                                GtkPageSetup     *page_setup)
721 {
722   GtkPageSet page_set;
723   double scale;
724   GtkPaperSize *papersize = NULL;
725   char *ppd_paper_name;
726
727   print_job->print_pages = gtk_print_settings_get_print_pages (settings);
728   print_job->page_ranges = NULL;
729   print_job->num_page_ranges = 0;
730   
731   if (print_job->print_pages == GTK_PRINT_PAGES_RANGES)
732     print_job->page_ranges =
733       gtk_print_settings_get_page_ranges (settings,
734                                           &print_job->num_page_ranges);
735   
736   print_job->collate = gtk_print_settings_get_collate (settings);
737   print_job->reverse = gtk_print_settings_get_reverse (settings);
738   print_job->num_copies = gtk_print_settings_get_n_copies (settings);
739  
740   scale = gtk_print_settings_get_scale (settings);
741   if (scale != 100.0)
742     print_job->scale = scale/100.0;
743
744   papersize = gtk_page_setup_get_paper_size (page_setup);
745   ppd_paper_name = gtk_paper_size_get_ppd_name (papersize);
746
747   page_set = gtk_print_settings_get_page_set (settings);
748   if (page_set == GTK_PAGE_SET_EVEN)
749     print_job->page_set = GTK_PAGE_SET_EVEN;
750   else if (page_set == GTK_PAGE_SET_ODD)
751     print_job->page_set = GTK_PAGE_SET_ODD;
752   else
753     print_job->page_set = GTK_PAGE_SET_ALL;
754
755   print_job->rotate_to_orientation = TRUE;
756
757 }
758
759 gboolean
760 is_local_printer (gchar *printer_uri)
761 {
762   if (strncmp (printer_uri, "lpsched:", 8) == 0)
763     return TRUE;
764   else
765     return FALSE;
766 }
767
768 void
769 merge_ppd_data (papi_attribute_t ***attributes, gchar *ppdfile)
770 {
771   get_ppd_attrs (attributes, ppdfile);
772 }
773
774
775 static void
776 papi_display_printer_status_done (gpointer user_data)
777 {
778   GtkPrinter *printer = (GtkPrinter *) user_data;
779   GtkPrinterPapi *papi_printer;
780
781   g_signal_emit_by_name (printer, "details-acquired", TRUE); 
782   papi_printer = GTK_PRINTER_PAPI (printer);
783   return;
784 }
785
786 #define IDLE 3
787 #define PROCESSING 4
788 #define STOPPED 5
789 static gboolean
790 papi_display_printer_status (gpointer user_data)
791 {
792   GtkPrinter *printer = (GtkPrinter *) user_data;
793   GtkPrinterPapi *papi_printer;
794   gchar *loc, *printer_uri, *ppdfile;
795   int state;
796   papi_service_t service;
797   papi_attribute_t **attrs = NULL;
798   papi_printer_t current_printer = NULL;
799   static int count = 0;
800
801   papi_printer = GTK_PRINTER_PAPI (printer);
802   if (papiServiceCreate (&service, NULL, NULL, NULL, NULL, PAPI_ENCRYPT_NEVER,
803                           NULL) != PAPI_OK)
804     return FALSE;
805
806   if (papiPrinterQuery (service, papi_printer->printer_name, NULL, NULL,
807                         &current_printer) != PAPI_OK) 
808     {
809        /* SUN_BRANDING */
810        gtk_printer_set_state_message (printer, _("printer offline"));
811     }
812
813   if (current_printer != NULL)
814     {
815         attrs = papiPrinterGetAttributeList (current_printer);
816     }
817
818   if (papiAttributeListGetString (attrs, NULL, "printer-info", &loc) == PAPI_OK)
819     {
820         gtk_printer_set_location (printer, loc);
821     }
822
823   if (papiAttributeListGetInteger (attrs, NULL, "printer-state", &state) == PAPI_OK)
824     {
825       switch (state) 
826         {
827           /* SUN_BRANDING */
828           case IDLE: gtk_printer_set_state_message (printer, _("ready to print"));
829                      break;
830           /* SUN_BRANDING */
831           case PROCESSING: gtk_printer_set_state_message (printer, _("processing job"));
832                            break;
833
834           /* SUN_BRANDING */
835           case STOPPED: gtk_printer_set_state_message (printer, _("paused"));
836                         break;
837           /* SUN_BRANDING */
838           default: gtk_printer_set_state_message (printer, _("unknown"));
839                    break;
840         }
841     }
842
843   papiPrinterFree (current_printer);
844   papiServiceDestroy (service);
845   gtk_printer_set_has_details (printer, TRUE);
846
847   return FALSE;
848 }
849
850 static void  
851 papi_printer_request_details (GtkPrinter *printer)
852 {
853   g_idle_add_full (G_PRIORITY_DEFAULT_IDLE, papi_display_printer_status, printer, papi_display_printer_status_done); 
854 }
855
856
857 static GtkPrintCapabilities
858 papi_printer_get_capabilities (GtkPrinter *printer)
859 {
860   return GTK_PRINT_CAPABILITY_COPIES | GTK_PRINT_CAPABILITY_PAGE_SET ; 
861 }
862