]> Pileus Git - ~andy/gtk/blob - gtk/gtkprintbackend.c
32e6596d0a6b3dca6c37af3164006f117156b452
[~andy/gtk] / gtk / gtkprintbackend.c
1 /* GTK - The GIMP Toolkit
2  * gtkprintbackend.h: Abstract printer backend interfaces
3  * Copyright (C) 2003, Red Hat, Inc.
4  *
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.
9  *
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.
14  *
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.
19  */
20
21 #include "config.h"
22 #include <string.h>
23
24 #include <gmodule.h>
25
26 #include "gtkintl.h"
27 #include "gtkmodules.h"
28 #include "gtkprivate.h"
29 #include "gtkprintbackend.h"
30 #include "gtkalias.h"
31
32 static void gtk_print_backend_base_init (gpointer g_class);
33
34 GQuark
35 gtk_print_backend_error_quark (void)
36 {
37   static GQuark quark = 0;
38   if (quark == 0)
39     quark = g_quark_from_static_string ("gtk-print-backend-error-quark");
40   return quark;
41 }
42
43 /*****************************************
44  *     GtkPrintBackendModule modules     *
45  *****************************************/
46
47 typedef struct _GtkPrintBackendModule GtkPrintBackendModule;
48 typedef struct _GtkPrintBackendModuleClass GtkPrintBackendModuleClass;
49
50 struct _GtkPrintBackendModule
51 {
52   GTypeModule parent_instance;
53   
54   GModule *library;
55
56   void             (*init)     (GTypeModule    *module);
57   void             (*exit)     (void);
58   GtkPrintBackend* (*create)   (void);
59
60   gchar *path;
61 };
62
63 struct _GtkPrintBackendModuleClass
64 {
65   GTypeModuleClass parent_class;
66 };
67
68 G_DEFINE_TYPE (GtkPrintBackendModule, _gtk_print_backend_module, G_TYPE_TYPE_MODULE);
69 #define GTK_TYPE_PRINT_BACKEND_MODULE      (_gtk_print_backend_module_get_type ())
70 #define GTK_PRINT_BACKEND_MODULE(module)   (G_TYPE_CHECK_INSTANCE_CAST ((module), GTK_TYPE_PRINT_BACKEND_MODULE, GtkPrintBackendModule))
71
72 static GSList *loaded_backends;
73
74 static gboolean
75 gtk_print_backend_module_load (GTypeModule *module)
76 {
77   GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module); 
78   gpointer initp, exitp, createp;
79  
80   pb_module->library = g_module_open (pb_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL);
81   if (!pb_module->library)
82     {
83       g_warning (g_module_error());
84       return FALSE;
85     }
86   
87   /* extract symbols from the lib */
88   if (!g_module_symbol (pb_module->library, "pb_module_init",
89                         &initp) ||
90       !g_module_symbol (pb_module->library, "pb_module_exit", 
91                         &exitp) ||
92       !g_module_symbol (pb_module->library, "pb_module_create", 
93                         &createp))
94     {
95       g_warning (g_module_error());
96       g_module_close (pb_module->library);
97       
98       return FALSE;
99     }
100
101   pb_module->init = initp;
102   pb_module->exit = exitp;
103   pb_module->create = createp;
104
105   /* call the filesystems's init function to let it */
106   /* setup anything it needs to set up. */
107   pb_module->init (module);
108
109   return TRUE;
110 }
111
112 static void
113 gtk_print_backend_module_unload (GTypeModule *module)
114 {
115   GtkPrintBackendModule *pb_module = GTK_PRINT_BACKEND_MODULE (module);
116   
117   pb_module->exit();
118
119   g_module_close (pb_module->library);
120   pb_module->library = NULL;
121
122   pb_module->init = NULL;
123   pb_module->exit = NULL;
124   pb_module->create = NULL;
125 }
126
127 /* This only will ever be called if an error occurs during
128  * initialization
129  */
130 static void
131 gtk_print_backend_module_finalize (GObject *object)
132 {
133   GtkPrintBackendModule *module = GTK_PRINT_BACKEND_MODULE (object);
134
135   g_free (module->path);
136
137   G_OBJECT_CLASS (_gtk_print_backend_module_parent_class)->finalize (object);
138 }
139
140 static void
141 _gtk_print_backend_module_class_init (GtkPrintBackendModuleClass *class)
142 {
143   GTypeModuleClass *module_class = G_TYPE_MODULE_CLASS (class);
144   GObjectClass *gobject_class = G_OBJECT_CLASS (class);
145   
146   module_class->load = gtk_print_backend_module_load;
147   module_class->unload = gtk_print_backend_module_unload;
148
149   gobject_class->finalize = gtk_print_backend_module_finalize;
150 }
151
152 static void
153 _gtk_print_backend_module_init (GtkPrintBackendModule *pb_module)
154 {
155 }
156
157 static GtkPrintBackend *
158 _gtk_print_backend_module_create (GtkPrintBackendModule *pb_module)
159 {
160   GtkPrintBackend *pb;
161   
162   if (g_type_module_use (G_TYPE_MODULE (pb_module)))
163     {
164       pb = pb_module->create ();
165       g_type_module_unuse (G_TYPE_MODULE (pb_module));
166       return pb;
167     }
168   return NULL;
169 }
170
171 GtkPrintBackend *
172 _gtk_print_backend_create (const char *backend_name)
173 {
174   GSList *l;
175   char *module_path;
176   char *full_name;
177   GtkPrintBackendModule *pb_module;
178   GtkPrintBackend *pb;
179
180   /* TODO: make module loading code work */
181   for (l = loaded_backends; l != NULL; l = l->next)
182     {
183       pb_module = l->data;
184       
185       if (strcmp (G_TYPE_MODULE (pb_module)->name, backend_name) == 0)
186         return _gtk_print_backend_module_create (pb_module);
187     }
188
189   pb = NULL;
190   if (g_module_supported ())
191     {
192       full_name = g_strconcat ("printbackend-", backend_name, NULL);
193       module_path = _gtk_find_module (full_name, "printbackends");
194       g_free (full_name);
195
196       if (module_path)
197         {
198           pb_module = g_object_new (GTK_TYPE_PRINT_BACKEND_MODULE, NULL);
199
200           g_type_module_set_name (G_TYPE_MODULE (pb_module), backend_name);
201           pb_module->path = g_strdup (module_path);
202
203           loaded_backends = g_slist_prepend (loaded_backends,
204                                              pb_module);
205
206           pb = _gtk_print_backend_module_create (pb_module);
207         }
208       
209       g_free (module_path);
210     }
211
212   return pb;
213
214   return NULL;
215 }
216
217 static void
218 gtk_print_backend_initialize (void)
219 {
220   static gboolean initialized = FALSE;
221
222   if (!initialized)
223     {
224       gtk_settings_install_property (g_param_spec_string ("gtk-print-backends",
225                                                           P_("Default print backend"),
226                                                           P_("List of the GtkPrintBackend backends to use by default"),
227                                                           GTK_PRINT_BACKENDS,
228                                                           GTK_PARAM_READWRITE));
229
230       initialized = TRUE;
231     }
232 }
233
234
235
236 GList *
237 gtk_print_backend_load_modules ()
238 {
239   GList *result;
240   GtkPrintBackend *backend;
241   gchar *setting;
242   gchar **backends;
243   gint i;
244   GtkSettings *settings;
245
246   result = NULL;
247
248   gtk_print_backend_initialize ();
249   
250   settings = gtk_settings_get_default ();
251
252   g_object_get (settings, "gtk-print-backends", &setting, NULL);
253
254   backends = g_strsplit (setting, ",", -1);
255
256   for (i = 0; backends[i]; i++)
257     {
258       g_strchug (backends[i]);
259       g_strchomp (backends[i]);
260       backend = _gtk_print_backend_create (backends[i]);
261       
262       if (backend)
263         result = g_list_append (result, backend);
264     }
265
266   g_strfreev (backends);
267   g_free (setting);
268
269   return result;
270 }
271
272 /*****************************************
273  *             GtkPrintBackend           *
274  *****************************************/
275 GType
276 gtk_print_backend_get_type (void)
277 {
278   static GType print_backend_type = 0;
279
280   if (!print_backend_type)
281     {
282       static const GTypeInfo print_backend_info =
283       {
284         sizeof (GtkPrintBackendIface),  /* class_size */
285         gtk_print_backend_base_init,    /* base_init */
286         NULL,                         /* base_finalize */
287       };
288
289       print_backend_type = g_type_register_static (G_TYPE_INTERFACE,
290                                                  "GtkPrintBackend",
291                                                  &print_backend_info, 0);
292
293       g_type_interface_add_prerequisite (print_backend_type, G_TYPE_OBJECT);
294     }
295
296   return print_backend_type;
297 }
298
299 static void
300 gtk_print_backend_base_init (gpointer g_class)
301 {
302   static gboolean initialized = FALSE;
303   
304   if (!initialized)
305     {
306       GType iface_type = G_TYPE_FROM_INTERFACE (g_class);
307
308       g_signal_new ("printer-list-changed",
309                     iface_type,
310                     G_SIGNAL_RUN_LAST,
311                     G_STRUCT_OFFSET (GtkPrintBackendIface, printer_list_changed),
312                     NULL, NULL,
313                     g_cclosure_marshal_VOID__VOID,
314                     G_TYPE_NONE, 0);
315       g_signal_new ("printer-added",
316                     iface_type,
317                     G_SIGNAL_RUN_LAST,
318                     G_STRUCT_OFFSET (GtkPrintBackendIface, printer_added),
319                     NULL, NULL,
320                     g_cclosure_marshal_VOID__OBJECT,
321                     G_TYPE_NONE, 1, G_TYPE_OBJECT);
322       g_signal_new ("printer-removed",
323                     iface_type,
324                     G_SIGNAL_RUN_LAST,
325                     G_STRUCT_OFFSET (GtkPrintBackendIface, printer_removed),
326                     NULL, NULL,
327                     g_cclosure_marshal_VOID__OBJECT,
328                     G_TYPE_NONE, 1, G_TYPE_OBJECT);
329       g_signal_new ("printer-status-changed",
330                     iface_type,
331                     G_SIGNAL_RUN_LAST,
332                     G_STRUCT_OFFSET (GtkPrintBackendIface, printer_status_changed),
333                     NULL, NULL,
334                     g_cclosure_marshal_VOID__OBJECT,
335                     G_TYPE_NONE, 1, G_TYPE_OBJECT);
336
337       initialized = TRUE;
338     }
339 }
340
341 GList *
342 gtk_print_backend_get_printer_list (GtkPrintBackend *print_backend)
343 {
344   g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), NULL);
345
346   return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->get_printer_list (print_backend);
347
348 }
349
350 GtkPrinter *
351 gtk_print_backend_find_printer (GtkPrintBackend *print_backend,
352                                 const gchar *printer_name)
353 {
354   g_return_val_if_fail (GTK_IS_PRINT_BACKEND (print_backend), NULL);
355
356   return GTK_PRINT_BACKEND_GET_IFACE (print_backend)->find_printer (print_backend, printer_name);
357
358 }
359
360 void
361 gtk_print_backend_print_stream (GtkPrintBackend *print_backend,
362                                 GtkPrintJob *job,
363                                 gint data_fd,
364                                 GtkPrintJobCompleteFunc callback,
365                                 gpointer user_data,
366                                 GDestroyNotify dnotify)
367 {
368   g_return_if_fail (GTK_IS_PRINT_BACKEND (print_backend));
369
370   GTK_PRINT_BACKEND_GET_IFACE (print_backend)->print_stream (print_backend,
371                                                              job,
372                                                              data_fd,
373                                                              callback,
374                                                              user_data,
375                                                              dnotify);
376 }
377
378 #define __GTK_PRINT_BACKEND_C__
379 #include "gtkaliasdef.c"