]> Pileus Git - ~andy/gtk/blob - gtk/gtkprinter.c
cleanup
[~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 gboolean
586 _gtk_printer_has_details (GtkPrinter *printer)
587 {
588   return printer->priv->has_details;
589 }
590
591 void
592 gtk_printer_set_has_details (GtkPrinter *printer,
593                              gboolean val)
594 {
595   printer->priv->has_details = val;
596 }
597
598 /**
599  * gtk_printer_is_active:
600  * @printer: a #GtkPrinter
601  * 
602  * Returns whether the printer is currently active (i.e. 
603  * accepts new jobs).
604  * 
605  * Return value: %TRUE if @printer is active
606  *
607  * Since: 2.10
608  */
609 gboolean
610 gtk_printer_is_active (GtkPrinter *printer)
611 {
612   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
613   
614   return printer->priv->is_active;
615 }
616
617 void
618 gtk_printer_set_is_active (GtkPrinter *printer,
619                            gboolean val)
620 {
621   g_return_if_fail (GTK_IS_PRINTER (printer));
622
623   printer->priv->is_active = val;
624 }
625
626
627 /**
628  * gtk_printer_is_virtual:
629  * @printer: a #GtkPrinter
630  * 
631  * Returns whether the printer is virtual (i.e. does not
632  * represent actual printer hardware, but something like 
633  * a CUPS class).
634  * 
635  * Return value: %TRUE if @printer is virtual
636  *
637  * Since: 2.10
638  */
639 gboolean
640 gtk_printer_is_virtual (GtkPrinter *printer)
641 {
642   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
643   
644   return printer->priv->is_virtual;
645 }
646
647 gboolean 
648 gtk_printer_accepts_pdf (GtkPrinter *printer)
649
650   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
651   
652   return printer->priv->accepts_pdf;
653 }
654
655 gboolean 
656 gtk_printer_accepts_ps (GtkPrinter *printer)
657
658   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
659   
660   return printer->priv->accepts_ps;
661 }
662
663 gboolean
664 gtk_printer_is_new (GtkPrinter *printer)
665 {
666   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
667   
668   return printer->priv->is_new;
669 }
670
671 void
672 gtk_printer_set_is_new (GtkPrinter *printer,
673                         gboolean val)
674 {
675   g_return_if_fail (GTK_IS_PRINTER (printer));
676
677   printer->priv->is_new = val;
678 }
679
680
681 /**
682  * gtk_printer_is_default:
683  * @printer: a #GtkPrinter
684  * 
685  * Returns whether the printer is the default printer.
686  * 
687  * Return value: %TRUE if @printer is the default
688  *
689  * Since: 2.10
690  */
691 gboolean
692 gtk_printer_is_default (GtkPrinter *printer)
693 {
694   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
695   
696   return printer->priv->is_default;
697 }
698
699 void
700 gtk_printer_set_is_default (GtkPrinter *printer,
701                             gboolean    val)
702 {
703   g_return_if_fail (GTK_IS_PRINTER (printer));
704
705   printer->priv->is_default = TRUE;
706 }
707
708 void
709 _gtk_printer_request_details (GtkPrinter *printer)
710 {
711   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
712   backend_class->printer_request_details (printer);
713 }
714
715 GtkPrinterOptionSet *
716 _gtk_printer_get_options (GtkPrinter           *printer,
717                           GtkPrintSettings     *settings,
718                           GtkPageSetup         *page_setup,
719                           GtkPrintCapabilities  capabilities)
720 {
721   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
722   return backend_class->printer_get_options (printer, settings, page_setup, capabilities);
723 }
724
725 gboolean
726 _gtk_printer_mark_conflicts (GtkPrinter          *printer,
727                              GtkPrinterOptionSet *options)
728 {
729   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
730   return backend_class->printer_mark_conflicts (printer, options);
731 }
732   
733 void
734 _gtk_printer_get_settings_from_options (GtkPrinter          *printer,
735                                         GtkPrinterOptionSet *options,
736                                         GtkPrintSettings    *settings)
737 {
738   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
739   backend_class->printer_get_settings_from_options (printer, options, settings);
740 }
741
742 void
743 _gtk_printer_prepare_for_print (GtkPrinter       *printer,
744                                 GtkPrintJob      *print_job,
745                                 GtkPrintSettings *settings,
746                                 GtkPageSetup     *page_setup)
747 {
748   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
749   backend_class->printer_prepare_for_print (printer, print_job, settings, page_setup);
750 }
751
752 cairo_surface_t *
753 _gtk_printer_create_cairo_surface (GtkPrinter       *printer,
754                                    GtkPrintSettings *settings,
755                                    gdouble           width, 
756                                    gdouble           height,
757                                    gint              cache_fd)
758 {
759   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
760
761   return backend_class->printer_create_cairo_surface (printer, settings,
762                                                       width, height, cache_fd);
763 }
764
765 GList  *
766 _gtk_printer_list_papers (GtkPrinter *printer)
767 {
768   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
769
770   return backend_class->printer_list_papers (printer);
771 }
772
773 void
774 _gtk_printer_get_hard_margins (GtkPrinter *printer,
775                                gdouble    *top,
776                                gdouble    *bottom,
777                                gdouble    *left,
778                                gdouble    *right)
779 {
780   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
781
782   backend_class->printer_get_hard_margins (printer, top, bottom, left, right);
783 }
784
785 GtkPrintCapabilities
786 _gtk_printer_get_capabilities (GtkPrinter *printer)
787 {
788   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
789
790   return backend_class->printer_get_capabilities (printer);
791 }
792
793 gint
794 gtk_printer_compare (GtkPrinter *a, GtkPrinter *b)
795 {
796   const char *name_a, *name_b;
797   
798   g_assert (GTK_IS_PRINTER (a) && GTK_IS_PRINTER (b));
799   
800   name_a = gtk_printer_get_name (a);
801   name_b = gtk_printer_get_name (b);
802   if (name_a == NULL  && name_b == NULL)
803     return 0;
804   else if (name_a == NULL)
805     return G_MAXINT;
806   else if (name_b == NULL)
807     return G_MININT;
808   else
809     return g_ascii_strcasecmp (name_a, name_b);
810 }
811
812
813 typedef struct 
814 {
815   GList *backends;
816   GtkPrinterFunc func;
817   gpointer data;
818   GDestroyNotify destroy;
819   GMainLoop *loop;
820 } PrinterList;
821
822 static void list_done_cb (GtkPrintBackend *backend, 
823                           PrinterList     *printer_list);
824
825 static void
826 stop_enumeration (PrinterList *printer_list)
827 {
828   GList *list, *next;
829   GtkPrintBackend *backend;
830
831   for (list = printer_list->backends; list; list = next)
832     {
833       next = list->next;
834       backend = GTK_PRINT_BACKEND (list->data);
835       list_done_cb (backend, printer_list);
836     }
837
838   if (printer_list->destroy)
839     printer_list->destroy (printer_list->data);
840
841   if (printer_list->loop)
842     {    
843       g_main_loop_quit (printer_list->loop);
844
845       g_main_loop_unref (printer_list->loop);
846     }
847
848   g_free (printer_list);
849 }
850
851 static void
852 list_added_cb (GtkPrintBackend *backend, 
853                GtkPrinter      *printer, 
854                PrinterList     *printer_list)
855 {
856   if (printer_list->func (printer, printer_list->data))
857     stop_enumeration (printer_list);
858 }
859
860 static void
861 list_done_cb (GtkPrintBackend *backend, 
862               PrinterList     *printer_list)
863 {
864   printer_list->backends = g_list_remove (printer_list->backends, backend);
865   
866   g_signal_handlers_disconnect_by_func (backend, list_added_cb, printer_list);
867   g_signal_handlers_disconnect_by_func (backend, list_done_cb, printer_list);
868   
869   gtk_print_backend_destroy (backend);
870   g_object_unref (backend);
871
872   if (printer_list->backends == NULL)
873     stop_enumeration (printer_list);
874 }
875
876 static void
877 list_printers_init (PrinterList     *printer_list,
878                     GtkPrintBackend *backend)
879 {
880   GList *list;
881   GList *node;
882
883   list = gtk_print_backend_get_printer_list (backend);
884
885   for (node = list; node != NULL; node = node->next)
886     list_added_cb (backend, node->data, printer_list);
887
888   g_list_free (list);
889
890   if (gtk_print_backend_printer_list_is_done (backend))
891     {
892       printer_list->backends = g_list_remove (printer_list->backends, backend);
893       gtk_print_backend_destroy (backend);
894       g_object_unref (backend);
895     }
896   else
897     {
898       g_signal_connect (backend, "printer-added", 
899                         (GCallback) list_added_cb, 
900                         printer_list);
901       g_signal_connect (backend, "printer-list-done", 
902                         (GCallback) list_done_cb, 
903                         printer_list);
904     }
905
906 }
907
908 /**
909  * gtk_enumerate_printers:
910  * @func: a function to call for each printer
911  * @data: user data to pass to @func
912  * @destroy: function to call if @data is no longer needed
913  * @wait: if %TRUE, wait in a recursive mainloop until
914  *    all printers are enumerated; otherwise return early
915  *
916  * Calls a function for all #GtkPrinter<!-- -->s. If @func
917  * returns %TRUE, the enumeration is stopped.
918  *
919  * Since: 2.10
920  */
921 void
922 gtk_enumerate_printers (GtkPrinterFunc func,
923                         gpointer       data,
924                         GDestroyNotify destroy,
925                         gboolean       wait)
926 {
927   PrinterList *printer_list;
928   GList *node, *next;
929   GtkPrintBackend *backend;
930
931   printer_list = g_new0 (PrinterList, 1);
932
933   printer_list->func = func;
934   printer_list->data = data;
935   printer_list->destroy = destroy;
936
937   if (g_module_supported ())
938     printer_list->backends = gtk_print_backend_load_modules ();
939
940   for (node = printer_list->backends; node != NULL; node = next)
941     {
942       next = node->next;
943       backend = GTK_PRINT_BACKEND (node->data);
944       list_printers_init (printer_list, backend);
945     }
946
947   if (wait && printer_list->backends)
948     {
949       printer_list->loop = g_main_loop_new (NULL, FALSE);
950
951       GDK_THREADS_LEAVE ();  
952       g_main_loop_run (printer_list->loop);
953       GDK_THREADS_ENTER ();  
954     }
955 }
956
957
958 #define __GTK_PRINTER_C__
959 #include "gtkaliasdef.c"