summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorAlexander Larsson <alexl@redhat.com>2006-05-04 13:43:32 +0000
committerAlexander Larsson <alexl@src.gnome.org>2006-05-04 13:43:32 +0000
commitc36d8f3cb3781db3cf41b1888c7daf8487324d78 (patch)
treed2ca4427d7aabba33cc64b05f96f4a261334064c /modules
parent89b5cb64808fe544a4e0c6717bdb0c24908097b0 (diff)
downloadgtk+-c36d8f3cb3781db3cf41b1888c7daf8487324d78.tar.gz
Added new symbols
2006-05-04 Alexander Larsson <alexl@redhat.com> * gtk/gtk.symbols: Added new symbols * gtk/gtkpagesetupunixdialog.c: * gtk/gtkprintunixdialog.c: Destroy backends when finalizing dialogs. Fix printer leak in selected_printer_changed. * gtk/gtkprintbackend.[ch]: Convert from interface to baseclass. Move printer hashtable here so that the baseclass can handle the slightly complicated ownership model. Add gtk_print_backend_destroy which runs the dispose method, causing the ref-cycles between the backend and its printers to be broken. Add gtk_print_backend_unref_at_idle(). * gtk/gtkprinter.[ch]: GtkPrinter objects now ref their backend so that its always availible, since its needed for the printer object to work. This causes a reference-cycle that is broken using gtk_print_backend_destroy. Add gtk_printer_compare. * gtk/gtkprintoperation-private.h: * gtk/gtkprintoperation-unix.c: * gtk/gtkprintoperation.c: Implement !show_dialog for unix. Make sure the print data is fully spooled before returning from a sync run_dialog. * modules/printbackends/cups/gtkcupsutils.[ch]: Add gtk_cups_request_ipp_add_strings * modules/printbackends/cups/gtkprintbackendcups.c: * modules/printbackends/cups/gtkprintercups.c: * modules/printbackends/lpr/gtkprintbackendlpr.c: * modules/printbackends/pdf/gtkprintbackendpdf.c: Convert backends to derive instead of implementing interface. Move common code into baseclass. CUPS: Remove the printer polling in dispose, not finalize. In the cups watch, remove the backend at idle instead of immediately, since the unref can cause the module to be unloaded. Limit the number of printer attributes requested Get printer uri in initial printer listing so that we can use the printer object immediately. * tests/Makefile.am: * tests/testnouiprint.c: Add testcase for !show_dialog.
Diffstat (limited to 'modules')
-rw-r--r--modules/printbackends/cups/gtkcupsutils.c20
-rw-r--r--modules/printbackends/cups/gtkcupsutils.h7
-rw-r--r--modules/printbackends/cups/gtkprintbackendcups.c467
-rw-r--r--modules/printbackends/cups/gtkprintercups.c3
-rw-r--r--modules/printbackends/lpr/gtkprintbackendlpr.c123
-rw-r--r--modules/printbackends/pdf/gtkprintbackendpdf.c123
6 files changed, 307 insertions, 436 deletions
diff --git a/modules/printbackends/cups/gtkcupsutils.c b/modules/printbackends/cups/gtkcupsutils.c
index 458e1c4219..2ebf4a785f 100644
--- a/modules/printbackends/cups/gtkcupsutils.c
+++ b/modules/printbackends/cups/gtkcupsutils.c
@@ -242,6 +242,26 @@ gtk_cups_request_ipp_add_string (GtkCupsRequest *request,
value);
}
+void
+gtk_cups_request_ipp_add_strings (GtkCupsRequest *request,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int num_values,
+ const char *charset,
+ const char * const *values)
+{
+ ippAddStrings (request->ipp_request,
+ group,
+ tag,
+ name,
+ num_values,
+ charset,
+ values);
+}
+
+
+
typedef struct
{
const char *name;
diff --git a/modules/printbackends/cups/gtkcupsutils.h b/modules/printbackends/cups/gtkcupsutils.h
index f49cd2e9bc..88fb8810f2 100644
--- a/modules/printbackends/cups/gtkcupsutils.h
+++ b/modules/printbackends/cups/gtkcupsutils.h
@@ -109,6 +109,13 @@ void gtk_cups_request_ipp_add_string (GtkCupsRequest *request,
const char *name,
const char *charset,
const char *value);
+void gtk_cups_request_ipp_add_strings (GtkCupsRequest *request,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int num_values,
+ const char *charset,
+ const char * const *values);
gboolean gtk_cups_request_read_write (GtkCupsRequest *request);
GtkCupsPollState gtk_cups_request_get_poll_state (GtkCupsRequest *request);
void gtk_cups_request_free (GtkCupsRequest *request);
diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c
index 0e10c275b0..13bdfdb0d4 100644
--- a/modules/printbackends/cups/gtkprintbackendcups.c
+++ b/modules/printbackends/cups/gtkprintbackendcups.c
@@ -89,14 +89,12 @@ typedef struct
struct _GtkPrintBackendCupsClass
{
- GObjectClass parent_class;
+ GtkPrintBackendClass parent_class;
};
struct _GtkPrintBackendCups
{
- GObject parent_instance;
-
- GHashTable *printers;
+ GtkPrintBackend parent_instance;
char *default_printer;
@@ -108,10 +106,10 @@ struct _GtkPrintBackendCups
static GObjectClass *backend_parent_class;
static void gtk_print_backend_cups_class_init (GtkPrintBackendCupsClass *class);
-static void gtk_print_backend_cups_iface_init (GtkPrintBackendIface *iface);
static void gtk_print_backend_cups_init (GtkPrintBackendCups *impl);
static void gtk_print_backend_cups_finalize (GObject *object);
-static GList * cups_get_printer_list (GtkPrintBackend *print_backend);
+static void gtk_print_backend_cups_dispose (GObject *object);
+static void cups_get_printer_list (GtkPrintBackend *print_backend);
static void cups_request_execute (GtkPrintBackendCups *print_backend,
GtkCupsRequest *request,
GtkPrintCupsResponseCallbackFunc callback,
@@ -145,6 +143,17 @@ static void cups_begin_polling_info (GtkPrintBack
GtkPrintJob *job,
int job_id);
static gboolean cups_job_info_poll_timeout (gpointer user_data);
+static void gtk_print_backend_cups_print_stream (GtkPrintBackend *backend,
+ GtkPrintJob *job,
+ gint data_fd,
+ GtkPrintJobCompleteFunc callback,
+ gpointer user_data,
+ GDestroyNotify dnotify);
+static cairo_surface_t * cups_printer_create_cairo_surface (GtkPrinter *printer,
+ gdouble width,
+ gdouble height,
+ gint cache_fd);
+
static void
gtk_print_backend_cups_register_type (GTypeModule *module)
@@ -164,21 +173,10 @@ gtk_print_backend_cups_register_type (GTypeModule *module)
(GInstanceInitFunc) gtk_print_backend_cups_init
};
- static const GInterfaceInfo print_backend_info =
- {
- (GInterfaceInitFunc) gtk_print_backend_cups_iface_init, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
print_backend_cups_type = g_type_module_register_type (module,
- G_TYPE_OBJECT,
+ GTK_TYPE_PRINT_BACKEND,
"GtkPrintBackendCups",
&print_backend_cups_info, 0);
- g_type_module_add_interface (module,
- print_backend_cups_type,
- GTK_TYPE_PRINT_BACKEND,
- &print_backend_info);
}
}
@@ -229,10 +227,23 @@ static void
gtk_print_backend_cups_class_init (GtkPrintBackendCupsClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);
backend_parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = gtk_print_backend_cups_finalize;
+ gobject_class->dispose = gtk_print_backend_cups_dispose;
+
+ backend_class->request_printer_list = cups_get_printer_list;
+ backend_class->print_stream = gtk_print_backend_cups_print_stream;
+ backend_class->printer_request_details = cups_printer_request_details;
+ backend_class->printer_create_cairo_surface = cups_printer_create_cairo_surface;
+ backend_class->printer_get_options = cups_printer_get_options;
+ backend_class->printer_mark_conflicts = cups_printer_mark_conflicts;
+ backend_class->printer_get_settings_from_options = cups_printer_get_settings_from_options;
+ backend_class->printer_prepare_for_print = cups_printer_prepare_for_print;
+ backend_class->printer_list_papers = cups_printer_list_papers;
+ backend_class->printer_get_hard_margins = cups_printer_get_hard_margins;
}
static cairo_status_t
@@ -272,18 +283,6 @@ cups_printer_create_cairo_surface (GtkPrinter *printer,
return surface;
}
-static GtkPrinter *
-gtk_print_backend_cups_find_printer (GtkPrintBackend *print_backend,
- const gchar *printer_name)
-{
- GtkPrintBackendCups *cups_print_backend;
-
- cups_print_backend = GTK_PRINT_BACKEND_CUPS (print_backend);
-
- return (GtkPrinter *) g_hash_table_lookup (cups_print_backend->printers,
- printer_name);
-}
-
typedef struct {
GtkPrintJobCompleteFunc callback;
GtkPrintJob *job;
@@ -417,30 +416,10 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend,
static void
-gtk_print_backend_cups_iface_init (GtkPrintBackendIface *iface)
-{
- iface->get_printer_list = cups_get_printer_list;
- iface->find_printer = gtk_print_backend_cups_find_printer;
- iface->print_stream = gtk_print_backend_cups_print_stream;
- iface->printer_request_details = cups_printer_request_details;
- iface->printer_create_cairo_surface = cups_printer_create_cairo_surface;
- iface->printer_get_options = cups_printer_get_options;
- iface->printer_mark_conflicts = cups_printer_mark_conflicts;
- iface->printer_get_settings_from_options = cups_printer_get_settings_from_options;
- iface->printer_prepare_for_print = cups_printer_prepare_for_print;
- iface->printer_list_papers = cups_printer_list_papers;
- iface->printer_get_hard_margins = cups_printer_get_hard_margins;
-}
-
-static void
gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups)
{
backend_cups->list_printers_poll = 0;
backend_cups->list_printers_pending = FALSE;
- backend_cups->printers = g_hash_table_new_full (g_str_hash,
- g_str_equal,
- (GDestroyNotify) g_free,
- (GDestroyNotify) g_object_unref);
cups_request_default_printer (backend_cups);
}
@@ -452,18 +431,27 @@ gtk_print_backend_cups_finalize (GObject *object)
backend_cups = GTK_PRINT_BACKEND_CUPS (object);
- if (backend_cups->list_printers_poll > 0)
- g_source_remove (backend_cups->list_printers_poll);
-
- if (backend_cups->printers)
- g_hash_table_unref (backend_cups->printers);
-
g_free (backend_cups->default_printer);
backend_cups->default_printer = NULL;
backend_parent_class->finalize (object);
}
+static void
+gtk_print_backend_cups_dispose (GObject *object)
+{
+ GtkPrintBackendCups *backend_cups;
+
+ backend_cups = GTK_PRINT_BACKEND_CUPS (object);
+
+ if (backend_cups->list_printers_poll > 0)
+ g_source_remove (backend_cups->list_printers_poll);
+ backend_cups->list_printers_poll = 0;
+
+ backend_parent_class->dispose (object);
+}
+
+
static gboolean
cups_dispatch_watch_check (GSource *source)
{
@@ -514,13 +502,12 @@ cups_dispatch_watch_check (GSource *source)
static gboolean
cups_dispatch_watch_prepare (GSource *source,
- gint *timeout_)
+ gint *timeout_)
{
GtkPrintCupsDispatchWatch *dispatch;
dispatch = (GtkPrintCupsDispatchWatch *) source;
-
*timeout_ = -1;
return gtk_cups_request_read_write (dispatch->request);
@@ -528,8 +515,8 @@ cups_dispatch_watch_prepare (GSource *source,
static gboolean
cups_dispatch_watch_dispatch (GSource *source,
- GSourceFunc callback,
- gpointer user_data)
+ GSourceFunc callback,
+ gpointer user_data)
{
GtkPrintCupsDispatchWatch *dispatch;
GtkPrintCupsResponseCallbackFunc ep_callback;
@@ -548,7 +535,6 @@ cups_dispatch_watch_dispatch (GSource *source,
ep_callback (GTK_PRINT_BACKEND (dispatch->backend), result, user_data);
- g_source_unref (source);
return FALSE;
}
@@ -563,7 +549,11 @@ cups_dispatch_watch_finalize (GSource *source)
if (dispatch->backend)
{
- g_object_unref (dispatch->backend);
+ /* We need to unref this at idle time, because it might be the
+ last reference to this module causing the code to be
+ unloaded (including this particular function!)
+ */
+ gtk_print_backend_unref_at_idle (GTK_PRINT_BACKEND (dispatch->backend));
dispatch->backend = NULL;
}
@@ -588,7 +578,7 @@ cups_request_execute (GtkPrintBackendCups *print_backend,
GError **err)
{
GtkPrintCupsDispatchWatch *dispatch;
-
+
dispatch = (GtkPrintCupsDispatchWatch *) g_source_new (&_cups_dispatch_watch_funcs,
sizeof (GtkPrintCupsDispatchWatch));
@@ -599,10 +589,11 @@ cups_request_execute (GtkPrintBackendCups *print_backend,
g_source_set_callback ((GSource *) dispatch, (GSourceFunc) callback, user_data, notify);
g_source_attach ((GSource *) dispatch, NULL);
+ g_source_unref ((GSource *) dispatch);
}
static void
-cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
+cups_request_printer_info_cb (GtkPrintBackendCups *backend,
GtkCupsResult *result,
gpointer user_data)
{
@@ -611,40 +602,29 @@ cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
gchar *printer_name;
GtkPrinterCups *cups_printer;
GtkPrinter *printer;
- gchar *printer_uri;
- gchar *member_printer_uri;
gchar *loc;
gchar *desc;
gchar *state_msg;
int job_count;
-
- char uri[HTTP_MAX_URI], /* Printer URI */
- method[HTTP_MAX_URI], /* Method/scheme name */
- username[HTTP_MAX_URI], /* Username:password */
- hostname[HTTP_MAX_URI], /* Hostname */
- resource[HTTP_MAX_URI]; /* Resource name */
- int port; /* Port number */
gboolean status_changed;
- g_assert (GTK_IS_PRINT_BACKEND_CUPS (print_backend));
-
- printer_uri = NULL;
- member_printer_uri = NULL;
+ g_assert (GTK_IS_PRINT_BACKEND_CUPS (backend));
printer_name = (gchar *)user_data;
- cups_printer = (GtkPrinterCups *) g_hash_table_lookup (print_backend->printers, printer_name);
+ printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (backend),
+ printer_name);
- if (!cups_printer)
+ if (!printer)
return;
- printer = GTK_PRINTER (cups_printer);
+ cups_printer = GTK_PRINTER_CUPS (printer);
if (gtk_cups_result_is_error (result))
{
if (gtk_printer_is_new (printer))
{
- g_hash_table_remove (print_backend->printers,
- printer_name);
+ gtk_print_backend_remove_printer (GTK_PRINT_BACKEND (backend),
+ printer);
return;
}
else
@@ -656,8 +636,6 @@ cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
/* TODO: determine printer type and use correct icon */
gtk_printer_set_icon_name (printer, "printer");
- cups_printer->device_uri = g_strdup_printf ("/printers/%s", printer_name);
-
state_msg = "";
loc = "";
desc = "";
@@ -670,8 +648,6 @@ cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
_CUPS_MAP_ATTR_STR (attr, loc, "printer-location");
_CUPS_MAP_ATTR_STR (attr, desc, "printer-info");
_CUPS_MAP_ATTR_STR (attr, state_msg, "printer-state-message");
- _CUPS_MAP_ATTR_STR (attr, printer_uri, "printer-uri-supported");
- _CUPS_MAP_ATTR_STR (attr, member_printer_uri, "member-uris");
_CUPS_MAP_ATTR_INT (attr, cups_printer->state, "printer-state");
_CUPS_MAP_ATTR_INT (attr, job_count, "queued-job-count");
}
@@ -679,53 +655,15 @@ cups_request_printer_info_cb (GtkPrintBackendCups *print_backend,
/* if we got a member_printer_uri then this printer is part of a class
so use member_printer_uri, else user printer_uri */
- if (cups_printer->printer_uri)
- g_free (cups_printer->printer_uri);
-
- if (member_printer_uri)
- {
- g_free (printer_uri);
- cups_printer->printer_uri = member_printer_uri;
- }
- else
- cups_printer->printer_uri = printer_uri;
-
status_changed = gtk_printer_set_job_count (printer, job_count);
status_changed |= gtk_printer_set_location (printer, loc);
status_changed |= gtk_printer_set_description (printer, desc);
status_changed |= gtk_printer_set_state_message (printer, state_msg);
-#if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 1
- httpSeparateURI (HTTP_URI_CODING_ALL, cups_printer->printer_uri,
- method, sizeof (method),
- username, sizeof (username),
- hostname, sizeof (hostname),
- &port,
- resource, sizeof (resource));
-
-#else
- httpSeparate (cups_printer->printer_uri,
- method,
- username,
- hostname,
- &port,
- resource);
-#endif
-
- gethostname(uri, sizeof(uri));
-
- if (strcasecmp(uri, hostname) == 0)
- strcpy(hostname, "localhost");
-
- if (cups_printer->hostname)
- g_free (cups_printer->hostname);
-
- cups_printer->hostname = g_strdup (hostname);
- cups_printer->port = port;
-
if (status_changed)
- g_signal_emit_by_name (GTK_PRINT_BACKEND (print_backend), "printer-status-changed", printer);
+ g_signal_emit_by_name (GTK_PRINT_BACKEND (backend),
+ "printer-status-changed", printer);
}
static void
@@ -735,6 +673,14 @@ cups_request_printer_info (GtkPrintBackendCups *print_backend,
GError *error;
GtkCupsRequest *request;
gchar *printer_uri;
+ static const char * const pattrs[] = /* Attributes we're interested in */
+ {
+ "printer-location",
+ "printer-info",
+ "printer-state-message",
+ "printer-state",
+ "queued-job-count"
+ };
error = NULL;
@@ -752,6 +698,10 @@ cups_request_printer_info (GtkPrintBackendCups *print_backend,
g_free (printer_uri);
+ gtk_cups_request_ipp_add_strings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", G_N_ELEMENTS (pattrs),
+ NULL, pattrs);
+
cups_request_execute (print_backend,
request,
(GtkPrintCupsResponseCallbackFunc) cups_request_printer_info_cb,
@@ -922,82 +872,22 @@ cups_begin_polling_info (GtkPrintBackendCups *print_backend,
cups_request_job_info (data);
}
-static gint
-printer_cmp (GtkPrinter *a, GtkPrinter *b)
-{
- const char *name_a, *name_b;
- g_assert (GTK_IS_PRINTER (a) && GTK_IS_PRINTER (b));
-
- name_a = gtk_printer_get_name (a);
- name_b = gtk_printer_get_name (b);
- if (name_a == NULL && name_b == NULL)
- return 0;
- else if (name_a == NULL)
- return G_MAXINT;
- else if (name_b == NULL)
- return G_MININT;
- else
- return g_ascii_strcasecmp (name_a, name_b);
-}
-
static void
-printer_hash_to_sorted_active_list (const gchar *key,
- gpointer value,
- GList **out_list)
+mark_printer_inactive (GtkPrinter *printer,
+ GtkPrintBackend *backend)
{
- GtkPrinter *printer;
-
- printer = GTK_PRINTER (value);
-
- if (gtk_printer_get_name (printer) == NULL)
- return;
-
- if (!gtk_printer_is_active (printer))
- return;
-
- *out_list = g_list_insert_sorted (*out_list, value, (GCompareFunc) printer_cmp);
+ gtk_printer_set_is_active (printer, FALSE);
+ g_signal_emit_by_name (backend,
+ "printer-removed", printer);
}
-static void
-printer_hash_to_sorted_active_name_list (const gchar *key,
- gpointer value,
- GList **out_list)
+static gint
+find_printer (GtkPrinter *printer, const char *find_name)
{
- GtkPrinter *printer;
-
- printer = GTK_PRINTER (value);
-
-
- if (gtk_printer_get_name (printer) == NULL)
- return;
-
- if (!gtk_printer_is_active (printer))
- return;
+ const char *printer_name;
- if (gtk_printer_is_active (printer))
- *out_list = g_list_insert_sorted (*out_list,
- (char *)gtk_printer_get_name (printer),
- g_str_equal);
-}
-
-static void
-mark_printer_inactive (const gchar *printer_name,
- GtkPrintBackendCups *cups_backend)
-{
- GtkPrinter *printer;
- GHashTable *printer_hash;
-
- printer_hash = cups_backend->printers;
-
- printer = (GtkPrinter *) g_hash_table_lookup (printer_hash,
- printer_name);
-
- if (printer == NULL)
- return;
-
- gtk_printer_set_is_active (printer, FALSE);
-
- g_signal_emit_by_name (GTK_PRINT_BACKEND (cups_backend), "printer-removed", printer);
+ printer_name = gtk_printer_get_name (printer);
+ return g_ascii_strcasecmp (printer_name, find_name);
}
static void
@@ -1021,51 +911,122 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
g_warning ("Error getting printer list: %s", gtk_cups_result_get_error_string (result));
return;
}
-
+
/* gether the names of the printers in the current queue
so we may check to see if they were removed */
- removed_printer_checklist = NULL;
- if (cups_backend->printers != NULL)
- g_hash_table_foreach (cups_backend->printers,
- (GHFunc) printer_hash_to_sorted_active_name_list,
- &removed_printer_checklist);
-
+ removed_printer_checklist = gtk_print_backend_get_printer_list (GTK_PRINT_BACKEND (cups_backend));
+
response = gtk_cups_result_get_response (result);
- attr = ippFindAttribute (response, "printer-name", IPP_TAG_NAME);
- while (attr)
+ for (attr = response->attrs; attr != NULL; attr = attr->next)
{
- GtkPrinterCups *cups_printer;
GtkPrinter *printer;
const gchar *printer_name;
+ const char *printer_uri;
+ const char *member_uris;
GList *node;
+
+ /*
+ * Skip leading attributes until we hit a printer...
+ */
+ while (attr != NULL && attr->group_tag != IPP_TAG_PRINTER)
+ attr = attr->next;
+
+ if (attr == NULL)
+ break;
+
+ printer_name = NULL;
+ printer_uri = NULL;
+ member_uris = NULL;
+ while (attr != NULL && attr->group_tag == IPP_TAG_PRINTER)
+ {
+ if (!strcmp(attr->name, "printer-name") &&
+ attr->value_tag == IPP_TAG_NAME)
+ printer_name = attr->values[0].string.text;
+ else if (!strcmp(attr->name, "printer-uri-supported") &&
+ attr->value_tag == IPP_TAG_URI)
+ printer_uri = attr->values[0].string.text;
+ else if (!strcmp(attr->name, "member-uris") &&
+ attr->value_tag == IPP_TAG_URI)
+ member_uris = attr->values[0].string.text;
+
+ attr = attr->next;
+ }
- printer_name = attr->values[0].string.text;
+ if (printer_name == NULL ||
+ (printer_uri == NULL && member_uris == NULL))
+ {
+ if (attr == NULL)
+ break;
+ else
+ continue;
+ }
+
/* remove name from checklist if it was found */
- node = g_list_find_custom (removed_printer_checklist, printer_name, (GCompareFunc) g_ascii_strcasecmp);
+ node = g_list_find_custom (removed_printer_checklist, printer_name, (GCompareFunc) find_printer);
removed_printer_checklist = g_list_delete_link (removed_printer_checklist, node);
- cups_printer = (GtkPrinterCups *) g_hash_table_lookup (cups_backend->printers,
- printer_name);
- printer = cups_printer ? GTK_PRINTER (cups_printer) : NULL;
-
- if (!cups_printer)
+ printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (cups_backend), printer_name);
+ if (!printer)
{
+ GtkPrinterCups *cups_printer;
+ char uri[HTTP_MAX_URI], /* Printer URI */
+ method[HTTP_MAX_URI], /* Method/scheme name */
+ username[HTTP_MAX_URI], /* Username:password */
+ hostname[HTTP_MAX_URI], /* Hostname */
+ resource[HTTP_MAX_URI]; /* Resource name */
+ int port; /* Port number */
+
list_has_changed = TRUE;
- cups_printer = gtk_printer_cups_new (attr->values[0].string.text,
+ cups_printer = gtk_printer_cups_new (printer_name,
GTK_PRINT_BACKEND (cups_backend));
- printer = GTK_PRINTER (cups_printer);
+ cups_printer->device_uri = g_strdup_printf ("/printers/%s", printer_name);
+
+ if (member_uris)
+ {
+ cups_printer->printer_uri = g_strdup (member_uris);
+ }
+ else
+ cups_printer->printer_uri = g_strdup (printer_uri);
+
+#if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 1
+ httpSeparateURI (HTTP_URI_CODING_ALL, cups_printer->printer_uri,
+ method, sizeof (method),
+ username, sizeof (username),
+ hostname, sizeof (hostname),
+ &port,
+ resource, sizeof (resource));
+
+#else
+ httpSeparate (cups_printer->printer_uri,
+ method,
+ username,
+ hostname,
+ &port,
+ resource);
+#endif
+
+ gethostname(uri, sizeof(uri));
+ if (strcasecmp(uri, hostname) == 0)
+ strcpy(hostname, "localhost");
+
+ cups_printer->hostname = g_strdup (hostname);
+ cups_printer->port = port;
+
+ printer = GTK_PRINTER (cups_printer);
+
if (cups_backend->default_printer != NULL &&
strcmp (cups_backend->default_printer, gtk_printer_get_name (printer)) == 0)
gtk_printer_set_is_default (printer, TRUE);
- g_hash_table_insert (cups_backend->printers,
- g_strdup (gtk_printer_get_name (printer)),
- cups_printer);
+
+ gtk_print_backend_add_printer (GTK_PRINT_BACKEND (cups_backend), printer);
}
-
+ else
+ g_object_ref (printer);
+
if (!gtk_printer_is_active (printer))
{
gtk_printer_set_is_active (printer, TRUE);
@@ -1083,25 +1044,29 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
}
cups_request_printer_info (cups_backend, gtk_printer_get_name (printer));
-
- attr = ippFindNextAttribute (response,
- "printer-name",
- IPP_TAG_NAME);
- }
- /* look at the removed printers checklist and mark any printer
- as inactive if it is in the list, emitting a printer_removed signal */
+ /* The ref is held by GtkPrintBackend, in add_printer() */
+ g_object_unref (printer);
- if (removed_printer_checklist != NULL)
- {
- g_list_foreach (removed_printer_checklist, (GFunc) mark_printer_inactive, cups_backend);
- g_list_free (removed_printer_checklist);
- list_has_changed = TRUE;
- }
-
- if (list_has_changed)
- g_signal_emit_by_name (GTK_PRINT_BACKEND (cups_backend), "printer-list-changed");
+
+ if (attr == NULL)
+ break;
+ }
+ /* look at the removed printers checklist and mark any printer
+ as inactive if it is in the list, emitting a printer_removed signal */
+ if (removed_printer_checklist != NULL)
+ {
+ g_list_foreach (removed_printer_checklist, (GFunc) mark_printer_inactive,
+ GTK_PRINT_BACKEND (cups_backend));
+ g_list_free (removed_printer_checklist);
+ list_has_changed = TRUE;
+ }
+
+ if (list_has_changed)
+ g_signal_emit_by_name (GTK_PRINT_BACKEND (cups_backend), "printer-list-changed");
+
+ gtk_print_backend_set_list_done (GTK_PRINT_BACKEND (cups_backend));
}
static gboolean
@@ -1109,7 +1074,13 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend)
{
GError *error;
GtkCupsRequest *request;
-
+ static const char * const pattrs[] = /* Attributes we're interested in */
+ {
+ "printer-name",
+ "printer-uri-supported",
+ "member-uris"
+ };
+
if (cups_backend->list_printers_pending ||
!cups_backend->got_default_printer)
return TRUE;
@@ -1125,6 +1096,10 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend)
NULL,
NULL);
+ gtk_cups_request_ipp_add_strings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD,
+ "requested-attributes", G_N_ELEMENTS (pattrs),
+ NULL, pattrs);
+
cups_request_execute (cups_backend,
request,
(GtkPrintCupsResponseCallbackFunc) cups_request_printer_list_cb,
@@ -1136,29 +1111,19 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend)
return TRUE;
}
-static GList *
-cups_get_printer_list (GtkPrintBackend *print_backend)
+static void
+cups_get_printer_list (GtkPrintBackend *backend)
{
GtkPrintBackendCups *cups_backend;
- GList *result;
-
- cups_backend = GTK_PRINT_BACKEND_CUPS (print_backend);
-
- result = NULL;
- if (cups_backend->printers != NULL)
- g_hash_table_foreach (cups_backend->printers,
- (GHFunc) printer_hash_to_sorted_active_list,
- &result);
+ cups_backend = GTK_PRINT_BACKEND_CUPS (backend);
if (cups_backend->list_printers_poll == 0)
{
cups_request_printer_list (cups_backend);
- cups_backend->list_printers_poll = g_timeout_add (3000,
+ cups_backend->list_printers_poll = g_timeout_add (3000 * 100000,
(GSourceFunc) cups_request_printer_list,
- print_backend);
+ backend);
}
-
- return result;
}
typedef struct {
diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c
index c36b8077e5..89713339e7 100644
--- a/modules/printbackends/cups/gtkprintercups.c
+++ b/modules/printbackends/cups/gtkprintercups.c
@@ -90,8 +90,7 @@ gtk_printer_cups_finalize (GObject *object)
if (printer->ppd_file)
ppdClose (printer->ppd_file);
- if (G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize)
- G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize (object);
+ G_OBJECT_CLASS (gtk_printer_cups_parent_class)->finalize (object);
}
/**
diff --git a/modules/printbackends/lpr/gtkprintbackendlpr.c b/modules/printbackends/lpr/gtkprintbackendlpr.c
index 4560c92a2f..daed2e589b 100644
--- a/modules/printbackends/lpr/gtkprintbackendlpr.c
+++ b/modules/printbackends/lpr/gtkprintbackendlpr.c
@@ -51,25 +51,18 @@ static GType print_backend_lpr_type = 0;
struct _GtkPrintBackendLprClass
{
- GObjectClass parent_class;
+ GtkPrintBackendClass parent_class;
};
struct _GtkPrintBackendLpr
{
- GObject parent_instance;
-
- GtkPrinter *printer;
-
- GHashTable *printers;
+ GtkPrintBackend parent_instance;
};
static GObjectClass *backend_parent_class;
static void gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class);
-static void gtk_print_backend_lpr_iface_init (GtkPrintBackendIface *iface);
static void gtk_print_backend_lpr_init (GtkPrintBackendLpr *impl);
-static void gtk_print_backend_lpr_finalize (GObject *object);
-static GList * lpr_request_printer_list (GtkPrintBackend *print_backend);
static void lpr_printer_get_settings_from_options (GtkPrinter *printer,
GtkPrinterOptionSet *options,
GtkPrintSettings *settings);
@@ -89,6 +82,16 @@ static void lpr_printer_get_hard_margins (GtkPrinter
double *right);
static void lpr_printer_request_details (GtkPrinter *printer);
static GList * lpr_printer_list_papers (GtkPrinter *printer);
+static cairo_surface_t * lpr_printer_create_cairo_surface (GtkPrinter *printer,
+ gdouble width,
+ gdouble height,
+ gint cache_fd);
+static void gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
+ GtkPrintJob *job,
+ gint data_fd,
+ GtkPrintJobCompleteFunc callback,
+ gpointer user_data,
+ GDestroyNotify dnotify);
static void
gtk_print_backend_lpr_register_type (GTypeModule *module)
@@ -108,24 +111,11 @@ gtk_print_backend_lpr_register_type (GTypeModule *module)
(GInstanceInitFunc) gtk_print_backend_lpr_init,
};
- static const GInterfaceInfo print_backend_info =
- {
- (GInterfaceInitFunc) gtk_print_backend_lpr_iface_init, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
print_backend_lpr_type = g_type_module_register_type (module,
- G_TYPE_OBJECT,
- "GtkPrintBackendLpr",
- &print_backend_lpr_info, 0);
- g_type_module_add_interface (module,
- print_backend_lpr_type,
- GTK_TYPE_PRINT_BACKEND,
- &print_backend_info);
+ GTK_TYPE_PRINT_BACKEND,
+ "GtkPrintBackendLpr",
+ &print_backend_lpr_info, 0);
}
-
-
}
G_MODULE_EXPORT void
@@ -173,11 +163,19 @@ gtk_print_backend_lpr_new (void)
static void
gtk_print_backend_lpr_class_init (GtkPrintBackendLprClass *class)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
-
+ GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);
+
backend_parent_class = g_type_class_peek_parent (class);
- gobject_class->finalize = gtk_print_backend_lpr_finalize;
+ backend_class->print_stream = gtk_print_backend_lpr_print_stream;
+ backend_class->printer_request_details = lpr_printer_request_details;
+ backend_class->printer_create_cairo_surface = lpr_printer_create_cairo_surface;
+ backend_class->printer_get_options = lpr_printer_get_options;
+ backend_class->printer_mark_conflicts = lpr_printer_mark_conflicts;
+ backend_class->printer_get_settings_from_options = lpr_printer_get_settings_from_options;
+ backend_class->printer_prepare_for_print = lpr_printer_prepare_for_print;
+ backend_class->printer_list_papers = lpr_printer_list_papers;
+ backend_class->printer_get_hard_margins = lpr_printer_get_hard_margins;
}
static cairo_status_t
@@ -215,22 +213,6 @@ lpr_printer_create_cairo_surface (GtkPrinter *printer,
return surface;
}
-static GtkPrinter *
-gtk_print_backend_lpr_find_printer (GtkPrintBackend *print_backend,
- const gchar *printer_name)
-{
- GtkPrintBackendLpr *lpr_print_backend;
- GtkPrinter *printer;
-
- lpr_print_backend = GTK_PRINT_BACKEND_LPR (print_backend);
-
- printer = NULL;
- if (strcmp (gtk_printer_get_name (lpr_print_backend->printer), printer_name) == 0)
- printer = lpr_print_backend->printer;
-
- return printer;
-}
-
typedef struct {
GtkPrintBackend *backend;
GtkPrintJobCompleteFunc callback;
@@ -398,64 +380,21 @@ gtk_print_backend_lpr_print_stream (GtkPrintBackend *print_backend,
g_strfreev (argv);
}
-
static void
-gtk_print_backend_lpr_iface_init (GtkPrintBackendIface *iface)
-{
- iface->get_printer_list = lpr_request_printer_list;
- iface->find_printer = gtk_print_backend_lpr_find_printer;
- iface->print_stream = gtk_print_backend_lpr_print_stream;
- iface->printer_request_details = lpr_printer_request_details;
- iface->printer_create_cairo_surface = lpr_printer_create_cairo_surface;
- iface->printer_get_options = lpr_printer_get_options;
- iface->printer_mark_conflicts = lpr_printer_mark_conflicts;
- iface->printer_get_settings_from_options = lpr_printer_get_settings_from_options;
- iface->printer_prepare_for_print = lpr_printer_prepare_for_print;
- iface->printer_list_papers = lpr_printer_list_papers;
- iface->printer_get_hard_margins = lpr_printer_get_hard_margins;
-}
-
-static GList *
-lpr_request_printer_list (GtkPrintBackend *backend)
-{
- GList *l;
- GtkPrintBackendLpr *lpr_backend;
-
- l = NULL;
-
- lpr_backend = GTK_PRINT_BACKEND_LPR (backend);
-
- if (lpr_backend->printer)
- l = g_list_append (l, lpr_backend->printer);
-
- return l;
-}
-
-static void
-gtk_print_backend_lpr_init (GtkPrintBackendLpr *backend_lpr)
+gtk_print_backend_lpr_init (GtkPrintBackendLpr *backend)
{
GtkPrinter *printer;
printer = gtk_printer_new (_("Print to LPR"),
- GTK_PRINT_BACKEND (backend_lpr),
+ GTK_PRINT_BACKEND (backend),
TRUE);
gtk_printer_set_has_details (printer, TRUE);
gtk_printer_set_icon_name (printer, "printer");
gtk_printer_set_is_active (printer, TRUE);
-
- backend_lpr->printer = printer;
-}
-
-static void
-gtk_print_backend_lpr_finalize (GObject *object)
-{
- GtkPrintBackendLpr *backend_lpr;
-
- backend_lpr = GTK_PRINT_BACKEND_LPR (object);
-
- g_object_unref (backend_lpr->printer);
+ gtk_printer_set_is_default (printer, TRUE);
- backend_parent_class->finalize (object);
+ gtk_print_backend_add_printer (GTK_PRINT_BACKEND (backend), printer);
+ g_object_unref (printer);
}
static void
diff --git a/modules/printbackends/pdf/gtkprintbackendpdf.c b/modules/printbackends/pdf/gtkprintbackendpdf.c
index e746f92d46..206b2c1a8e 100644
--- a/modules/printbackends/pdf/gtkprintbackendpdf.c
+++ b/modules/printbackends/pdf/gtkprintbackendpdf.c
@@ -52,25 +52,18 @@ static GType print_backend_pdf_type = 0;
struct _GtkPrintBackendPdfClass
{
- GObjectClass parent_class;
+ GtkPrintBackendClass parent_class;
};
struct _GtkPrintBackendPdf
{
- GObject parent_instance;
-
- GtkPrinter *printer;
-
- GHashTable *printers;
+ GtkPrintBackend parent_instance;
};
static GObjectClass *backend_parent_class;
static void gtk_print_backend_pdf_class_init (GtkPrintBackendPdfClass *class);
-static void gtk_print_backend_pdf_iface_init (GtkPrintBackendIface *iface);
static void gtk_print_backend_pdf_init (GtkPrintBackendPdf *impl);
-static void gtk_print_backend_pdf_finalize (GObject *object);
-static GList * pdf_request_printer_list (GtkPrintBackend *print_backend);
static void pdf_printer_get_settings_from_options (GtkPrinter *printer,
GtkPrinterOptionSet *options,
GtkPrintSettings *settings);
@@ -90,6 +83,16 @@ static void pdf_printer_get_hard_margins (GtkPrinter
double *right);
static void pdf_printer_request_details (GtkPrinter *printer);
static GList * pdf_printer_list_papers (GtkPrinter *printer);
+static void gtk_print_backend_pdf_print_stream (GtkPrintBackend *print_backend,
+ GtkPrintJob *job,
+ gint data_fd,
+ GtkPrintJobCompleteFunc callback,
+ gpointer user_data,
+ GDestroyNotify dnotify);
+static cairo_surface_t * pdf_printer_create_cairo_surface (GtkPrinter *printer,
+ gdouble width,
+ gdouble height,
+ gint cache_fd);
static void
gtk_print_backend_pdf_register_type (GTypeModule *module)
@@ -109,24 +112,11 @@ gtk_print_backend_pdf_register_type (GTypeModule *module)
(GInstanceInitFunc) gtk_print_backend_pdf_init,
};
- static const GInterfaceInfo print_backend_info =
- {
- (GInterfaceInitFunc) gtk_print_backend_pdf_iface_init, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
print_backend_pdf_type = g_type_module_register_type (module,
- G_TYPE_OBJECT,
- "GtkPrintBackendPdf",
- &print_backend_pdf_info, 0);
- g_type_module_add_interface (module,
- print_backend_pdf_type,
- GTK_TYPE_PRINT_BACKEND,
- &print_backend_info);
+ GTK_TYPE_PRINT_BACKEND,
+ "GtkPrintBackendPdf",
+ &print_backend_pdf_info, 0);
}
-
-
}
G_MODULE_EXPORT void
@@ -174,11 +164,19 @@ gtk_print_backend_pdf_new (void)
static void
gtk_print_backend_pdf_class_init (GtkPrintBackendPdfClass *class)
{
- GObjectClass *gobject_class = G_OBJECT_CLASS (class);
+ GtkPrintBackendClass *backend_class = GTK_PRINT_BACKEND_CLASS (class);
backend_parent_class = g_type_class_peek_parent (class);
- gobject_class->finalize = gtk_print_backend_pdf_finalize;
+ backend_class->print_stream = gtk_print_backend_pdf_print_stream;
+ backend_class->printer_request_details = pdf_printer_request_details;
+ backend_class->printer_create_cairo_surface = pdf_printer_create_cairo_surface;
+ backend_class->printer_get_options = pdf_printer_get_options;
+ backend_class->printer_mark_conflicts = pdf_printer_mark_conflicts;
+ backend_class->printer_get_settings_from_options = pdf_printer_get_settings_from_options;
+ backend_class->printer_prepare_for_print = pdf_printer_prepare_for_print;
+ backend_class->printer_list_papers = pdf_printer_list_papers;
+ backend_class->printer_get_hard_margins = pdf_printer_get_hard_margins;
}
static cairo_status_t
@@ -216,22 +214,6 @@ pdf_printer_create_cairo_surface (GtkPrinter *printer,
return surface;
}
-static GtkPrinter *
-gtk_print_backend_pdf_find_printer (GtkPrintBackend *print_backend,
- const gchar *printer_name)
-{
- GtkPrintBackendPdf *pdf_print_backend;
- GtkPrinter *printer;
-
- pdf_print_backend = GTK_PRINT_BACKEND_PDF (print_backend);
-
- printer = NULL;
- if (strcmp (gtk_printer_get_name (pdf_print_backend->printer), printer_name) == 0)
- printer = pdf_print_backend->printer;
-
- return printer;
-}
-
typedef struct {
GtkPrintBackend *backend;
GtkPrintJobCompleteFunc callback;
@@ -366,64 +348,23 @@ gtk_print_backend_pdf_print_stream (GtkPrintBackend *print_backend,
ps);
}
-
static void
-gtk_print_backend_pdf_iface_init (GtkPrintBackendIface *iface)
-{
- iface->get_printer_list = pdf_request_printer_list;
- iface->find_printer = gtk_print_backend_pdf_find_printer;
- iface->print_stream = gtk_print_backend_pdf_print_stream;
- iface->printer_request_details = pdf_printer_request_details;
- iface->printer_create_cairo_surface = pdf_printer_create_cairo_surface;
- iface->printer_get_options = pdf_printer_get_options;
- iface->printer_mark_conflicts = pdf_printer_mark_conflicts;
- iface->printer_get_settings_from_options = pdf_printer_get_settings_from_options;
- iface->printer_prepare_for_print = pdf_printer_prepare_for_print;
- iface->printer_list_papers = pdf_printer_list_papers;
- iface->printer_get_hard_margins = pdf_printer_get_hard_margins;
-}
-
-static GList *
-pdf_request_printer_list (GtkPrintBackend *backend)
-{
- GList *l;
- GtkPrintBackendPdf *pdf_backend;
-
- l = NULL;
-
- pdf_backend = GTK_PRINT_BACKEND_PDF (backend);
-
- if (pdf_backend->printer)
- l = g_list_append (l, pdf_backend->printer);
-
- return l;
-}
-
-static void
-gtk_print_backend_pdf_init (GtkPrintBackendPdf *backend_pdf)
+gtk_print_backend_pdf_init (GtkPrintBackendPdf *backend)
{
GtkPrinter *printer;
- backend_pdf->printer = gtk_printer_new (_("Print to PDF"),
- GTK_PRINT_BACKEND (backend_pdf),
- TRUE);
+ printer = gtk_printer_new (_("Print to PDF"),
+ GTK_PRINT_BACKEND (backend),
+ TRUE);
- printer = backend_pdf->printer;
gtk_printer_set_has_details (printer, TRUE);
gtk_printer_set_icon_name (printer, "floppy");
gtk_printer_set_is_active (printer, TRUE);
-}
-
-static void
-gtk_print_backend_pdf_finalize (GObject *object)
-{
- GtkPrintBackendPdf *backend_pdf;
-
- backend_pdf = GTK_PRINT_BACKEND_PDF (object);
- g_object_unref (backend_pdf->printer);
+ gtk_print_backend_add_printer (GTK_PRINT_BACKEND (backend), printer);
+ g_object_unref (printer);
- backend_parent_class->finalize (object);
+ gtk_print_backend_set_list_done (GTK_PRINT_BACKEND (backend));
}
static void