]> Pileus Git - ~andy/gtk/blob - gtk/gtkprinter.c
Add new capability GTK_PRINT_CAPABILITY_NUMBER_UP.
[~andy/gtk] / gtk / gtkprinter.c
1 /* GtkPrinter
2  * Copyright (C) 2006 John (J5) Palmieri  <johnp@redhat.com>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with this library; if not, write to the
16  * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
17  * Boston, MA 02111-1307, USA.
18  */
19
20 #include "config.h"
21 #include <stdlib.h>
22 #include <string.h>
23 #include <stdio.h>
24
25 #include "gtkintl.h"
26 #include "gtkprivate.h"
27
28 #include "gtkprinter.h"
29 #include "gtkprinter-private.h"
30 #include "gtkprintbackend.h"
31 #include "gtkprintjob.h"
32 #include "gtkalias.h"
33
34 #define GTK_PRINTER_GET_PRIVATE(o)  \
35    (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINTER, GtkPrinterPrivate))
36
37 static void gtk_printer_finalize     (GObject *object);
38
39 struct _GtkPrinterPrivate
40 {
41   gchar *name;
42   gchar *location;
43   gchar *description;
44   gchar *icon_name;
45
46   guint is_active   : 1;
47   guint is_new      : 1;
48   guint is_virtual  : 1;
49   guint is_default  : 1;
50   guint has_details : 1;
51   guint accepts_pdf : 1;
52   guint accepts_ps  : 1;
53
54   gchar *state_message;  
55   gint job_count;
56
57   GtkPrintBackend *backend;
58 };
59
60 enum {
61   DETAILS_ACQUIRED,
62   LAST_SIGNAL
63 };
64
65 enum {
66   PROP_0,
67   PROP_NAME,
68   PROP_BACKEND,
69   PROP_IS_VIRTUAL,
70   PROP_STATE_MESSAGE,
71   PROP_LOCATION,
72   PROP_ICON_NAME,
73   PROP_JOB_COUNT,
74   PROP_ACCEPTS_PDF,
75   PROP_ACCEPTS_PS
76 };
77
78 static guint signals[LAST_SIGNAL] = { 0 };
79
80 static void gtk_printer_set_property (GObject      *object,
81                                       guint         prop_id,
82                                       const GValue *value,
83                                       GParamSpec   *pspec);
84 static void gtk_printer_get_property (GObject      *object,
85                                       guint         prop_id,
86                                       GValue       *value,
87                                       GParamSpec   *pspec);
88
89 G_DEFINE_TYPE (GtkPrinter, gtk_printer, G_TYPE_OBJECT)
90
91 static int
92 safe_strcmp (const char *a, const char *b)
93 {
94   if (a == b)
95     return 0;
96   if (a == NULL)
97     return -1;
98   if (b == NULL)
99     return 1;
100   return strcmp (a, b);
101 }
102
103 static void
104 gtk_printer_class_init (GtkPrinterClass *class)
105 {
106   GObjectClass *object_class;
107   object_class = (GObjectClass *) class;
108
109   object_class->finalize = gtk_printer_finalize;
110
111   object_class->set_property = gtk_printer_set_property;
112   object_class->get_property = gtk_printer_get_property;
113
114   g_type_class_add_private (class, sizeof (GtkPrinterPrivate));
115
116   g_object_class_install_property (G_OBJECT_CLASS (class),
117                                    PROP_NAME,
118                                    g_param_spec_string ("name",
119                                                         P_("Name"),
120                                                         P_("Name of the printer"),
121                                                         NULL,
122                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
123   g_object_class_install_property (G_OBJECT_CLASS (class),
124                                    PROP_BACKEND,
125                                    g_param_spec_object ("backend",
126                                                         P_("Backend"),
127                                                         P_("Backend for the printer"),
128                                                         GTK_TYPE_PRINT_BACKEND,
129                                                         GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
130   g_object_class_install_property (G_OBJECT_CLASS (class),
131                                    PROP_IS_VIRTUAL,
132                                    g_param_spec_boolean ("is-virtual",
133                                                          P_("Is Virtual"),
134                                                          P_("FALSE if this represents a real hardware printer"),
135                                                          FALSE,
136                                                          GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
137   g_object_class_install_property (G_OBJECT_CLASS (class),
138                                    PROP_ACCEPTS_PDF,
139                                    g_param_spec_boolean ("accepts-pdf",
140                                                          P_("Accepts PDF"),
141                                                          P_("TRUE if this printer can accept PDF"),
142                                                          TRUE,
143                                                          GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
144   g_object_class_install_property (G_OBJECT_CLASS (class),
145                                    PROP_ACCEPTS_PS,
146                                    g_param_spec_boolean ("accepts-ps",
147                                                          P_("Accepts PostScript"),
148                                                          P_("TRUE if this printer can accept PostScript"),
149                                                          TRUE,
150                                                          GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
151   g_object_class_install_property (G_OBJECT_CLASS (class),
152                                    PROP_STATE_MESSAGE,
153                                    g_param_spec_string ("state-message",
154                                                         P_("State Message"),
155                                                         P_("String giving the current state of the printer"),
156                                                         NULL,
157                                                         GTK_PARAM_READABLE));
158   g_object_class_install_property (G_OBJECT_CLASS (class),
159                                    PROP_LOCATION,
160                                    g_param_spec_string ("location",
161                                                         P_("Location"),
162                                                         P_("The location of the printer"),
163                                                         NULL,
164                                                         GTK_PARAM_READABLE));
165   g_object_class_install_property (G_OBJECT_CLASS (class),
166                                    PROP_ICON_NAME,
167                                    g_param_spec_string ("icon-name",
168                                                         P_("Icon Name"),
169                                                         P_("The icon name to use for the printer"),
170                                                         NULL,
171                                                         GTK_PARAM_READABLE));
172   g_object_class_install_property (G_OBJECT_CLASS (class),
173                                    PROP_JOB_COUNT,
174                                    g_param_spec_int ("job-count",
175                                                      P_("Job Count"),
176                                                      P_("Number of jobs queued in the printer"),
177                                                      0,
178                                                      G_MAXINT,
179                                                      0,
180                                                      GTK_PARAM_READABLE));
181
182   /**
183    * GtkPrinter::details-acquired:
184    * @printer: the #GtkPrinter on which the signal is emitted
185    * @success: %TRUE if the details were successfully acquired
186    *
187    * Gets emitted in response to a request for detailed information
188    * about a printer from the print backend. The @success parameter
189    * indicates if the information was actually obtained.
190    *
191    * Since: 2.10
192    */
193   signals[DETAILS_ACQUIRED] =
194     g_signal_new (I_("details-acquired"),
195                   G_TYPE_FROM_CLASS (class),
196                   G_SIGNAL_RUN_LAST,
197                   G_STRUCT_OFFSET (GtkPrinterClass, details_acquired),
198                   NULL, NULL,
199                   g_cclosure_marshal_VOID__BOOLEAN,
200                   G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
201 }
202
203 static void
204 gtk_printer_init (GtkPrinter *printer)
205 {
206   GtkPrinterPrivate *priv;
207
208   priv = printer->priv = GTK_PRINTER_GET_PRIVATE (printer); 
209
210   priv->name = NULL;
211   priv->location = NULL;
212   priv->description = NULL;
213   priv->icon_name = NULL;
214
215   priv->is_active = TRUE;
216   priv->is_new = TRUE;
217   priv->has_details = FALSE;
218   priv->accepts_pdf = TRUE;
219   priv->accepts_ps = TRUE;
220
221   priv->state_message = NULL;  
222   priv->job_count = 0;
223 }
224
225 static void
226 gtk_printer_finalize (GObject *object)
227 {
228   GtkPrinter *printer = GTK_PRINTER (object);
229   GtkPrinterPrivate *priv = printer->priv;
230
231   g_free (priv->name);
232   g_free (priv->location);
233   g_free (priv->description);
234   g_free (priv->state_message);
235   g_free (priv->icon_name);
236
237   if (priv->backend)
238     g_object_unref (priv->backend);
239
240   G_OBJECT_CLASS (gtk_printer_parent_class)->finalize (object);
241 }
242
243 static void
244 gtk_printer_set_property (GObject         *object,
245                           guint            prop_id,
246                           const GValue    *value,
247                           GParamSpec      *pspec)
248 {
249   GtkPrinter *printer = GTK_PRINTER (object);
250   GtkPrinterPrivate *priv = printer->priv;
251
252   switch (prop_id)
253     {
254     case PROP_NAME:
255       priv->name = g_value_dup_string (value);
256       break;
257     
258     case PROP_BACKEND:
259       priv->backend = GTK_PRINT_BACKEND (g_value_dup_object (value));
260       break;
261
262     case PROP_IS_VIRTUAL:
263       priv->is_virtual = g_value_get_boolean (value);
264       break;
265
266     case PROP_ACCEPTS_PDF:
267       priv->accepts_pdf = g_value_get_boolean (value);
268       break;
269
270     case PROP_ACCEPTS_PS:
271       priv->accepts_ps = g_value_get_boolean (value);
272       break;
273
274     default:
275       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
276       break;
277     }
278 }
279
280 static void
281 gtk_printer_get_property (GObject    *object,
282                           guint       prop_id,
283                           GValue     *value,
284                           GParamSpec *pspec)
285 {
286   GtkPrinter *printer = GTK_PRINTER (object);
287   GtkPrinterPrivate *priv = printer->priv;
288
289   switch (prop_id)
290     {
291     case PROP_NAME:
292       if (priv->name)
293         g_value_set_string (value, priv->name);
294       else
295         g_value_set_string (value, "");
296       break;
297     case PROP_BACKEND:
298       g_value_set_object (value, priv->backend);
299       break;
300     case PROP_STATE_MESSAGE:
301       if (priv->state_message)
302         g_value_set_string (value, priv->state_message);
303       else
304         g_value_set_string (value, "");
305       break;
306     case PROP_LOCATION:
307       if (priv->location)
308         g_value_set_string (value, priv->location);
309       else
310         g_value_set_string (value, "");
311       break;
312     case PROP_ICON_NAME:
313       if (priv->icon_name)
314         g_value_set_string (value, priv->icon_name);
315       else
316         g_value_set_string (value, "");
317       break;
318     case PROP_JOB_COUNT:
319       g_value_set_int (value, priv->job_count);
320       break;
321     case PROP_IS_VIRTUAL:
322       g_value_set_boolean (value, priv->is_virtual);
323       break;
324     case PROP_ACCEPTS_PDF:
325       g_value_set_boolean (value, priv->accepts_pdf);
326       break;
327     case PROP_ACCEPTS_PS:
328       g_value_set_boolean (value, priv->accepts_ps);
329       break;
330     default:
331       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
332       break;
333     }
334 }
335
336 /**
337  * gtk_printer_new:
338  * @name: the name of the printer
339  * @backend: a #GtkPrintBackend
340  * @virtual_: whether the printer is virtual
341  *
342  * Creates a new #GtkPrinter.
343  *
344  * Return value: a new #GtkPrinter
345  *
346  * Since: 2.10
347  **/
348 GtkPrinter *
349 gtk_printer_new (const gchar     *name,
350                  GtkPrintBackend *backend,
351                  gboolean         virtual_)
352 {
353   GObject *result;
354   
355   result = g_object_new (GTK_TYPE_PRINTER,
356                          "name", name,
357                          "backend", backend,
358                          "is-virtual", virtual_,
359                          NULL);
360
361   return (GtkPrinter *) result;
362 }
363
364 /**
365  * gtk_printer_get_backend:
366  * @printer: a #GtkPrinter
367  * 
368  * Returns the backend of the printer.
369  * 
370  * Return value: the backend of @printer
371  * 
372  * Since: 2.10
373  */
374 GtkPrintBackend *
375 gtk_printer_get_backend (GtkPrinter *printer)
376 {
377   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
378   
379   return printer->priv->backend;
380 }
381
382 /**
383  * gtk_printer_get_name:
384  * @printer: a #GtkPrinter
385  * 
386  * Returns the name of the printer.
387  * 
388  * Return value: the name of @printer
389  *
390  * Since: 2.10
391  */
392 G_CONST_RETURN gchar *
393 gtk_printer_get_name (GtkPrinter *printer)
394 {
395   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
396
397   return printer->priv->name;
398 }
399
400 /**
401  * gtk_printer_get_description:
402  * @printer: a #GtkPrinter
403  * 
404  * Gets the description of the printer.
405  * 
406  * Return value: the description of @printer
407  *
408  * Since: 2.10
409  */
410 G_CONST_RETURN gchar *
411 gtk_printer_get_description (GtkPrinter *printer)
412 {
413   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
414   
415   return printer->priv->description;
416 }
417
418 gboolean
419 gtk_printer_set_description (GtkPrinter  *printer,
420                              const gchar *description)
421 {
422   GtkPrinterPrivate *priv;
423
424   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
425
426   priv = printer->priv;
427
428   if (safe_strcmp (priv->description, description) == 0)
429     return FALSE;
430
431   g_free (priv->description);
432   priv->description = g_strdup (description);
433   
434   return TRUE;
435 }
436
437 /**
438  * gtk_printer_get_state_message:
439  * @printer: a #GtkPrinter
440  * 
441  * Returns the state message describing the current state
442  * of the printer.
443  * 
444  * Return value: the state message of @printer
445  *
446  * Since: 2.10
447  */
448 G_CONST_RETURN gchar *
449 gtk_printer_get_state_message (GtkPrinter *printer)
450 {
451   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
452
453   return printer->priv->state_message;
454 }
455
456 gboolean
457 gtk_printer_set_state_message (GtkPrinter  *printer,
458                                const gchar *message)
459 {
460   GtkPrinterPrivate *priv;
461
462   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
463
464   priv = printer->priv;
465
466   if (safe_strcmp (priv->state_message, message) == 0)
467     return FALSE;
468
469   g_free (priv->state_message);
470   priv->state_message = g_strdup (message);
471   g_object_notify (G_OBJECT (printer), "state-message");
472
473   return TRUE;
474 }
475
476 /**
477  * gtk_printer_get_location:
478  * @printer: a #GtkPrinter
479  * 
480  * Returns a description of the location of the printer.
481  * 
482  * Return value: the location of @printer
483  *
484  * Since: 2.10
485  */
486 G_CONST_RETURN gchar *
487 gtk_printer_get_location (GtkPrinter *printer)
488 {
489   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
490
491   return printer->priv->location;
492 }
493
494 gboolean
495 gtk_printer_set_location (GtkPrinter  *printer,
496                           const gchar *location)
497 {
498   GtkPrinterPrivate *priv;
499
500   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
501
502   priv = printer->priv;
503
504   if (safe_strcmp (priv->location, location) == 0)
505     return FALSE;
506
507   g_free (priv->location);
508   priv->location = g_strdup (location);
509   g_object_notify (G_OBJECT (printer), "location");
510   
511   return TRUE;
512 }
513
514 /**
515  * gtk_printer_get_icon_name:
516  * @printer: a #GtkPrinter
517  * 
518  * Gets the name of the icon to use for the printer.
519  * 
520  * Return value: the icon name for @printer
521  *
522  * Since: 2.10
523  */
524 G_CONST_RETURN gchar * 
525 gtk_printer_get_icon_name (GtkPrinter *printer)
526 {
527   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
528
529   return printer->priv->icon_name;
530 }
531
532 void
533 gtk_printer_set_icon_name (GtkPrinter  *printer,
534                            const gchar *icon)
535 {
536   GtkPrinterPrivate *priv;
537
538   g_return_if_fail (GTK_IS_PRINTER (printer));
539
540   priv = printer->priv;
541
542   g_free (priv->icon_name);
543   priv->icon_name = g_strdup (icon);
544   g_object_notify (G_OBJECT (printer), "icon-name");
545 }
546
547 /**
548  * gtk_printer_get_job_count:
549  * @printer: a #GtkPrinter
550  * 
551  * Gets the number of jobs currently queued on the printer.
552  * 
553  * Return value: the number of jobs on @printer
554  *
555  * Since: 2.10
556  */
557 gint 
558 gtk_printer_get_job_count (GtkPrinter *printer)
559 {
560   g_return_val_if_fail (GTK_IS_PRINTER (printer), 0);
561
562   return printer->priv->job_count;
563 }
564
565 gboolean
566 gtk_printer_set_job_count (GtkPrinter *printer,
567                            gint        count)
568 {
569   GtkPrinterPrivate *priv;
570
571   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
572
573   priv = printer->priv;
574
575   if (priv->job_count == count)
576     return FALSE;
577
578   priv->job_count = count;
579   
580   g_object_notify (G_OBJECT (printer), "job-count");
581   
582   return TRUE;
583 }
584
585 /**
586  * gtk_printer_has_details:
587  * @printer: a #GtkPrinter
588  * 
589  * Returns whether the printer details are available.
590  * 
591  * Return value: %TRUE if @printer details are available
592  *
593  * Since: 2.12
594  */
595 gboolean
596 gtk_printer_has_details (GtkPrinter *printer)
597 {
598   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
599
600   return printer->priv->has_details;
601 }
602
603 void
604 gtk_printer_set_has_details (GtkPrinter *printer,
605                              gboolean val)
606 {
607   printer->priv->has_details = val;
608 }
609
610 /**
611  * gtk_printer_is_active:
612  * @printer: a #GtkPrinter
613  * 
614  * Returns whether the printer is currently active (i.e. 
615  * accepts new jobs).
616  * 
617  * Return value: %TRUE if @printer is active
618  *
619  * Since: 2.10
620  */
621 gboolean
622 gtk_printer_is_active (GtkPrinter *printer)
623 {
624   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
625   
626   return printer->priv->is_active;
627 }
628
629 void
630 gtk_printer_set_is_active (GtkPrinter *printer,
631                            gboolean val)
632 {
633   g_return_if_fail (GTK_IS_PRINTER (printer));
634
635   printer->priv->is_active = val;
636 }
637
638
639 /**
640  * gtk_printer_is_virtual:
641  * @printer: a #GtkPrinter
642  * 
643  * Returns whether the printer is virtual (i.e. does not
644  * represent actual printer hardware, but something like 
645  * a CUPS class).
646  * 
647  * Return value: %TRUE if @printer is virtual
648  *
649  * Since: 2.10
650  */
651 gboolean
652 gtk_printer_is_virtual (GtkPrinter *printer)
653 {
654   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
655   
656   return printer->priv->is_virtual;
657 }
658
659 /**
660  * gtk_printer_accepts_pdf:
661  * @printer: a #GtkPrinter
662  *
663  * Returns whether the printer accepts input in
664  * PDF format.  
665  *
666  * Return value: %TRUE if @printer accepts PDF
667  *
668  * Since: 2.10
669  */
670 gboolean 
671 gtk_printer_accepts_pdf (GtkPrinter *printer)
672
673   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
674   
675   return printer->priv->accepts_pdf;
676 }
677
678 /**
679  * gtk_printer_accepts_ps:
680  * @printer: a #GtkPrinter
681  *
682  * Returns whether the printer accepts input in
683  * PostScript format.  
684  *
685  * Return value: %TRUE if @printer accepts PostScript
686  *
687  * Since: 2.10
688  */
689 gboolean 
690 gtk_printer_accepts_ps (GtkPrinter *printer)
691
692   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
693   
694   return printer->priv->accepts_ps;
695 }
696
697 gboolean
698 gtk_printer_is_new (GtkPrinter *printer)
699 {
700   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
701   
702   return printer->priv->is_new;
703 }
704
705 void
706 gtk_printer_set_is_new (GtkPrinter *printer,
707                         gboolean val)
708 {
709   g_return_if_fail (GTK_IS_PRINTER (printer));
710
711   printer->priv->is_new = val;
712 }
713
714
715 /**
716  * gtk_printer_is_default:
717  * @printer: a #GtkPrinter
718  * 
719  * Returns whether the printer is the default printer.
720  * 
721  * Return value: %TRUE if @printer is the default
722  *
723  * Since: 2.10
724  */
725 gboolean
726 gtk_printer_is_default (GtkPrinter *printer)
727 {
728   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
729   
730   return printer->priv->is_default;
731 }
732
733 void
734 gtk_printer_set_is_default (GtkPrinter *printer,
735                             gboolean    val)
736 {
737   g_return_if_fail (GTK_IS_PRINTER (printer));
738
739   printer->priv->is_default = TRUE;
740 }
741
742 /**
743  * gtk_printer_request_details:
744  * @printer: a #GtkPrinter
745  * 
746  * Requests the printer details. When the details are available,
747  * the #GtkPrinter::details-acquired signal will be emitted on @printer.
748  * 
749  * Since: 2.12
750  */
751 void
752 gtk_printer_request_details (GtkPrinter *printer)
753 {
754   GtkPrintBackendClass *backend_class;
755
756   g_return_if_fail (GTK_IS_PRINTER (printer));
757
758   backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
759   backend_class->printer_request_details (printer);
760 }
761
762 GtkPrinterOptionSet *
763 _gtk_printer_get_options (GtkPrinter           *printer,
764                           GtkPrintSettings     *settings,
765                           GtkPageSetup         *page_setup,
766                           GtkPrintCapabilities  capabilities)
767 {
768   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
769   return backend_class->printer_get_options (printer, settings, page_setup, capabilities);
770 }
771
772 gboolean
773 _gtk_printer_mark_conflicts (GtkPrinter          *printer,
774                              GtkPrinterOptionSet *options)
775 {
776   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
777   return backend_class->printer_mark_conflicts (printer, options);
778 }
779   
780 void
781 _gtk_printer_get_settings_from_options (GtkPrinter          *printer,
782                                         GtkPrinterOptionSet *options,
783                                         GtkPrintSettings    *settings)
784 {
785   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
786   backend_class->printer_get_settings_from_options (printer, options, settings);
787 }
788
789 void
790 _gtk_printer_prepare_for_print (GtkPrinter       *printer,
791                                 GtkPrintJob      *print_job,
792                                 GtkPrintSettings *settings,
793                                 GtkPageSetup     *page_setup)
794 {
795   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
796   backend_class->printer_prepare_for_print (printer, print_job, settings, page_setup);
797 }
798
799 cairo_surface_t *
800 _gtk_printer_create_cairo_surface (GtkPrinter       *printer,
801                                    GtkPrintSettings *settings,
802                                    gdouble           width, 
803                                    gdouble           height,
804                                    GIOChannel       *cache_io)
805 {
806   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
807
808   return backend_class->printer_create_cairo_surface (printer, settings,
809                                                       width, height, cache_io);
810 }
811
812 /**
813  * gtk_printer_list_papers:
814  * @printer: a #GtkPrinter
815  * 
816  * Lists all the paper sizes @printer supports.
817  * This will return and empty list unless the printer's details are 
818  * available, see gtk_printer_has_details() and gtk_printer_request_details().
819  * 
820  * Return value: a newly allocated list of newly allocated #GtkPageSetup s.
821  *
822  * Since: 2.12
823  */
824 GList  *
825 gtk_printer_list_papers (GtkPrinter *printer)
826 {
827   GtkPrintBackendClass *backend_class;
828
829   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
830
831   backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
832   return backend_class->printer_list_papers (printer);
833 }
834
835 void
836 _gtk_printer_get_hard_margins (GtkPrinter *printer,
837                                gdouble    *top,
838                                gdouble    *bottom,
839                                gdouble    *left,
840                                gdouble    *right)
841 {
842   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
843
844   backend_class->printer_get_hard_margins (printer, top, bottom, left, right);
845 }
846
847 /**
848  * gtk_printer_get_capabilities:
849  * @printer: a #GtkPrinter
850  * 
851  * Returns the printer's capabilities.
852  *
853  * This is useful when you're using #GtkPrintUnixDialog's manual-capabilities 
854  * setting and need to know which settings the printer can handle and which 
855  * you must handle yourself.
856  *
857  * This will return 0 unless the printer's details are available, see
858  * gtk_printer_has_details() and gtk_printer_request_details().
859  *  *
860  * Return value: the printer's capabilities
861  *
862  * Since: 2.12
863  */
864 GtkPrintCapabilities
865 gtk_printer_get_capabilities (GtkPrinter *printer)
866 {
867   GtkPrintBackendClass *backend_class;
868
869   g_return_val_if_fail (GTK_IS_PRINTER (printer), 0);
870
871   backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
872   return backend_class->printer_get_capabilities (printer);
873 }
874
875 /**
876  * gtk_printer_compare:
877  * @a: a #GtkPrinter
878  * @b: another #GtkPrinter
879  *
880  * Compares two printers.
881  * 
882  * Return value: 0 if the printer match, a negative value if @a &lt; @b, 
883  *   or a positive value if @a &gt; @b
884  *
885  * Since: 2.10
886  */
887 gint
888 gtk_printer_compare (GtkPrinter *a, 
889                      GtkPrinter *b)
890 {
891   const char *name_a, *name_b;
892   
893   g_assert (GTK_IS_PRINTER (a) && GTK_IS_PRINTER (b));
894   
895   name_a = gtk_printer_get_name (a);
896   name_b = gtk_printer_get_name (b);
897   if (name_a == NULL  && name_b == NULL)
898     return 0;
899   else if (name_a == NULL)
900     return G_MAXINT;
901   else if (name_b == NULL)
902     return G_MININT;
903   else
904     return g_ascii_strcasecmp (name_a, name_b);
905 }
906
907
908 typedef struct 
909 {
910   GList *backends;
911   GtkPrinterFunc func;
912   gpointer data;
913   GDestroyNotify destroy;
914   GMainLoop *loop;
915 } PrinterList;
916
917 static void list_done_cb (GtkPrintBackend *backend, 
918                           PrinterList     *printer_list);
919
920 static void
921 stop_enumeration (PrinterList *printer_list)
922 {
923   GList *list, *next;
924   GtkPrintBackend *backend;
925
926   for (list = printer_list->backends; list; list = next)
927     {
928       next = list->next;
929       backend = GTK_PRINT_BACKEND (list->data);
930       list_done_cb (backend, printer_list);
931     }
932 }
933
934 static void 
935 free_printer_list (PrinterList *printer_list)
936 {
937   if (printer_list->destroy)
938     printer_list->destroy (printer_list->data);
939
940   if (printer_list->loop)
941     {    
942       g_main_loop_quit (printer_list->loop);
943       g_main_loop_unref (printer_list->loop);
944     }
945
946   g_free (printer_list);
947 }
948
949 static gboolean
950 list_added_cb (GtkPrintBackend *backend, 
951                GtkPrinter      *printer, 
952                PrinterList     *printer_list)
953 {
954   if (printer_list->func (printer, printer_list->data))
955     {
956       stop_enumeration (printer_list);
957       return TRUE;
958     }
959
960   return FALSE;
961 }
962
963 static void
964 list_done_cb (GtkPrintBackend *backend, 
965               PrinterList     *printer_list)
966 {
967   printer_list->backends = g_list_remove (printer_list->backends, backend);
968   
969   g_signal_handlers_disconnect_by_func (backend, list_added_cb, printer_list);
970   g_signal_handlers_disconnect_by_func (backend, list_done_cb, printer_list);
971   
972   gtk_print_backend_destroy (backend);
973   g_object_unref (backend);
974
975   if (printer_list->backends == NULL)
976     free_printer_list (printer_list);
977 }
978
979 static gboolean
980 list_printers_init (PrinterList     *printer_list,
981                     GtkPrintBackend *backend)
982 {
983   GList *list, *node;
984
985   list = gtk_print_backend_get_printer_list (backend);
986
987   for (node = list; node != NULL; node = node->next)
988     {
989       if (list_added_cb (backend, node->data, printer_list))
990         {
991           g_list_free (list);
992           return TRUE;
993         }
994     }
995
996   g_list_free (list);
997
998   if (gtk_print_backend_printer_list_is_done (backend))
999     {
1000       printer_list->backends = g_list_remove (printer_list->backends, backend);
1001       gtk_print_backend_destroy (backend);
1002       g_object_unref (backend);
1003     }
1004   else
1005     {
1006       g_signal_connect (backend, "printer-added", 
1007                         (GCallback) list_added_cb, 
1008                         printer_list);
1009       g_signal_connect (backend, "printer-list-done", 
1010                         (GCallback) list_done_cb, 
1011                         printer_list);
1012     }
1013
1014   return FALSE;
1015 }
1016
1017 /**
1018  * gtk_enumerate_printers:
1019  * @func: a function to call for each printer
1020  * @data: user data to pass to @func
1021  * @destroy: function to call if @data is no longer needed
1022  * @wait: if %TRUE, wait in a recursive mainloop until
1023  *    all printers are enumerated; otherwise return early
1024  *
1025  * Calls a function for all #GtkPrinter<!-- -->s. 
1026  * If @func returns %TRUE, the enumeration is stopped.
1027  *
1028  * Since: 2.10
1029  */
1030 void
1031 gtk_enumerate_printers (GtkPrinterFunc func,
1032                         gpointer       data,
1033                         GDestroyNotify destroy,
1034                         gboolean       wait)
1035 {
1036   PrinterList *printer_list;
1037   GList *node, *next;
1038   GtkPrintBackend *backend;
1039
1040   printer_list = g_new0 (PrinterList, 1);
1041
1042   printer_list->func = func;
1043   printer_list->data = data;
1044   printer_list->destroy = destroy;
1045
1046   if (g_module_supported ())
1047     printer_list->backends = gtk_print_backend_load_modules ();
1048   
1049   if (printer_list->backends == NULL)
1050     {
1051       free_printer_list (printer_list);
1052       return;
1053     }
1054
1055   for (node = printer_list->backends; node != NULL; node = next)
1056     {
1057       next = node->next;
1058       backend = GTK_PRINT_BACKEND (node->data);
1059       if (list_printers_init (printer_list, backend))
1060         return;
1061     }
1062
1063   if (wait && printer_list->backends)
1064     {
1065       printer_list->loop = g_main_loop_new (NULL, FALSE);
1066
1067       GDK_THREADS_LEAVE ();  
1068       g_main_loop_run (printer_list->loop);
1069       GDK_THREADS_ENTER ();  
1070     }
1071 }
1072
1073 GType
1074 gtk_print_capabilities_get_type (void)
1075 {
1076   static GType etype = 0;
1077
1078   if (G_UNLIKELY (etype == 0))
1079     {
1080       static const GFlagsValue values[] = {
1081         { GTK_PRINT_CAPABILITY_PAGE_SET, "GTK_PRINT_CAPABILITY_PAGE_SET", "page-set" },
1082         { GTK_PRINT_CAPABILITY_COPIES, "GTK_PRINT_CAPABILITY_COPIES", "copies" },
1083         { GTK_PRINT_CAPABILITY_COLLATE, "GTK_PRINT_CAPABILITY_COLLATE", "collate" },
1084         { GTK_PRINT_CAPABILITY_REVERSE, "GTK_PRINT_CAPABILITY_REVERSE", "reverse" },
1085         { GTK_PRINT_CAPABILITY_SCALE, "GTK_PRINT_CAPABILITY_SCALE", "scale" },
1086         { GTK_PRINT_CAPABILITY_GENERATE_PDF, "GTK_PRINT_CAPABILITY_GENERATE_PDF", "generate-pdf" },
1087         { GTK_PRINT_CAPABILITY_GENERATE_PS, "GTK_PRINT_CAPABILITY_GENERATE_PS", "generate-ps" },
1088         { GTK_PRINT_CAPABILITY_PREVIEW, "GTK_PRINT_CAPABILITY_PREVIEW", "preview" },
1089         { GTK_PRINT_CAPABILITY_NUMBER_UP, "GTK_PRINT_CAPABILITY_NUMBER_UP", "number-up"},
1090         { 0, NULL, NULL }
1091       };
1092
1093       etype = g_flags_register_static (I_("GtkPrintCapabilities"), values);
1094     }
1095
1096   return etype;
1097 }
1098
1099
1100 #define __GTK_PRINTER_C__
1101 #include "gtkaliasdef.c"