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, see <http://www.gnu.org/licenses/>.
16  */
17 
18 #include "config.h"
19 #include <stdlib.h>
20 #include <string.h>
21 #include <stdio.h>
22 
23 #include "gtkintl.h"
24 #include "gtkprivate.h"
25 
26 #include "gtkprinter.h"
27 #include "gtkprinter-private.h"
28 #include "gtkprintbackend.h"
29 #include "gtkprintjob.h"
30 
31 /**
32  * SECTION:gtkprinter
33  * @Short_description: Represents a printer
34  * @Title: GtkPrinter
35  *
36  * A #GtkPrinter object represents a printer. You only need to
37  * deal directly with printers if you use the non-portable
38  * #GtkPrintUnixDialog API.
39  *
40  * A #GtkPrinter allows to get status information about the printer,
41  * such as its description, its location, the number of queued jobs,
42  * etc. Most importantly, a #GtkPrinter object can be used to create
43  * a #GtkPrintJob object, which lets you print to the printer.
44  *
45  * Printing support was added in GTK+ 2.10.
46  */
47 
48 
49 static void gtk_printer_finalize     (GObject *object);
50 
51 struct _GtkPrinterPrivate
52 {
53   gchar *name;
54   gchar *location;
55   gchar *description;
56   gchar *icon_name;
57 
58   guint is_active         : 1;
59   guint is_paused         : 1;
60   guint is_accepting_jobs : 1;
61   guint is_new            : 1;
62   guint is_virtual        : 1;
63   guint is_default        : 1;
64   guint has_details       : 1;
65   guint accepts_pdf       : 1;
66   guint accepts_ps        : 1;
67 
68   gchar *state_message;
69   gint job_count;
70 
71   GtkPrintBackend *backend;
72 };
73 
74 enum {
75   DETAILS_ACQUIRED,
76   LAST_SIGNAL
77 };
78 
79 enum {
80   PROP_0,
81   PROP_NAME,
82   PROP_BACKEND,
83   PROP_IS_VIRTUAL,
84   PROP_STATE_MESSAGE,
85   PROP_LOCATION,
86   PROP_ICON_NAME,
87   PROP_JOB_COUNT,
88   PROP_ACCEPTS_PDF,
89   PROP_ACCEPTS_PS,
90   PROP_PAUSED,
91   PROP_ACCEPTING_JOBS
92 };
93 
94 static guint signals[LAST_SIGNAL] = { 0 };
95 
96 static void gtk_printer_set_property (GObject      *object,
97 				      guint         prop_id,
98 				      const GValue *value,
99 				      GParamSpec   *pspec);
100 static void gtk_printer_get_property (GObject      *object,
101 				      guint         prop_id,
102 				      GValue       *value,
103 				      GParamSpec   *pspec);
104 
G_DEFINE_TYPE_WITH_PRIVATE(GtkPrinter,gtk_printer,G_TYPE_OBJECT)105 G_DEFINE_TYPE_WITH_PRIVATE (GtkPrinter, gtk_printer, G_TYPE_OBJECT)
106 
107 static void
108 gtk_printer_class_init (GtkPrinterClass *class)
109 {
110   GObjectClass *object_class;
111   object_class = (GObjectClass *) class;
112 
113   object_class->finalize = gtk_printer_finalize;
114 
115   object_class->set_property = gtk_printer_set_property;
116   object_class->get_property = gtk_printer_get_property;
117 
118   g_object_class_install_property (G_OBJECT_CLASS (class),
119                                    PROP_NAME,
120                                    g_param_spec_string ("name",
121 						        P_("Name"),
122 						        P_("Name of the printer"),
123 						        "",
124 							GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
125   g_object_class_install_property (G_OBJECT_CLASS (class),
126                                    PROP_BACKEND,
127                                    g_param_spec_object ("backend",
128 						        P_("Backend"),
129 						        P_("Backend for the printer"),
130 						        GTK_TYPE_PRINT_BACKEND,
131 							GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
132   g_object_class_install_property (G_OBJECT_CLASS (class),
133                                    PROP_IS_VIRTUAL,
134                                    g_param_spec_boolean ("is-virtual",
135 							 P_("Is Virtual"),
136 							 P_("FALSE if this represents a real hardware printer"),
137 							 FALSE,
138 							 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
139   g_object_class_install_property (G_OBJECT_CLASS (class),
140                                    PROP_ACCEPTS_PDF,
141                                    g_param_spec_boolean ("accepts-pdf",
142 							 P_("Accepts PDF"),
143 							 P_("TRUE if this printer can accept PDF"),
144 							 FALSE,
145 							 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
146   g_object_class_install_property (G_OBJECT_CLASS (class),
147                                    PROP_ACCEPTS_PS,
148                                    g_param_spec_boolean ("accepts-ps",
149 							 P_("Accepts PostScript"),
150 							 P_("TRUE if this printer can accept PostScript"),
151 							 TRUE,
152 							 GTK_PARAM_READWRITE | G_PARAM_CONSTRUCT_ONLY));
153   g_object_class_install_property (G_OBJECT_CLASS (class),
154                                    PROP_STATE_MESSAGE,
155                                    g_param_spec_string ("state-message",
156 						        P_("State Message"),
157 						        P_("String giving the current state of the printer"),
158 						        "",
159 							GTK_PARAM_READABLE));
160   g_object_class_install_property (G_OBJECT_CLASS (class),
161                                    PROP_LOCATION,
162                                    g_param_spec_string ("location",
163 						        P_("Location"),
164 						        P_("The location of the printer"),
165 						        "",
166 							GTK_PARAM_READABLE));
167   g_object_class_install_property (G_OBJECT_CLASS (class),
168                                    PROP_ICON_NAME,
169                                    g_param_spec_string ("icon-name",
170 						        P_("Icon Name"),
171 						        P_("The icon name to use for the printer"),
172 						        "",
173 							GTK_PARAM_READABLE));
174   g_object_class_install_property (G_OBJECT_CLASS (class),
175                                    PROP_JOB_COUNT,
176 				   g_param_spec_int ("job-count",
177  						     P_("Job Count"),
178  						     P_("Number of jobs queued in the printer"),
179  						     0,
180  						     G_MAXINT,
181  						     0,
182  						     GTK_PARAM_READABLE));
183 
184   /**
185    * GtkPrinter:paused:
186    *
187    * This property is %TRUE if this printer is paused.
188    * A paused printer still accepts jobs, but it does
189    * not print them.
190    *
191    * Since: 2.14
192    */
193   g_object_class_install_property (G_OBJECT_CLASS (class),
194                                    PROP_PAUSED,
195                                    g_param_spec_boolean ("paused",
196 							 P_("Paused Printer"),
197 							 P_("TRUE if this printer is paused"),
198 							 FALSE,
199 							 GTK_PARAM_READABLE));
200   /**
201    * GtkPrinter:accepting-jobs:
202    *
203    * This property is %TRUE if the printer is accepting jobs.
204    *
205    * Since: 2.14
206    */
207   g_object_class_install_property (G_OBJECT_CLASS (class),
208                                    PROP_ACCEPTING_JOBS,
209                                    g_param_spec_boolean ("accepting-jobs",
210 							 P_("Accepting Jobs"),
211 							 P_("TRUE if this printer is accepting new jobs"),
212 							 TRUE,
213 							 GTK_PARAM_READABLE));
214 
215   /**
216    * GtkPrinter::details-acquired:
217    * @printer: the #GtkPrinter on which the signal is emitted
218    * @success: %TRUE if the details were successfully acquired
219    *
220    * Gets emitted in response to a request for detailed information
221    * about a printer from the print backend. The @success parameter
222    * indicates if the information was actually obtained.
223    *
224    * Since: 2.10
225    */
226   signals[DETAILS_ACQUIRED] =
227     g_signal_new (I_("details-acquired"),
228 		  G_TYPE_FROM_CLASS (class),
229 		  G_SIGNAL_RUN_LAST,
230 		  G_STRUCT_OFFSET (GtkPrinterClass, details_acquired),
231 		  NULL, NULL,
232 		  NULL,
233 		  G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
234 }
235 
236 static void
gtk_printer_init(GtkPrinter * printer)237 gtk_printer_init (GtkPrinter *printer)
238 {
239   GtkPrinterPrivate *priv;
240 
241   priv = printer->priv = gtk_printer_get_instance_private (printer);
242 
243   priv->name = NULL;
244   priv->location = NULL;
245   priv->description = NULL;
246   priv->icon_name = g_strdup ("printer");
247 
248   priv->is_active = TRUE;
249   priv->is_paused = FALSE;
250   priv->is_accepting_jobs = TRUE;
251   priv->is_new = TRUE;
252   priv->has_details = FALSE;
253   priv->accepts_pdf = FALSE;
254   priv->accepts_ps = TRUE;
255 
256   priv->state_message = NULL;
257   priv->job_count = 0;
258 }
259 
260 static void
gtk_printer_finalize(GObject * object)261 gtk_printer_finalize (GObject *object)
262 {
263   GtkPrinter *printer = GTK_PRINTER (object);
264   GtkPrinterPrivate *priv = printer->priv;
265 
266   g_free (priv->name);
267   g_free (priv->location);
268   g_free (priv->description);
269   g_free (priv->state_message);
270   g_free (priv->icon_name);
271 
272   if (priv->backend)
273     g_object_unref (priv->backend);
274 
275   G_OBJECT_CLASS (gtk_printer_parent_class)->finalize (object);
276 }
277 
278 static void
gtk_printer_set_property(GObject * object,guint prop_id,const GValue * value,GParamSpec * pspec)279 gtk_printer_set_property (GObject         *object,
280 			  guint            prop_id,
281 			  const GValue    *value,
282 			  GParamSpec      *pspec)
283 {
284   GtkPrinter *printer = GTK_PRINTER (object);
285   GtkPrinterPrivate *priv = printer->priv;
286 
287   switch (prop_id)
288     {
289     case PROP_NAME:
290       priv->name = g_value_dup_string (value);
291       break;
292 
293     case PROP_BACKEND:
294       priv->backend = GTK_PRINT_BACKEND (g_value_dup_object (value));
295       break;
296 
297     case PROP_IS_VIRTUAL:
298       priv->is_virtual = g_value_get_boolean (value);
299       break;
300 
301     case PROP_ACCEPTS_PDF:
302       priv->accepts_pdf = g_value_get_boolean (value);
303       break;
304 
305     case PROP_ACCEPTS_PS:
306       priv->accepts_ps = g_value_get_boolean (value);
307       break;
308 
309     default:
310       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
311       break;
312     }
313 }
314 
315 static void
gtk_printer_get_property(GObject * object,guint prop_id,GValue * value,GParamSpec * pspec)316 gtk_printer_get_property (GObject    *object,
317 			  guint       prop_id,
318 			  GValue     *value,
319 			  GParamSpec *pspec)
320 {
321   GtkPrinter *printer = GTK_PRINTER (object);
322   GtkPrinterPrivate *priv = printer->priv;
323 
324   switch (prop_id)
325     {
326     case PROP_NAME:
327       if (priv->name)
328 	g_value_set_string (value, priv->name);
329       else
330 	g_value_set_static_string (value, "");
331       break;
332     case PROP_BACKEND:
333       g_value_set_object (value, priv->backend);
334       break;
335     case PROP_STATE_MESSAGE:
336       if (priv->state_message)
337 	g_value_set_string (value, priv->state_message);
338       else
339 	g_value_set_static_string (value, "");
340       break;
341     case PROP_LOCATION:
342       if (priv->location)
343 	g_value_set_string (value, priv->location);
344       else
345 	g_value_set_static_string (value, "");
346       break;
347     case PROP_ICON_NAME:
348       if (priv->icon_name)
349 	g_value_set_string (value, priv->icon_name);
350       else
351 	g_value_set_static_string (value, "");
352       break;
353     case PROP_JOB_COUNT:
354       g_value_set_int (value, priv->job_count);
355       break;
356     case PROP_IS_VIRTUAL:
357       g_value_set_boolean (value, priv->is_virtual);
358       break;
359     case PROP_ACCEPTS_PDF:
360       g_value_set_boolean (value, priv->accepts_pdf);
361       break;
362     case PROP_ACCEPTS_PS:
363       g_value_set_boolean (value, priv->accepts_ps);
364       break;
365     case PROP_PAUSED:
366       g_value_set_boolean (value, priv->is_paused);
367       break;
368     case PROP_ACCEPTING_JOBS:
369       g_value_set_boolean (value, priv->is_accepting_jobs);
370       break;
371     default:
372       G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
373       break;
374     }
375 }
376 
377 /**
378  * gtk_printer_new:
379  * @name: the name of the printer
380  * @backend: a #GtkPrintBackend
381  * @virtual_: whether the printer is virtual
382  *
383  * Creates a new #GtkPrinter.
384  *
385  * Returns: a new #GtkPrinter
386  *
387  * Since: 2.10
388  **/
389 GtkPrinter *
gtk_printer_new(const gchar * name,GtkPrintBackend * backend,gboolean virtual_)390 gtk_printer_new (const gchar     *name,
391 		 GtkPrintBackend *backend,
392 		 gboolean         virtual_)
393 {
394   GObject *result;
395 
396   result = g_object_new (GTK_TYPE_PRINTER,
397 			 "name", name,
398 			 "backend", backend,
399 			 "is-virtual", virtual_,
400                          NULL);
401 
402   return (GtkPrinter *) result;
403 }
404 
405 /**
406  * gtk_printer_get_backend:
407  * @printer: a #GtkPrinter
408  *
409  * Returns the backend of the printer.
410  *
411  * Returns: (transfer none): the backend of @printer
412  *
413  * Since: 2.10
414  */
415 GtkPrintBackend *
gtk_printer_get_backend(GtkPrinter * printer)416 gtk_printer_get_backend (GtkPrinter *printer)
417 {
418   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
419 
420   return printer->priv->backend;
421 }
422 
423 /**
424  * gtk_printer_get_name:
425  * @printer: a #GtkPrinter
426  *
427  * Returns the name of the printer.
428  *
429  * Returns: the name of @printer
430  *
431  * Since: 2.10
432  */
433 const gchar *
gtk_printer_get_name(GtkPrinter * printer)434 gtk_printer_get_name (GtkPrinter *printer)
435 {
436   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
437 
438   return printer->priv->name;
439 }
440 
441 /**
442  * gtk_printer_get_description:
443  * @printer: a #GtkPrinter
444  *
445  * Gets the description of the printer.
446  *
447  * Returns: the description of @printer
448  *
449  * Since: 2.10
450  */
451 const gchar *
gtk_printer_get_description(GtkPrinter * printer)452 gtk_printer_get_description (GtkPrinter *printer)
453 {
454   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
455 
456   return printer->priv->description;
457 }
458 
459 gboolean
gtk_printer_set_description(GtkPrinter * printer,const gchar * description)460 gtk_printer_set_description (GtkPrinter  *printer,
461 			     const gchar *description)
462 {
463   GtkPrinterPrivate *priv;
464 
465   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
466 
467   priv = printer->priv;
468 
469   if (g_strcmp0 (priv->description, description) == 0)
470     return FALSE;
471 
472   g_free (priv->description);
473   priv->description = g_strdup (description);
474 
475   return TRUE;
476 }
477 
478 /**
479  * gtk_printer_get_state_message:
480  * @printer: a #GtkPrinter
481  *
482  * Returns the state message describing the current state
483  * of the printer.
484  *
485  * Returns: the state message of @printer
486  *
487  * Since: 2.10
488  */
489 const gchar *
gtk_printer_get_state_message(GtkPrinter * printer)490 gtk_printer_get_state_message (GtkPrinter *printer)
491 {
492   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
493 
494   return printer->priv->state_message;
495 }
496 
497 gboolean
gtk_printer_set_state_message(GtkPrinter * printer,const gchar * message)498 gtk_printer_set_state_message (GtkPrinter  *printer,
499 			       const gchar *message)
500 {
501   GtkPrinterPrivate *priv;
502 
503   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
504 
505   priv = printer->priv;
506 
507   if (g_strcmp0 (priv->state_message, message) == 0)
508     return FALSE;
509 
510   g_free (priv->state_message);
511   priv->state_message = g_strdup (message);
512   g_object_notify (G_OBJECT (printer), "state-message");
513 
514   return TRUE;
515 }
516 
517 /**
518  * gtk_printer_get_location:
519  * @printer: a #GtkPrinter
520  *
521  * Returns a description of the location of the printer.
522  *
523  * Returns: the location of @printer
524  *
525  * Since: 2.10
526  */
527 const gchar *
gtk_printer_get_location(GtkPrinter * printer)528 gtk_printer_get_location (GtkPrinter *printer)
529 {
530   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
531 
532   return printer->priv->location;
533 }
534 
535 gboolean
gtk_printer_set_location(GtkPrinter * printer,const gchar * location)536 gtk_printer_set_location (GtkPrinter  *printer,
537 			  const gchar *location)
538 {
539   GtkPrinterPrivate *priv;
540 
541   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
542 
543   priv = printer->priv;
544 
545   if (g_strcmp0 (priv->location, location) == 0)
546     return FALSE;
547 
548   g_free (priv->location);
549   priv->location = g_strdup (location);
550   g_object_notify (G_OBJECT (printer), "location");
551 
552   return TRUE;
553 }
554 
555 /**
556  * gtk_printer_get_icon_name:
557  * @printer: a #GtkPrinter
558  *
559  * Gets the name of the icon to use for the printer.
560  *
561  * Returns: the icon name for @printer
562  *
563  * Since: 2.10
564  */
565 const gchar *
gtk_printer_get_icon_name(GtkPrinter * printer)566 gtk_printer_get_icon_name (GtkPrinter *printer)
567 {
568   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
569 
570   return printer->priv->icon_name;
571 }
572 
573 void
gtk_printer_set_icon_name(GtkPrinter * printer,const gchar * icon)574 gtk_printer_set_icon_name (GtkPrinter  *printer,
575 			   const gchar *icon)
576 {
577   GtkPrinterPrivate *priv;
578 
579   g_return_if_fail (GTK_IS_PRINTER (printer));
580 
581   priv = printer->priv;
582 
583   g_free (priv->icon_name);
584   priv->icon_name = g_strdup (icon);
585   g_object_notify (G_OBJECT (printer), "icon-name");
586 }
587 
588 /**
589  * gtk_printer_get_job_count:
590  * @printer: a #GtkPrinter
591  *
592  * Gets the number of jobs currently queued on the printer.
593  *
594  * Returns: the number of jobs on @printer
595  *
596  * Since: 2.10
597  */
598 gint
gtk_printer_get_job_count(GtkPrinter * printer)599 gtk_printer_get_job_count (GtkPrinter *printer)
600 {
601   g_return_val_if_fail (GTK_IS_PRINTER (printer), 0);
602 
603   return printer->priv->job_count;
604 }
605 
606 gboolean
gtk_printer_set_job_count(GtkPrinter * printer,gint count)607 gtk_printer_set_job_count (GtkPrinter *printer,
608 			   gint        count)
609 {
610   GtkPrinterPrivate *priv;
611 
612   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
613 
614   priv = printer->priv;
615 
616   if (priv->job_count == count)
617     return FALSE;
618 
619   priv->job_count = count;
620 
621   g_object_notify (G_OBJECT (printer), "job-count");
622 
623   return TRUE;
624 }
625 
626 /**
627  * gtk_printer_has_details:
628  * @printer: a #GtkPrinter
629  *
630  * Returns whether the printer details are available.
631  *
632  * Returns: %TRUE if @printer details are available
633  *
634  * Since: 2.12
635  */
636 gboolean
gtk_printer_has_details(GtkPrinter * printer)637 gtk_printer_has_details (GtkPrinter *printer)
638 {
639   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
640 
641   return printer->priv->has_details;
642 }
643 
644 void
gtk_printer_set_has_details(GtkPrinter * printer,gboolean val)645 gtk_printer_set_has_details (GtkPrinter *printer,
646 			     gboolean val)
647 {
648   printer->priv->has_details = val;
649 }
650 
651 /**
652  * gtk_printer_is_active:
653  * @printer: a #GtkPrinter
654  *
655  * Returns whether the printer is currently active (i.e.
656  * accepts new jobs).
657  *
658  * Returns: %TRUE if @printer is active
659  *
660  * Since: 2.10
661  */
662 gboolean
gtk_printer_is_active(GtkPrinter * printer)663 gtk_printer_is_active (GtkPrinter *printer)
664 {
665   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
666 
667   return printer->priv->is_active;
668 }
669 
670 void
gtk_printer_set_is_active(GtkPrinter * printer,gboolean val)671 gtk_printer_set_is_active (GtkPrinter *printer,
672 			   gboolean val)
673 {
674   g_return_if_fail (GTK_IS_PRINTER (printer));
675 
676   printer->priv->is_active = val;
677 }
678 
679 /**
680  * gtk_printer_is_paused:
681  * @printer: a #GtkPrinter
682  *
683  * Returns whether the printer is currently paused.
684  * A paused printer still accepts jobs, but it is not
685  * printing them.
686  *
687  * Returns: %TRUE if @printer is paused
688  *
689  * Since: 2.14
690  */
691 gboolean
gtk_printer_is_paused(GtkPrinter * printer)692 gtk_printer_is_paused (GtkPrinter *printer)
693 {
694   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
695 
696   return printer->priv->is_paused;
697 }
698 
699 gboolean
gtk_printer_set_is_paused(GtkPrinter * printer,gboolean val)700 gtk_printer_set_is_paused (GtkPrinter *printer,
701 			   gboolean    val)
702 {
703   GtkPrinterPrivate *priv;
704 
705   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
706 
707   priv = printer->priv;
708 
709   if (val == priv->is_paused)
710     return FALSE;
711 
712   priv->is_paused = val;
713 
714   return TRUE;
715 }
716 
717 /**
718  * gtk_printer_is_accepting_jobs:
719  * @printer: a #GtkPrinter
720  *
721  * Returns whether the printer is accepting jobs
722  *
723  * Returns: %TRUE if @printer is accepting jobs
724  *
725  * Since: 2.14
726  */
727 gboolean
gtk_printer_is_accepting_jobs(GtkPrinter * printer)728 gtk_printer_is_accepting_jobs (GtkPrinter *printer)
729 {
730   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
731 
732   return printer->priv->is_accepting_jobs;
733 }
734 
735 gboolean
gtk_printer_set_is_accepting_jobs(GtkPrinter * printer,gboolean val)736 gtk_printer_set_is_accepting_jobs (GtkPrinter *printer,
737 				   gboolean val)
738 {
739   GtkPrinterPrivate *priv;
740 
741   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
742 
743   priv = printer->priv;
744 
745   if (val == priv->is_accepting_jobs)
746     return FALSE;
747 
748   priv->is_accepting_jobs = val;
749 
750   return TRUE;
751 }
752 
753 /**
754  * gtk_printer_is_virtual:
755  * @printer: a #GtkPrinter
756  *
757  * Returns whether the printer is virtual (i.e. does not
758  * represent actual printer hardware, but something like
759  * a CUPS class).
760  *
761  * Returns: %TRUE if @printer is virtual
762  *
763  * Since: 2.10
764  */
765 gboolean
gtk_printer_is_virtual(GtkPrinter * printer)766 gtk_printer_is_virtual (GtkPrinter *printer)
767 {
768   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
769 
770   return printer->priv->is_virtual;
771 }
772 
773 /**
774  * gtk_printer_accepts_pdf:
775  * @printer: a #GtkPrinter
776  *
777  * Returns whether the printer accepts input in
778  * PDF format.
779  *
780  * Returns: %TRUE if @printer accepts PDF
781  *
782  * Since: 2.10
783  */
784 gboolean
gtk_printer_accepts_pdf(GtkPrinter * printer)785 gtk_printer_accepts_pdf (GtkPrinter *printer)
786 {
787   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
788 
789   return printer->priv->accepts_pdf;
790 }
791 
792 void
gtk_printer_set_accepts_pdf(GtkPrinter * printer,gboolean val)793 gtk_printer_set_accepts_pdf (GtkPrinter *printer,
794 			     gboolean val)
795 {
796   g_return_if_fail (GTK_IS_PRINTER (printer));
797 
798   printer->priv->accepts_pdf = val;
799 }
800 
801 /**
802  * gtk_printer_accepts_ps:
803  * @printer: a #GtkPrinter
804  *
805  * Returns whether the printer accepts input in
806  * PostScript format.
807  *
808  * Returns: %TRUE if @printer accepts PostScript
809  *
810  * Since: 2.10
811  */
812 gboolean
gtk_printer_accepts_ps(GtkPrinter * printer)813 gtk_printer_accepts_ps (GtkPrinter *printer)
814 {
815   g_return_val_if_fail (GTK_IS_PRINTER (printer), TRUE);
816 
817   return printer->priv->accepts_ps;
818 }
819 
820 void
gtk_printer_set_accepts_ps(GtkPrinter * printer,gboolean val)821 gtk_printer_set_accepts_ps (GtkPrinter *printer,
822 			    gboolean val)
823 {
824   g_return_if_fail (GTK_IS_PRINTER (printer));
825 
826   printer->priv->accepts_ps = val;
827 }
828 
829 gboolean
gtk_printer_is_new(GtkPrinter * printer)830 gtk_printer_is_new (GtkPrinter *printer)
831 {
832   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
833 
834   return printer->priv->is_new;
835 }
836 
837 void
gtk_printer_set_is_new(GtkPrinter * printer,gboolean val)838 gtk_printer_set_is_new (GtkPrinter *printer,
839 			gboolean val)
840 {
841   g_return_if_fail (GTK_IS_PRINTER (printer));
842 
843   printer->priv->is_new = val;
844 }
845 
846 
847 /**
848  * gtk_printer_is_default:
849  * @printer: a #GtkPrinter
850  *
851  * Returns whether the printer is the default printer.
852  *
853  * Returns: %TRUE if @printer is the default
854  *
855  * Since: 2.10
856  */
857 gboolean
gtk_printer_is_default(GtkPrinter * printer)858 gtk_printer_is_default (GtkPrinter *printer)
859 {
860   g_return_val_if_fail (GTK_IS_PRINTER (printer), FALSE);
861 
862   return printer->priv->is_default;
863 }
864 
865 void
gtk_printer_set_is_default(GtkPrinter * printer,gboolean val)866 gtk_printer_set_is_default (GtkPrinter *printer,
867 			    gboolean    val)
868 {
869   g_return_if_fail (GTK_IS_PRINTER (printer));
870 
871   printer->priv->is_default = val;
872 }
873 
874 /**
875  * gtk_printer_request_details:
876  * @printer: a #GtkPrinter
877  *
878  * Requests the printer details. When the details are available,
879  * the #GtkPrinter::details-acquired signal will be emitted on @printer.
880  *
881  * Since: 2.12
882  */
883 void
gtk_printer_request_details(GtkPrinter * printer)884 gtk_printer_request_details (GtkPrinter *printer)
885 {
886   GtkPrintBackendClass *backend_class;
887 
888   g_return_if_fail (GTK_IS_PRINTER (printer));
889 
890   backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
891   backend_class->printer_request_details (printer);
892 }
893 
894 GtkPrinterOptionSet *
_gtk_printer_get_options(GtkPrinter * printer,GtkPrintSettings * settings,GtkPageSetup * page_setup,GtkPrintCapabilities capabilities)895 _gtk_printer_get_options (GtkPrinter           *printer,
896 			  GtkPrintSettings     *settings,
897 			  GtkPageSetup         *page_setup,
898 			  GtkPrintCapabilities  capabilities)
899 {
900   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
901   return backend_class->printer_get_options (printer, settings, page_setup, capabilities);
902 }
903 
904 gboolean
_gtk_printer_mark_conflicts(GtkPrinter * printer,GtkPrinterOptionSet * options)905 _gtk_printer_mark_conflicts (GtkPrinter          *printer,
906 			     GtkPrinterOptionSet *options)
907 {
908   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
909   return backend_class->printer_mark_conflicts (printer, options);
910 }
911 
912 void
_gtk_printer_get_settings_from_options(GtkPrinter * printer,GtkPrinterOptionSet * options,GtkPrintSettings * settings)913 _gtk_printer_get_settings_from_options (GtkPrinter          *printer,
914 					GtkPrinterOptionSet *options,
915 					GtkPrintSettings    *settings)
916 {
917   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
918   backend_class->printer_get_settings_from_options (printer, options, settings);
919 }
920 
921 void
_gtk_printer_prepare_for_print(GtkPrinter * printer,GtkPrintJob * print_job,GtkPrintSettings * settings,GtkPageSetup * page_setup)922 _gtk_printer_prepare_for_print (GtkPrinter       *printer,
923 				GtkPrintJob      *print_job,
924 				GtkPrintSettings *settings,
925 				GtkPageSetup     *page_setup)
926 {
927   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
928   backend_class->printer_prepare_for_print (printer, print_job, settings, page_setup);
929 }
930 
931 cairo_surface_t *
_gtk_printer_create_cairo_surface(GtkPrinter * printer,GtkPrintSettings * settings,gdouble width,gdouble height,GIOChannel * cache_io)932 _gtk_printer_create_cairo_surface (GtkPrinter       *printer,
933 				   GtkPrintSettings *settings,
934 				   gdouble           width,
935 				   gdouble           height,
936 				   GIOChannel       *cache_io)
937 {
938   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
939 
940   return backend_class->printer_create_cairo_surface (printer, settings,
941 						      width, height, cache_io);
942 }
943 
944 gboolean
_gtk_printer_get_hard_margins_for_paper_size(GtkPrinter * printer,GtkPaperSize * paper_size,gdouble * top,gdouble * bottom,gdouble * left,gdouble * right)945 _gtk_printer_get_hard_margins_for_paper_size (GtkPrinter   *printer,
946 					      GtkPaperSize *paper_size,
947 					      gdouble      *top,
948 					      gdouble      *bottom,
949 					      gdouble      *left,
950 					      gdouble      *right)
951 {
952   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
953 
954   return backend_class->printer_get_hard_margins_for_paper_size (printer, paper_size, top, bottom, left, right);
955 }
956 
957 /**
958  * gtk_printer_list_papers:
959  * @printer: a #GtkPrinter
960  *
961  * Lists all the paper sizes @printer supports.
962  * This will return and empty list unless the printer’s details are
963  * available, see gtk_printer_has_details() and gtk_printer_request_details().
964  *
965  * Returns: (element-type GtkPageSetup) (transfer full): a newly allocated list of newly allocated #GtkPageSetup s.
966  *
967  * Since: 2.12
968  */
969 GList  *
gtk_printer_list_papers(GtkPrinter * printer)970 gtk_printer_list_papers (GtkPrinter *printer)
971 {
972   GtkPrintBackendClass *backend_class;
973 
974   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
975 
976   backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
977   return backend_class->printer_list_papers (printer);
978 }
979 
980 /**
981  * gtk_printer_get_default_page_size:
982  * @printer: a #GtkPrinter
983  *
984  * Returns default page size of @printer.
985  *
986  * Returns: a newly allocated #GtkPageSetup with default page size of the printer.
987  *
988  * Since: 2.14
989  */
990 GtkPageSetup  *
gtk_printer_get_default_page_size(GtkPrinter * printer)991 gtk_printer_get_default_page_size (GtkPrinter *printer)
992 {
993   GtkPrintBackendClass *backend_class;
994 
995   g_return_val_if_fail (GTK_IS_PRINTER (printer), NULL);
996 
997   backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
998   return backend_class->printer_get_default_page_size (printer);
999 }
1000 
1001 /**
1002  * gtk_printer_get_hard_margins:
1003  * @printer: a #GtkPrinter
1004  * @top: (out): a location to store the top margin in
1005  * @bottom: (out): a location to store the bottom margin in
1006  * @left: (out): a location to store the left margin in
1007  * @right: (out): a location to store the right margin in
1008  *
1009  * Retrieve the hard margins of @printer, i.e. the margins that define
1010  * the area at the borders of the paper that the printer cannot print to.
1011  *
1012  * Note: This will not succeed unless the printer’s details are available,
1013  * see gtk_printer_has_details() and gtk_printer_request_details().
1014  *
1015  * Returns: %TRUE iff the hard margins were retrieved
1016  *
1017  * Since: 2.20
1018  */
1019 gboolean
gtk_printer_get_hard_margins(GtkPrinter * printer,gdouble * top,gdouble * bottom,gdouble * left,gdouble * right)1020 gtk_printer_get_hard_margins (GtkPrinter *printer,
1021 			      gdouble    *top,
1022 			      gdouble    *bottom,
1023 			      gdouble    *left,
1024 			      gdouble    *right)
1025 {
1026   GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
1027 
1028   return backend_class->printer_get_hard_margins (printer, top, bottom, left, right);
1029 }
1030 
1031 /**
1032  * gtk_printer_get_capabilities:
1033  * @printer: a #GtkPrinter
1034  *
1035  * Returns the printer’s capabilities.
1036  *
1037  * This is useful when you’re using #GtkPrintUnixDialog’s manual-capabilities
1038  * setting and need to know which settings the printer can handle and which
1039  * you must handle yourself.
1040  *
1041  * This will return 0 unless the printer’s details are available, see
1042  * gtk_printer_has_details() and gtk_printer_request_details().
1043  *
1044  * Returns: the printer’s capabilities
1045  *
1046  * Since: 2.12
1047  */
1048 GtkPrintCapabilities
gtk_printer_get_capabilities(GtkPrinter * printer)1049 gtk_printer_get_capabilities (GtkPrinter *printer)
1050 {
1051   GtkPrintBackendClass *backend_class;
1052 
1053   g_return_val_if_fail (GTK_IS_PRINTER (printer), 0);
1054 
1055   backend_class = GTK_PRINT_BACKEND_GET_CLASS (printer->priv->backend);
1056   return backend_class->printer_get_capabilities (printer);
1057 }
1058 
1059 /**
1060  * gtk_printer_compare:
1061  * @a: a #GtkPrinter
1062  * @b: another #GtkPrinter
1063  *
1064  * Compares two printers.
1065  *
1066  * Returns: 0 if the printer match, a negative value if @a < @b,
1067  *   or a positive value if @a > @b
1068  *
1069  * Since: 2.10
1070  */
1071 gint
gtk_printer_compare(GtkPrinter * a,GtkPrinter * b)1072 gtk_printer_compare (GtkPrinter *a,
1073                      GtkPrinter *b)
1074 {
1075   const char *name_a, *name_b;
1076 
1077   g_assert (GTK_IS_PRINTER (a) && GTK_IS_PRINTER (b));
1078 
1079   name_a = gtk_printer_get_name (a);
1080   name_b = gtk_printer_get_name (b);
1081   if (name_a == NULL  && name_b == NULL)
1082     return 0;
1083   else if (name_a == NULL)
1084     return G_MAXINT;
1085   else if (name_b == NULL)
1086     return G_MININT;
1087   else
1088     return g_ascii_strcasecmp (name_a, name_b);
1089 }
1090 
1091 
1092 typedef struct
1093 {
1094   GList *backends;
1095   GtkPrinterFunc func;
1096   gpointer data;
1097   GDestroyNotify destroy;
1098   GMainLoop *loop;
1099 } PrinterList;
1100 
1101 static void list_done_cb (GtkPrintBackend *backend,
1102 			  PrinterList     *printer_list);
1103 
1104 static void
stop_enumeration(PrinterList * printer_list)1105 stop_enumeration (PrinterList *printer_list)
1106 {
1107   GList *list, *next;
1108   GtkPrintBackend *backend;
1109 
1110   for (list = printer_list->backends; list; list = next)
1111     {
1112       next = list->next;
1113       backend = GTK_PRINT_BACKEND (list->data);
1114       list_done_cb (backend, printer_list);
1115     }
1116 }
1117 
1118 static void
free_printer_list(PrinterList * printer_list)1119 free_printer_list (PrinterList *printer_list)
1120 {
1121   if (printer_list->destroy)
1122     printer_list->destroy (printer_list->data);
1123 
1124   if (printer_list->loop)
1125     {
1126       g_main_loop_quit (printer_list->loop);
1127       g_main_loop_unref (printer_list->loop);
1128     }
1129 
1130   g_free (printer_list);
1131 }
1132 
1133 static gboolean
list_added_cb(GtkPrintBackend * backend,GtkPrinter * printer,PrinterList * printer_list)1134 list_added_cb (GtkPrintBackend *backend,
1135 	       GtkPrinter      *printer,
1136 	       PrinterList     *printer_list)
1137 {
1138   if (printer_list->func (printer, printer_list->data))
1139     {
1140       stop_enumeration (printer_list);
1141       return TRUE;
1142     }
1143 
1144   return FALSE;
1145 }
1146 
1147 static void
backend_status_changed(GObject * object,GParamSpec * pspec,gpointer data)1148 backend_status_changed (GObject    *object,
1149                         GParamSpec *pspec,
1150                         gpointer    data)
1151 {
1152   GtkPrintBackend *backend = GTK_PRINT_BACKEND (object);
1153   PrinterList *printer_list = data;
1154   GtkPrintBackendStatus status;
1155 
1156   g_object_get (backend, "status", &status, NULL);
1157 
1158   if (status == GTK_PRINT_BACKEND_STATUS_UNAVAILABLE)
1159     list_done_cb (backend, printer_list);
1160 }
1161 
1162 static gboolean
list_printers_remove_backend(PrinterList * printer_list,GtkPrintBackend * backend)1163 list_printers_remove_backend (PrinterList     *printer_list,
1164                               GtkPrintBackend *backend)
1165 {
1166   printer_list->backends = g_list_remove (printer_list->backends, backend);
1167   gtk_print_backend_destroy (backend);
1168   g_object_unref (backend);
1169 
1170   if (printer_list->backends == NULL)
1171     {
1172       free_printer_list (printer_list);
1173       return TRUE;
1174     }
1175 
1176   return FALSE;
1177 }
1178 
1179 static void
list_done_cb(GtkPrintBackend * backend,PrinterList * printer_list)1180 list_done_cb (GtkPrintBackend *backend,
1181 	      PrinterList     *printer_list)
1182 {
1183   g_signal_handlers_disconnect_by_func (backend, list_added_cb, printer_list);
1184   g_signal_handlers_disconnect_by_func (backend, list_done_cb, printer_list);
1185   g_signal_handlers_disconnect_by_func (backend, backend_status_changed, printer_list);
1186 
1187   list_printers_remove_backend(printer_list, backend);
1188 }
1189 
1190 static gboolean
list_printers_init(PrinterList * printer_list,GtkPrintBackend * backend)1191 list_printers_init (PrinterList     *printer_list,
1192 		    GtkPrintBackend *backend)
1193 {
1194   GList *list, *node;
1195   GtkPrintBackendStatus status;
1196 
1197   list = gtk_print_backend_get_printer_list (backend);
1198 
1199   for (node = list; node != NULL; node = node->next)
1200     {
1201       if (list_added_cb (backend, node->data, printer_list))
1202         {
1203           g_list_free (list);
1204           return TRUE;
1205         }
1206     }
1207 
1208   g_list_free (list);
1209 
1210   g_object_get (backend, "status", &status, NULL);
1211 
1212   if (status == GTK_PRINT_BACKEND_STATUS_UNAVAILABLE ||
1213       gtk_print_backend_printer_list_is_done (backend))
1214     {
1215       if (list_printers_remove_backend (printer_list, backend))
1216         return TRUE;
1217     }
1218   else
1219     {
1220       g_signal_connect (backend, "printer-added",
1221 			(GCallback) list_added_cb,
1222 			printer_list);
1223       g_signal_connect (backend, "printer-list-done",
1224 			(GCallback) list_done_cb,
1225 			printer_list);
1226       g_signal_connect (backend, "notify::status",
1227                         (GCallback) backend_status_changed,
1228                         printer_list);
1229     }
1230 
1231   return FALSE;
1232 }
1233 
1234 /**
1235  * gtk_enumerate_printers:
1236  * @func: a function to call for each printer
1237  * @data: user data to pass to @func
1238  * @destroy: function to call if @data is no longer needed
1239  * @wait: if %TRUE, wait in a recursive mainloop until
1240  *    all printers are enumerated; otherwise return early
1241  *
1242  * Calls a function for all #GtkPrinters.
1243  * If @func returns %TRUE, the enumeration is stopped.
1244  *
1245  * Since: 2.10
1246  */
1247 void
gtk_enumerate_printers(GtkPrinterFunc func,gpointer data,GDestroyNotify destroy,gboolean wait)1248 gtk_enumerate_printers (GtkPrinterFunc func,
1249 			gpointer       data,
1250 			GDestroyNotify destroy,
1251 			gboolean       wait)
1252 {
1253   PrinterList *printer_list;
1254   GList *node, *next;
1255   GtkPrintBackend *backend;
1256 
1257   printer_list = g_new0 (PrinterList, 1);
1258 
1259   printer_list->func = func;
1260   printer_list->data = data;
1261   printer_list->destroy = destroy;
1262 
1263   if (g_module_supported ())
1264     printer_list->backends = gtk_print_backend_load_modules ();
1265 
1266   if (printer_list->backends == NULL)
1267     {
1268       free_printer_list (printer_list);
1269       return;
1270     }
1271 
1272   for (node = printer_list->backends; node != NULL; node = next)
1273     {
1274       next = node->next;
1275       backend = GTK_PRINT_BACKEND (node->data);
1276       if (list_printers_init (printer_list, backend))
1277         return;
1278     }
1279 
1280   if (wait && printer_list->backends)
1281     {
1282       printer_list->loop = g_main_loop_new (NULL, FALSE);
1283 
1284       gdk_threads_leave ();
1285       g_main_loop_run (printer_list->loop);
1286       gdk_threads_enter ();
1287     }
1288 }
1289 
1290 GType
gtk_print_capabilities_get_type(void)1291 gtk_print_capabilities_get_type (void)
1292 {
1293   static GType etype = 0;
1294 
1295   if (G_UNLIKELY (etype == 0))
1296     {
1297       static const GFlagsValue values[] = {
1298         { GTK_PRINT_CAPABILITY_PAGE_SET, "GTK_PRINT_CAPABILITY_PAGE_SET", "page-set" },
1299         { GTK_PRINT_CAPABILITY_COPIES, "GTK_PRINT_CAPABILITY_COPIES", "copies" },
1300         { GTK_PRINT_CAPABILITY_COLLATE, "GTK_PRINT_CAPABILITY_COLLATE", "collate" },
1301         { GTK_PRINT_CAPABILITY_REVERSE, "GTK_PRINT_CAPABILITY_REVERSE", "reverse" },
1302         { GTK_PRINT_CAPABILITY_SCALE, "GTK_PRINT_CAPABILITY_SCALE", "scale" },
1303         { GTK_PRINT_CAPABILITY_GENERATE_PDF, "GTK_PRINT_CAPABILITY_GENERATE_PDF", "generate-pdf" },
1304         { GTK_PRINT_CAPABILITY_GENERATE_PS, "GTK_PRINT_CAPABILITY_GENERATE_PS", "generate-ps" },
1305         { GTK_PRINT_CAPABILITY_PREVIEW, "GTK_PRINT_CAPABILITY_PREVIEW", "preview" },
1306 	{ GTK_PRINT_CAPABILITY_NUMBER_UP, "GTK_PRINT_CAPABILITY_NUMBER_UP", "number-up"},
1307         { GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT, "GTK_PRINT_CAPABILITY_NUMBER_UP_LAYOUT", "number-up-layout" },
1308         { 0, NULL, NULL }
1309       };
1310 
1311       etype = g_flags_register_static (I_("GtkPrintCapabilities"), values);
1312     }
1313 
1314   return etype;
1315 }
1316