1 /* GTK - The GIMP Toolkit
2 * gtkprintbackend.h: Abstract printer backend interfaces
3 * Copyright (C) 2003, Red Hat, Inc.
5 * This library is free software; you can redistribute it and/or
6 * modify it under the terms of the GNU Lesser General Public
7 * License as published by the Free Software Foundation; either
8 * version 2 of the License, or (at your option) any later version.
10 * This library is distributed in the hope that it will be useful,
11 * but WITHOUT ANY WARRANTY; without even the implied warranty of
12 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
13 * Lesser General Public License for more details.
15 * You should have received a copy of the GNU Lesser General Public
16 * License along with this library; if not, write to the
17 * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
18 * Boston, MA 02111-1307, USA.
27 #include "gtkmodules.h"
28 #include "gtkprivate.h"
29 #include "gtkprintbackend.h"
30 #include "gtkprinter-private.h"
33 #define GTK_PRINT_BACKEND_GET_PRIVATE(o) \
34 (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINT_BACKEND, GtkPrintBackendPrivate))
36 static void gtk_print_backend_dispose (GObject *object);
38 struct _GtkPrintBackendPrivate
41 guint printer_list_requested : 1;
42 guint printer_list_done : 1;
50 PRINTER_STATUS_CHANGED,
54 static guint signals[LAST_SIGNAL] = { 0 };
56 static GObjectClass *backend_parent_class;
59 gtk_print_backend_error_quark (void)
61 static GQuark quark = 0;
63 quark = g_quark_from_static_string ("gtk-print-backend-error-quark");
67 /*****************************************
68 * GtkPrintBackendModule modules *
69 *****************************************/
71 typedef struct _GtkPrintBackendModule GtkPrintBackendModule;
72 typedef struct _GtkPrintBackendModuleClass GtkPrintBackendModuleClass;
74 struct _GtkPrintBackendModule
76 GTypeModule parent_instance;
80 void (*init) (GTypeModule *module);
82 GtkPrintBackend* (*create) (void);
87 struct _GtkPrintBackendModuleClass
89 GTypeModuleClass parent_class;
92 G_DEFINE_TYPE (GtkPrintBackendModule, _gtk_print_backend_module, G_TYPE_TYPE_MODULE)
93 #define GTK_TYPE_PRINT_BACKEND_MODULE (_gtk_print_backend_module_get_type ())
94 #define GTK_PRINT_BACKEND_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), GTK_TYPE_PRINT_BACKEND_MODULE, GtkPrintBackendModule))
96 static GSList *loaded_backends;
99 gtk_print_backend_module_load (GTypeModule *module)
101 GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module);
102 gpointer initp, exitp, createp;
104 pb_module->library = g_module_open (pb_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
105 if (!pb_module->library)
107 g_warning (g_module_error());
111 /* extract symbols from the lib */
112 if (!g_module_symbol (pb_module->library, "pb_module_init",
114 !g_module_symbol (pb_module->library, "pb_module_exit",
116 !g_module_symbol (pb_module->library, "pb_module_create",
119 g_warning (g_module_error());
120 g_module_close (pb_module->library);
125 pb_module->init = initp;
126 pb_module->exit = exitp;
127 pb_module->create = createp;
129 /* call the filesystems's init function to let it */
130 /* setup anything it needs to set up. */
131 pb_module->init (module);
137 gtk_print_backend_module_unload (GTypeModule *module)
139 GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module);
143 g_module_close (pb_module->library);
144 pb_module->library = NULL;
146 pb_module->init = NULL;
147 pb_module->exit = NULL;
148 pb_module->create = NULL;
151 /* This only will ever be called if an error occurs during
155 gtk_print_backend_module_finalize (GObject *object)
157 GtkPrintBackendModule *module = GTK_PRINT_BACKEND_MODULE (object);
159 g_free (module->path);
161 G_OBJECT_CLASS (_gtk_print_backend_module_parent_class)->finalize (object);
165 _gtk_print_backend_module_class_init (GtkPrintBackendModuleClass *class)
167 GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
168 GObjectClass *gobject_class = G_OBJECT_CLASS (class);
170 module_class->load = gtk_print_backend_module_load;
171 module_class->unload = gtk_print_backend_module_unload;
173 gobject_class->finalize = gtk_print_backend_module_finalize;
177 _gtk_print_backend_module_init (GtkPrintBackendModule *pb_module)
181 static GtkPrintBackend *
182 _gtk_print_backend_module_create (GtkPrintBackendModule *pb_module)
186 if (g_type_module_use (G_TYPE_MODULE (pb_module)))
188 pb = pb_module->create ();
189 g_type_module_unuse (G_TYPE_MODULE (pb_module));
195 static GtkPrintBackend *
196 _gtk_print_backend_create (const gchar *backend_name)
201 GtkPrintBackendModule *pb_module;
204 for (l = loaded_backends; l != NULL; l = l->next)
208 if (strcmp (G_TYPE_MODULE (pb_module)->name, backend_name) == 0)
209 return _gtk_print_backend_module_create (pb_module);
213 if (g_module_supported ())
215 full_name = g_strconcat ("printbackend-", backend_name, NULL);
216 module_path = _gtk_find_module (full_name, "printbackends");
221 pb_module = g_object_new (GTK_TYPE_PRINT_BACKEND_MODULE, NULL);
223 g_type_module_set_name (G_TYPE_MODULE (pb_module), backend_name);
224 pb_module->path = g_strdup (module_path);
226 loaded_backends = g_slist_prepend (loaded_backends,
229 pb = _gtk_print_backend_module_create (pb_module);
231 /* Increase use-count so that we don't unload print backends.
232 * There is a problem with module unloading in the cups module,
233 * see cups_dispatch_watch_finalize for details.
235 g_type_module_use (G_TYPE_MODULE (pb_module));
238 g_free (module_path);
245 gtk_print_backend_initialize (void)
247 static gboolean initialized = FALSE;
251 gtk_settings_install_property (g_param_spec_string ("gtk-print-backends",
252 P_("Default print backend"),
253 P_("List of the GtkPrintBackend backends to use by default"),
255 GTK_PARAM_READWRITE));
257 gtk_settings_install_property (g_param_spec_string ("gtk-print-preview-command",
258 P_("Default command to run when displaying a print preview"),
259 P_("Command to run when displaying a print preview"),
260 GTK_PRINT_PREVIEW_COMMAND,
261 GTK_PARAM_READWRITE));
269 gtk_print_backend_load_modules (void)
272 GtkPrintBackend *backend;
276 GtkSettings *settings;
280 gtk_print_backend_initialize ();
282 settings = gtk_settings_get_default ();
284 g_object_get (settings, "gtk-print-backends", &setting, NULL);
286 backends = g_strsplit (setting, ",", -1);
288 for (i = 0; backends[i]; i++)
290 g_strchug (backends[i]);
291 g_strchomp (backends[i]);
292 backend = _gtk_print_backend_create (backends[i]);
295 result = g_list_append (result, backend);
298 g_strfreev (backends);
304 /*****************************************
306 *****************************************/
308 G_DEFINE_TYPE (GtkPrintBackend, gtk_print_backend, G_TYPE_OBJECT)
310 static void fallback_printer_request_details (GtkPrinter *printer);
311 static gboolean fallback_printer_mark_conflicts (GtkPrinter *printer,
312 GtkPrinterOptionSet *options);
313 static void fallback_printer_get_hard_margins (GtkPrinter *printer,
318 static GList * fallback_printer_list_papers (GtkPrinter *printer);
319 static GtkPrintCapabilities fallback_printer_get_capabilities (GtkPrinter *printer);
322 gtk_print_backend_class_init (GtkPrintBackendClass *class)
324 GObjectClass *object_class;
325 object_class = (GObjectClass *) class;
327 backend_parent_class = g_type_class_peek_parent (class);
329 object_class->dispose = gtk_print_backend_dispose;
331 class->printer_request_details = fallback_printer_request_details;
332 class->printer_mark_conflicts = fallback_printer_mark_conflicts;
333 class->printer_get_hard_margins = fallback_printer_get_hard_margins;
334 class->printer_list_papers = fallback_printer_list_papers;
335 class->printer_get_capabilities = fallback_printer_get_capabilities;
337 g_type_class_add_private (class, sizeof (GtkPrintBackendPrivate));
339 signals[PRINTER_LIST_CHANGED] =
340 g_signal_new (I_("printer-list-changed"),
341 G_TYPE_FROM_CLASS (class),
343 G_STRUCT_OFFSET (GtkPrintBackendClass, printer_list_changed),
345 g_cclosure_marshal_VOID__VOID,
347 signals[PRINTER_LIST_DONE] =
348 g_signal_new (I_("printer-list-done"),
349 G_TYPE_FROM_CLASS (class),
351 G_STRUCT_OFFSET (GtkPrintBackendClass, printer_list_done),
353 g_cclosure_marshal_VOID__VOID,
355 signals[PRINTER_ADDED] =
356 g_signal_new (I_("printer-added"),
357 G_TYPE_FROM_CLASS (class),
359 G_STRUCT_OFFSET (GtkPrintBackendClass, printer_added),
361 g_cclosure_marshal_VOID__OBJECT,
362 G_TYPE_NONE, 1, GTK_TYPE_PRINTER);
363 signals[PRINTER_REMOVED] =
364 g_signal_new (I_("printer-removed"),
365 G_TYPE_FROM_CLASS (class),
367 G_STRUCT_OFFSET (GtkPrintBackendClass, printer_removed),
369 g_cclosure_marshal_VOID__OBJECT,
370 G_TYPE_NONE, 1, GTK_TYPE_PRINTER);
371 signals[PRINTER_STATUS_CHANGED] =
372 g_signal_new (I_("printer-status-changed"),
373 G_TYPE_FROM_CLASS (class),
375 G_STRUCT_OFFSET (GtkPrintBackendClass, printer_status_changed),
377 g_cclosure_marshal_VOID__OBJECT,
378 G_TYPE_NONE, 1, GTK_TYPE_PRINTER);
382 gtk_print_backend_init (GtkPrintBackend *backend)
384 GtkPrintBackendPrivate *priv;
386 priv = backend->priv = GTK_PRINT_BACKEND_GET_PRIVATE (backend);
388 priv->printers = g_hash_table_new_full (g_str_hash, g_str_equal,
389 (GDestroyNotify) g_free,
390 (GDestroyNotify) g_object_unref);
394 gtk_print_backend_dispose (GObject *object)
396 GtkPrintBackend *backend;
397 GtkPrintBackendPrivate *priv;
399 backend = GTK_PRINT_BACKEND (object);
400 priv = backend->priv;
402 /* We unref the printers in dispose, not in finalize so that
403 * we can break refcount cycles with gtk_print_backend_destroy
407 g_hash_table_destroy (priv->printers);
408 priv->printers = NULL;
411 backend_parent_class->dispose (object);
416 fallback_printer_request_details (GtkPrinter *printer)
421 fallback_printer_mark_conflicts (GtkPrinter *printer,
422 GtkPrinterOptionSet *options)
428 fallback_printer_get_hard_margins (GtkPrinter *printer,
441 fallback_printer_list_papers (GtkPrinter *printer)
446 static GtkPrintCapabilities
447 fallback_printer_get_capabilities (GtkPrinter *printer)
454 printer_hash_to_sorted_active_list (const gchar *key,
460 printer = GTK_PRINTER (value);
462 if (gtk_printer_get_name (printer) == NULL)
465 if (!gtk_printer_is_active (printer))
468 *out_list = g_list_insert_sorted (*out_list, value, (GCompareFunc) gtk_printer_compare);
473 gtk_print_backend_add_printer (GtkPrintBackend *backend,
476 GtkPrintBackendPrivate *priv;
478 g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
480 priv = backend->priv;
485 g_hash_table_insert (priv->printers,
486 g_strdup (gtk_printer_get_name (printer)),
487 g_object_ref (printer));
491 gtk_print_backend_remove_printer (GtkPrintBackend *backend,
494 GtkPrintBackendPrivate *priv;
496 g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
497 priv = backend->priv;
502 g_hash_table_remove (priv->printers,
503 gtk_printer_get_name (printer));
507 gtk_print_backend_set_list_done (GtkPrintBackend *backend)
509 if (!backend->priv->printer_list_done)
511 backend->priv->printer_list_done = TRUE;
512 g_signal_emit (backend, signals[PRINTER_LIST_DONE], 0);
518 gtk_print_backend_get_printer_list (GtkPrintBackend *backend)
520 GtkPrintBackendPrivate *priv;
523 g_return_val_if_fail (GTK_IS_PRINT_BACKEND (backend), NULL);
525 priv = backend->priv;
528 if (priv->printers != NULL)
529 g_hash_table_foreach (priv->printers,
530 (GHFunc) printer_hash_to_sorted_active_list,
533 if (!priv->printer_list_requested && priv->printers != NULL)
535 if (GTK_PRINT_BACKEND_GET_CLASS (backend)->request_printer_list)
536 GTK_PRINT_BACKEND_GET_CLASS (backend)->request_printer_list (backend);
537 priv->printer_list_requested = TRUE;
544 gtk_print_backend_printer_list_is_done (GtkPrintBackend *print_backend)
546 g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), TRUE);
548 return print_backend->priv->printer_list_done;
552 gtk_print_backend_find_printer (GtkPrintBackend *backend,
553 const gchar *printer_name)
555 GtkPrintBackendPrivate *priv;
558 g_return_val_if_fail (GTK_IS_PRINT_BACKEND (backend), NULL);
560 priv = backend->priv;
563 printer = g_hash_table_lookup (priv->printers, printer_name);
571 gtk_print_backend_print_stream (GtkPrintBackend *backend,
574 GtkPrintJobCompleteFunc callback,
576 GDestroyNotify dnotify)
578 g_return_if_fail (GTK_IS_PRINT_BACKEND (backend));
580 GTK_PRINT_BACKEND_GET_CLASS (backend)->print_stream (backend,
589 gtk_print_backend_destroy (GtkPrintBackend *print_backend)
591 /* The lifecycle of print backends and printers are tied, such that
592 * the backend owns the printers, but the printers also ref the backend.
593 * This is so that if the app has a reference to a printer its backend
594 * will be around. However, this results in a cycle, which we break
595 * with this call, which causes the print backend to release its printers.
597 g_object_run_dispose (G_OBJECT (print_backend));
600 #define __GTK_PRINT_BACKEND_C__
601 #include "gtkaliasdef.c"