diff options
Diffstat (limited to 'gtk/gtkprintbackend.c')
-rw-r--r-- | gtk/gtkprintbackend.c | 379 |
1 files changed, 379 insertions, 0 deletions
diff --git a/gtk/gtkprintbackend.c b/gtk/gtkprintbackend.c new file mode 100644 index 0000000000..32e6596d0a --- /dev/null +++ b/gtk/gtkprintbackend.c @@ -0,0 +1,379 @@ +/* GTK - The GIMP Toolkit + * gtkprintbackend.h: Abstract printer backend interfaces + * Copyright (C) 2003, Red Hat, Inc. + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the + * Free Software Foundation, Inc., 59 Temple Place - Suite 330, + * Boston, MA 02111-1307, USA. + */ + +#include "config.h" +#include <string.h> + +#include <gmodule.h> + +#include "gtkintl.h" +#include "gtkmodules.h" +#include "gtkprivate.h" +#include "gtkprintbackend.h" +#include "gtkalias.h" + +static void gtk_print_backend_base_init (gpointer g_class); + +GQuark +gtk_print_backend_error_quark (void) +{ + static GQuark quark = 0; + if (quark == 0) + quark = g_quark_from_static_string ("gtk-print-backend-error-quark"); + return quark; +} + +/***************************************** + * GtkPrintBackendModule modules * + *****************************************/ + +typedef struct _GtkPrintBackendModule GtkPrintBackendModule; +typedef struct _GtkPrintBackendModuleClass GtkPrintBackendModuleClass; + +struct _GtkPrintBackendModule +{ + GTypeModule parent_instance; + + GModule *library; + + void (*init) (GTypeModule *module); + void (*exit) (void); + GtkPrintBackend* (*create) (void); + + gchar *path; +}; + +struct _GtkPrintBackendModuleClass +{ + GTypeModuleClass parent_class; +}; + +G_DEFINE_TYPE (GtkPrintBackendModule, _gtk_print_backend_module, G_TYPE_TYPE_MODULE); +#define GTK_TYPE_PRINT_BACKEND_MODULE (_gtk_print_backend_module_get_type ()) +#define GTK_PRINT_BACKEND_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), GTK_TYPE_PRINT_BACKEND_MODULE, GtkPrintBackendModule)) + +static GSList *loaded_backends; + +static gboolean +gtk_print_backend_module_load (GTypeModule *module) +{ + GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module); + gpointer initp, exitp, createp; + + pb_module->library = g_module_open (pb_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); + if (!pb_module->library) + { + g_warning (g_module_error()); + return FALSE; + } + + /* extract symbols from the lib */ + if (!g_module_symbol (pb_module->library, "pb_module_init", + &initp) || + !g_module_symbol (pb_module->library, "pb_module_exit", + &exitp) || + !g_module_symbol (pb_module->library, "pb_module_create", + &createp)) + { + g_warning (g_module_error()); + g_module_close (pb_module->library); + + return FALSE; + } + + pb_module->init = initp; + pb_module->exit = exitp; + pb_module->create = createp; + + /* call the filesystems's init function to let it */ + /* setup anything it needs to set up. */ + pb_module->init (module); + + return TRUE; +} + +static void +gtk_print_backend_module_unload (GTypeModule *module) +{ + GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module); + + pb_module->exit(); + + g_module_close (pb_module->library); + pb_module->library = NULL; + + pb_module->init = NULL; + pb_module->exit = NULL; + pb_module->create = NULL; +} + +/* This only will ever be called if an error occurs during + * initialization + */ +static void +gtk_print_backend_module_finalize (GObject *object) +{ + GtkPrintBackendModule *module = GTK_PRINT_BACKEND_MODULE (object); + + g_free (module->path); + + G_OBJECT_CLASS (_gtk_print_backend_module_parent_class)->finalize (object); +} + +static void +_gtk_print_backend_module_class_init (GtkPrintBackendModuleClass *class) +{ + GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class); + GObjectClass *gobject_class = G_OBJECT_CLASS (class); + + module_class->load = gtk_print_backend_module_load; + module_class->unload = gtk_print_backend_module_unload; + + gobject_class->finalize = gtk_print_backend_module_finalize; +} + +static void +_gtk_print_backend_module_init (GtkPrintBackendModule *pb_module) +{ +} + +static GtkPrintBackend * +_gtk_print_backend_module_create (GtkPrintBackendModule *pb_module) +{ + GtkPrintBackend *pb; + + if (g_type_module_use (G_TYPE_MODULE (pb_module))) + { + pb = pb_module->create (); + g_type_module_unuse (G_TYPE_MODULE (pb_module)); + return pb; + } + return NULL; +} + +GtkPrintBackend * +_gtk_print_backend_create (const char *backend_name) +{ + GSList *l; + char *module_path; + char *full_name; + GtkPrintBackendModule *pb_module; + GtkPrintBackend *pb; + + /* TODO: make module loading code work */ + for (l = loaded_backends; l != NULL; l = l->next) + { + pb_module = l->data; + + if (strcmp (G_TYPE_MODULE (pb_module)->name, backend_name) == 0) + return _gtk_print_backend_module_create (pb_module); + } + + pb = NULL; + if (g_module_supported ()) + { + full_name = g_strconcat ("printbackend-", backend_name, NULL); + module_path = _gtk_find_module (full_name, "printbackends"); + g_free (full_name); + + if (module_path) + { + pb_module = g_object_new (GTK_TYPE_PRINT_BACKEND_MODULE, NULL); + + g_type_module_set_name (G_TYPE_MODULE (pb_module), backend_name); + pb_module->path = g_strdup (module_path); + + loaded_backends = g_slist_prepend (loaded_backends, + pb_module); + + pb = _gtk_print_backend_module_create (pb_module); + } + + g_free (module_path); + } + + return pb; + + return NULL; +} + +static void +gtk_print_backend_initialize (void) +{ + static gboolean initialized = FALSE; + + if (!initialized) + { + gtk_settings_install_property (g_param_spec_string ("gtk-print-backends", + P_("Default print backend"), + P_("List of the GtkPrintBackend backends to use by default"), + GTK_PRINT_BACKENDS, + GTK_PARAM_READWRITE)); + + initialized = TRUE; + } +} + + + +GList * +gtk_print_backend_load_modules () +{ + GList *result; + GtkPrintBackend *backend; + gchar *setting; + gchar **backends; + gint i; + GtkSettings *settings; + + result = NULL; + + gtk_print_backend_initialize (); + + settings = gtk_settings_get_default (); + + g_object_get (settings, "gtk-print-backends", &setting, NULL); + + backends = g_strsplit (setting, ",", -1); + + for (i = 0; backends[i]; i++) + { + g_strchug (backends[i]); + g_strchomp (backends[i]); + backend = _gtk_print_backend_create (backends[i]); + + if (backend) + result = g_list_append (result, backend); + } + + g_strfreev (backends); + g_free (setting); + + return result; +} + +/***************************************** + * GtkPrintBackend * + *****************************************/ +GType +gtk_print_backend_get_type (void) +{ + static GType print_backend_type = 0; + + if (!print_backend_type) + { + static const GTypeInfo print_backend_info = + { + sizeof (GtkPrintBackendIface), /* class_size */ + gtk_print_backend_base_init, /* base_init */ + NULL, /* base_finalize */ + }; + + print_backend_type = g_type_register_static (G_TYPE_INTERFACE, + "GtkPrintBackend", + &print_backend_info, 0); + + g_type_interface_add_prerequisite (print_backend_type, G_TYPE_OBJECT); + } + + return print_backend_type; +} + +static void +gtk_print_backend_base_init (gpointer g_class) +{ + static gboolean initialized = FALSE; + + if (!initialized) + { + GType iface_type = G_TYPE_FROM_INTERFACE (g_class); + + g_signal_new ("printer-list-changed", + iface_type, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkPrintBackendIface, printer_list_changed), + NULL, NULL, + g_cclosure_marshal_VOID__VOID, + G_TYPE_NONE, 0); + g_signal_new ("printer-added", + iface_type, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkPrintBackendIface, printer_added), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + g_signal_new ("printer-removed", + iface_type, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkPrintBackendIface, printer_removed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + g_signal_new ("printer-status-changed", + iface_type, + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkPrintBackendIface, printer_status_changed), + NULL, NULL, + g_cclosure_marshal_VOID__OBJECT, + G_TYPE_NONE, 1, G_TYPE_OBJECT); + + initialized = TRUE; + } +} + +GList * +gtk_print_backend_get_printer_list (GtkPrintBackend *print_backend) +{ + g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), NULL); + + return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->get_printer_list (print_backend); + +} + +GtkPrinter * +gtk_print_backend_find_printer (GtkPrintBackend *print_backend, + const gchar *printer_name) +{ + g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), NULL); + + return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->find_printer (print_backend, printer_name); + +} + +void +gtk_print_backend_print_stream (GtkPrintBackend *print_backend, + GtkPrintJob *job, + gint data_fd, + GtkPrintJobCompleteFunc callback, + gpointer user_data, + GDestroyNotify dnotify) +{ + g_return_if_fail (GTK_IS_PRINT_BACKEND (print_backend)); + + GTK_PRINT_BACKEND_GET_IFACE (print_backend)->print_stream (print_backend, + job, + data_fd, + callback, + user_data, + dnotify); +} + +#define __GTK_PRINT_BACKEND_C__ +#include "gtkaliasdef.c" |