From: Marek Kasik Date: Tue, 12 Mar 2013 16:18:16 +0000 (+0100) Subject: printing: Use DBus calls instead of Avahi API X-Git-Url: http://pileus.org/git/?p=~andy%2Fgtk;a=commitdiff_plain;h=05901bdbbdebe53f544aa844e751f4c24b60c955 printing: Use DBus calls instead of Avahi API Converts usage of Avahi API to DBus calls. This change allows us to remove dependency on avahi-gobject and avoids of possible circular dependency. Lists printers if Gtk+ is compiled with CUPS 1.6 or newer. --- diff --git a/configure.ac b/configure.ac index 91e7da02d..6d075c3d4 100644 --- a/configure.ac +++ b/configure.ac @@ -1455,45 +1455,6 @@ else fi fi -# Check for Avahi flags -AC_ARG_ENABLE(avahi-browsing, - [AS_HELP_STRING([--disable-avahi-browsing], - [disable avahi browsing of printers])],, - [enable_avahi_browsing=auto]) - -have_avahi_browsing=no -if test "x$enable_avahi_browsing" != "xno" -a \ - "x$have_cups_api_1_6" = "xyes"; then - AC_MSG_CHECKING([avahi-gobject]) - - if $PKG_CONFIG --exists avahi-gobject ; then - AVAHI_CFLAGS=`$PKG_CONFIG --cflags avahi-gobject` - AC_SUBST(AVAHI_CFLAGS) - AVAHI_LIBS=`$PKG_CONFIG --libs avahi-gobject` - AC_SUBST(AVAHI_LIBS) - have_avahi_gobject=yes - AC_MSG_RESULT([yes]) - else - AC_MSG_RESULT([no]) - fi - - if test "x$have_avahi_gobject" = "xyes" ; then - AC_DEFINE([HAVE_AVAHI_BROWSING], [1], [Define to 1 if avahi-gobject available]) - have_avahi_browsing=yes - else - AC_MSG_ERROR([ -*** avahi-gobject not found. avahi-gobject is required to build GTK+ with support -*** for avahi browsed printers when using CUPS 1.6. -]) - fi -else - if test "x$enable_avahi_browsing" = "xyes"; then - AC_MSG_ERROR([ -*** Avahi browsing support requested but CUPS 1.6 not found. -]) - fi -fi - # Checks to see if we should compile with PAPI backend for GTK+ # @@ -1870,7 +1831,6 @@ echo " Dynamic modules: $build_dynamic_modules" echo " Included immodules: $included_immodules" echo " PackageKit support: $build_packagekit" echo " colord support: $have_colord" -echo " Avahi browsing: $have_avahi_browsing" echo " Introspection: $found_introspection" echo " Debugging: $enable_debug" echo " Documentation: $enable_gtk_doc" diff --git a/modules/printbackends/cups/Makefile.am b/modules/printbackends/cups/Makefile.am index 2e5b92791..e9d4c2fdd 100644 --- a/modules/printbackends/cups/Makefile.am +++ b/modules/printbackends/cups/Makefile.am @@ -12,7 +12,6 @@ AM_CPPFLAGS = \ -I$(top_builddir)/gdk \ $(CUPS_CFLAGS) \ $(COLORD_CFLAGS) \ - $(AVAHI_CFLAGS) \ -DGTK_COMPILATION \ -DGTK_PRINT_BACKEND_ENABLE_UNSUPPORTED \ $(GTK_DEP_CFLAGS) \ @@ -38,6 +37,6 @@ noinst_HEADERS = \ gtkcupsutils.h libprintbackend_cups_la_LDFLAGS = -avoid-version -module $(no_undefined) -libprintbackend_cups_la_LIBADD = $(LDADDS) $(CUPS_LIBS) $(AVAHI_LIBS) +libprintbackend_cups_la_LIBADD = $(LDADDS) $(CUPS_LIBS) -include $(top_srcdir)/git.mk diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c index a8c8060f8..64b92bcdd 100644 --- a/modules/printbackends/cups/gtkprintbackendcups.c +++ b/modules/printbackends/cups/gtkprintbackendcups.c @@ -53,12 +53,6 @@ #include #include #include -#ifdef HAVE_AVAHI_BROWSING -#include -#include -#include -#include -#endif #include "gtkprintbackendcups.h" #include "gtkprintercups.h" @@ -78,6 +72,18 @@ typedef struct _GtkPrintBackendCupsClass GtkPrintBackendCupsClass; #define _CUPS_MAX_ATTEMPTS 10 #define _CUPS_MAX_CHUNK_SIZE 8192 +#ifdef HAVE_CUPS_API_1_6 +#define AVAHI_IF_UNSPEC -1 +#define AVAHI_PROTO_INET 0 +#define AVAHI_PROTO_INET6 1 +#define AVAHI_PROTO_UNSPEC -1 + +#define AVAHI_BUS "org.freedesktop.Avahi" +#define AVAHI_SERVER_IFACE "org.freedesktop.Avahi.Server" +#define AVAHI_SERVICE_BROWSER_IFACE "org.freedesktop.Avahi.ServiceBrowser" +#define AVAHI_SERVICE_RESOLVER_IFACE "org.freedesktop.Avahi.ServiceResolver" +#endif + /* define this to see warnings about ignored ppd options */ #undef PRINT_IGNORED_OPTIONS @@ -143,13 +149,13 @@ struct _GtkPrintBackendCups #ifdef HAVE_COLORD CdClient *colord_client; #endif -#ifdef HAVE_AVAHI_BROWSING - gchar *avahi_default_printer; - GList *avahi_resolvers; - GaServiceBrowser *avahi_ipp_browser; - GaServiceBrowser *avahi_ipps_browser; - GaClient *avahi_client; - GCancellable *avahi_cancellable; +#ifdef HAVE_CUPS_API_1_6 + GDBusConnection *dbus_connection; + gchar *avahi_default_printer; + guint avahi_service_browser_subscription_id; + guint avahi_service_browser_subscription_ids[2]; + gchar *avahi_service_browser_paths[2]; + GCancellable *avahi_cancellable; #endif }; @@ -217,8 +223,7 @@ void overwrite_and_free (gpointer static gboolean is_address_local (const gchar *address); static gboolean request_auth_info (gpointer data); -#ifdef HAVE_AVAHI_BROWSING -static void avahi_data_free (GtkPrintBackendCups *cups_backend); +#ifdef HAVE_CUPS_API_1_6 static void avahi_request_printer_list (GtkPrintBackendCups *cups_backend); #endif @@ -623,7 +628,7 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend, cups_printer = GTK_PRINTER_CUPS (gtk_print_job_get_printer (job)); settings = gtk_print_job_get_settings (job); -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 if (cups_printer->avahi_browsed) { http_t *http; @@ -738,6 +743,10 @@ void overwrite_and_free (gpointer data) static void gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups) { +#ifdef HAVE_CUPS_API_1_6 + gint i; +#endif + backend_cups->list_printers_poll = FALSE; backend_cups->got_default_printer = FALSE; backend_cups->list_printers_pending = FALSE; @@ -760,12 +769,15 @@ gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups) backend_cups->colord_client = cd_client_new (); #endif -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 + backend_cups->dbus_connection = NULL; backend_cups->avahi_default_printer = NULL; - backend_cups->avahi_resolvers = NULL; - backend_cups->avahi_ipp_browser = NULL; - backend_cups->avahi_ipps_browser = NULL; - backend_cups->avahi_client = NULL; + backend_cups->avahi_service_browser_subscription_id = 0; + for (i = 0; i < 2; i++) + { + backend_cups->avahi_service_browser_paths[i] = NULL; + backend_cups->avahi_service_browser_subscription_ids[i] = 0; + } #endif cups_get_local_default_printer (backend_cups); @@ -775,6 +787,9 @@ static void gtk_print_backend_cups_finalize (GObject *object) { GtkPrintBackendCups *backend_cups; +#ifdef HAVE_CUPS_API_1_6 + gint i; +#endif GTK_NOTE (PRINTING, g_print ("CUPS Backend: finalizing CUPS backend module\n")); @@ -798,8 +813,46 @@ gtk_print_backend_cups_finalize (GObject *object) g_object_unref (backend_cups->colord_client); #endif -#ifdef HAVE_AVAHI_BROWSING - avahi_data_free (backend_cups); +#ifdef HAVE_CUPS_API_1_6 + g_cancellable_cancel (backend_cups->avahi_cancellable); + + for (i = 0; i < 2; i++) + { + if (backend_cups->avahi_service_browser_subscription_ids[i] > 0) + { + g_dbus_connection_signal_unsubscribe (backend_cups->dbus_connection, + backend_cups->avahi_service_browser_subscription_ids[i]); + backend_cups->avahi_service_browser_subscription_ids[i] = 0; + } + + if (backend_cups->avahi_service_browser_paths[i]) + { + g_dbus_connection_call (backend_cups->dbus_connection, + AVAHI_BUS, + backend_cups->avahi_service_browser_paths[i], + AVAHI_SERVICE_BROWSER_IFACE, + "Free", + NULL, + NULL, + G_DBUS_CALL_FLAGS_NONE, + -1, + NULL, + NULL, + NULL); + g_clear_pointer (&backend_cups->avahi_service_browser_paths[i], g_free); + } + } + + if (backend_cups->avahi_service_browser_subscription_id > 0) + { + g_dbus_connection_signal_unsubscribe (backend_cups->dbus_connection, + backend_cups->avahi_service_browser_subscription_id); + backend_cups->avahi_service_browser_subscription_id = 0; + } + + g_clear_object (&backend_cups->avahi_cancellable); + g_clear_pointer (&backend_cups->avahi_default_printer, g_free); + g_object_unref (backend_cups->dbus_connection); #endif backend_parent_class->finalize (object); @@ -1823,7 +1876,7 @@ typedef struct gboolean default_printer; gboolean got_printer_type; gboolean remote_printer; -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 gboolean avahi_printer; #endif gchar **auth_info_required; @@ -2112,7 +2165,7 @@ cups_create_printer (GtkPrintBackendCups *cups_backend, char *cups_server; /* CUPS server */ #ifdef HAVE_COLORD -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 if (info->avahi_printer) cups_printer = gtk_printer_cups_new (info->printer_name, backend, @@ -2193,7 +2246,7 @@ cups_create_printer (GtkPrintBackendCups *cups_backend, strcmp (cups_backend->default_printer, gtk_printer_get_name (printer)) == 0) gtk_printer_set_is_default (printer, TRUE); -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 cups_printer->avahi_browsed = info->avahi_printer; #endif @@ -2307,7 +2360,7 @@ set_default_printer (GtkPrintBackendCups *cups_backend, } } -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 typedef struct { gchar *name; @@ -2330,22 +2383,6 @@ avahi_service_free (AvahiService *service) } } -static void -avahi_data_free (GtkPrintBackendCups *cups_backend) -{ - if (cups_backend) - { - g_cancellable_cancel (cups_backend->avahi_cancellable); - g_clear_object (&cups_backend->avahi_cancellable); - g_clear_pointer (&cups_backend->avahi_default_printer, g_free); - g_list_free_full (cups_backend->avahi_resolvers, g_object_unref); - cups_backend->avahi_resolvers = NULL; - g_clear_object (&cups_backend->avahi_ipp_browser); - g_clear_object (&cups_backend->avahi_ipps_browser); - g_clear_object (&cups_backend->avahi_client); - } -} - static void cups_request_avahi_printer_info_cb (GtkPrintBackendCups *cups_backend, GtkCupsResult *result, @@ -2567,283 +2604,340 @@ avahi_connection_test_cb (GObject *source_object, } static void -avahi_resolver_found_cb (GaServiceResolver *resolver, - int interface, - GaProtocol protocol, - const char *name, - const char *type, - const char *domain, - const char *host_name, - const AvahiAddress *address, - guint16 port, - AvahiStringList *txt, - glong flags, - gpointer *user_data) +avahi_service_resolver_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { AvahiConnectionTestData *data; GtkPrintBackendCups *backend = GTK_PRINT_BACKEND_CUPS (user_data); - AvahiStringList *item; + const gchar *name; + const gchar *host; + const gchar *type; + const gchar *domain; + const gchar *address; const gchar *protocol_string; - gchar host[AVAHI_ADDRESS_STR_MAX]; + GVariant *output; + GVariant *txt; + GVariant *child; + guint32 flags; + guint16 port; + GError *error = NULL; gchar *suffix = NULL; + gchar *tmp; + gint interface; + gint protocol; + gint aprotocol; + gint i, j; + + output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), + res, + &error); + if (output) + { + g_variant_get (output, "(ii&s&s&s&si&sq@aayu)", + &interface, + &protocol, + &name, + &type, + &domain, + &host, + &aprotocol, + &address, + &port, + &txt, + &flags); + + for (i = 0; i < g_variant_n_children (txt); i++) + { + child = g_variant_get_child_value (txt, i); - avahi_address_snprint (host, sizeof (host), address); - - item = avahi_string_list_find (txt, "rp"); - if (item) - avahi_string_list_get_pair (item, NULL, &suffix, NULL); + tmp = g_new0 (gchar, g_variant_n_children (child) + 1); + for (j = 0; j < g_variant_n_children (child); j++) + { + tmp[j] = g_variant_get_byte (g_variant_get_child_value (child, j)); + } - if (suffix) - { - if (g_strcmp0 (type, "_ipp._tcp") == 0) - protocol_string = "ipp"; - else - protocol_string = "ipps"; + if (g_str_has_prefix (tmp, "rp=")) + { + suffix = g_strdup (tmp + 3); + g_free (tmp); + break; + } - data = g_new0 (AvahiConnectionTestData, 1); + g_free (tmp); + } - if (protocol == GA_PROTOCOL_INET6) - data->printer_uri = g_strdup_printf ("%s://[%s]:%u/%s", protocol_string, host, port, suffix); - else - data->printer_uri = g_strdup_printf ("%s://%s:%u/%s", protocol_string, host, port, suffix); + if (suffix) + { + if (g_strcmp0 (type, "_ipp._tcp") == 0) + protocol_string = "ipp"; + else + protocol_string = "ipps"; - data->host = g_strdup (host); - data->port = port; - data->name = g_strdup (name); - data->type = g_strdup (type); - data->domain = g_strdup (domain); - data->backend = backend; + data = g_new0 (AvahiConnectionTestData, 1); - /* It can happen that the address is not reachable */ - g_socket_client_connect_to_host_async (g_socket_client_new (), - host, - port, - backend->avahi_cancellable, - avahi_connection_test_cb, - data); + if (aprotocol == AVAHI_PROTO_INET6) + data->printer_uri = g_strdup_printf ("%s://[%s]:%u/%s", protocol_string, address, port, suffix); + else + data->printer_uri = g_strdup_printf ("%s://%s:%u/%s", protocol_string, address, port, suffix); + + data->host = g_strdup (address); + data->port = port; + data->name = g_strdup (name); + data->type = g_strdup (type); + data->domain = g_strdup (domain); + data->backend = backend; + + /* It can happen that the address is not reachable */ + g_socket_client_connect_to_host_async (g_socket_client_new (), + address, + port, + backend->avahi_cancellable, + avahi_connection_test_cb, + data); + g_free (suffix); + } - g_free (suffix); + g_variant_unref (output); + } + else + { + g_warning ("%s", error->message); + g_error_free (error); } } static void -avahi_browser_new_service_cb (GaServiceBrowser *browser, - int interface, - GaProtocol protocol, - const char *name, - const char *type, - const char *domain, - glong flags, - gpointer user_data) +avahi_service_browser_signal_handler (GDBusConnection *connection, + const gchar *sender_name, + const gchar *object_path, + const gchar *interface_name, + const gchar *signal_name, + GVariant *parameters, + gpointer user_data) { GtkPrintBackendCups *backend = GTK_PRINT_BACKEND_CUPS (user_data); - GaServiceResolver *resolver; - GError *error = NULL; + gchar *name; + gchar *type; + gchar *domain; + guint flags; + gint interface; + gint protocol; + + if (g_strcmp0 (signal_name, "ItemNew") == 0) + { + g_variant_get (parameters, "(ii&s&s&su)", + &interface, + &protocol, + &name, + &type, + &domain, + &flags); + + if (g_strcmp0 (type, "_ipp._tcp") == 0 || + g_strcmp0 (type, "_ipps._tcp") == 0) + { + g_dbus_connection_call (backend->dbus_connection, + AVAHI_BUS, + "/", + AVAHI_SERVER_IFACE, + "ResolveService", + g_variant_new ("(iisssiu)", + interface, + protocol, + name, + type, + domain, + AVAHI_PROTO_UNSPEC, + 0), + G_VARIANT_TYPE ("(iissssisqaayu)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + backend->avahi_cancellable, + avahi_service_resolver_cb, + user_data); + } + } + else if (g_strcmp0 (signal_name, "ItemRemove") == 0) + { + GtkPrinterCups *printer; + GList *list; + GList *iter; - resolver = ga_service_resolver_new (AVAHI_IF_UNSPEC, - AVAHI_PROTO_UNSPEC, - name, type, domain, - AVAHI_PROTO_UNSPEC, - GA_LOOKUP_USE_MULTICAST); + g_variant_get (parameters, "(ii&s&s&su)", + &interface, + &protocol, + &name, + &type, + &domain, + &flags); - g_signal_connect (resolver, "found", - G_CALLBACK (avahi_resolver_found_cb), user_data); + if (g_strcmp0 (type, "_ipp._tcp") == 0 || + g_strcmp0 (type, "_ipps._tcp") == 0) + { + list = gtk_print_backend_get_printer_list (GTK_PRINT_BACKEND (backend)); + for (iter = list; iter; iter = iter->next) + { + printer = GTK_PRINTER_CUPS (iter->data); + if (g_strcmp0 (printer->avahi_name, name) == 0 && + g_strcmp0 (printer->avahi_type, type) == 0 && + g_strcmp0 (printer->avahi_domain, domain) == 0) + { + if (g_strcmp0 (gtk_printer_get_name (GTK_PRINTER (printer)), + backend->avahi_default_printer) == 0) + g_clear_pointer (&backend->avahi_default_printer, g_free); + + g_signal_emit_by_name (backend, "printer-removed", printer); + gtk_print_backend_remove_printer (GTK_PRINT_BACKEND (backend), + GTK_PRINTER (printer)); + g_signal_emit_by_name (backend, "printer-list-changed"); + break; + } + } + } - if (!ga_service_resolver_attach (resolver, - backend->avahi_client, - &error)) - { - GTK_NOTE (PRINTING, - g_warning ("CUPS Backend: Error resolving Avahi service %s: %s", - name, error->message)); - g_clear_object (&resolver); - g_clear_error (&error); - return; + g_list_free (list); } - - backend->avahi_resolvers = g_list_append (backend->avahi_resolvers, resolver); } static void -avahi_browser_removed_service_cb (GaServiceBrowser *browser, - int interface, - GaProtocol protocol, - const char *name, - const char *type, - const char *domain, - glong flags, - gpointer user_data) +avahi_service_browser_new_cb (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - GtkPrintBackendCups *backend = GTK_PRINT_BACKEND_CUPS (user_data); - GtkPrinterCups *printer; - GList *list; - GList *iter; + GtkPrintBackendCups *cups_backend = GTK_PRINT_BACKEND_CUPS (user_data); + GVariant *output; + GError *error = NULL; + gint i; - list = gtk_print_backend_get_printer_list (GTK_PRINT_BACKEND (backend)); - for (iter = list; iter; iter = iter->next) + output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), + res, + &error); + if (output) { - printer = GTK_PRINTER_CUPS (iter->data); - if (g_strcmp0 (printer->avahi_name, name) == 0 && - g_strcmp0 (printer->avahi_type, type) == 0 && - g_strcmp0 (printer->avahi_domain, domain) == 0) - { - if (g_strcmp0 (gtk_printer_get_name (GTK_PRINTER (printer)), - backend->avahi_default_printer) == 0) - g_clear_pointer (&backend->avahi_default_printer, g_free); - - g_signal_emit_by_name (backend, "printer-removed", printer); - gtk_print_backend_remove_printer (GTK_PRINT_BACKEND (backend), - GTK_PRINTER (printer)); - g_signal_emit_by_name (backend, "printer-list-changed"); - break; - } - } + i = cups_backend->avahi_service_browser_paths[0] ? 1 : 0; - g_list_free (list); -} + g_variant_get (output, "(o)", &cups_backend->avahi_service_browser_paths[i]); -static gboolean -avahi_client_renew (gpointer user_data) -{ - GtkPrintBackendCups *backend = GTK_PRINT_BACKEND_CUPS (user_data); - gboolean avahi_printers_removed = TRUE; - GList *list; - GList *iter; - - list = gtk_print_backend_get_printer_list (GTK_PRINT_BACKEND (backend)); - for (iter = list; iter; iter = iter->next) - if (GTK_PRINTER_CUPS (iter->data)->avahi_browsed) - avahi_printers_removed = FALSE; - - g_list_free (list); + cups_backend->avahi_service_browser_subscription_ids[i] = + g_dbus_connection_signal_subscribe (cups_backend->dbus_connection, + NULL, + AVAHI_SERVICE_BROWSER_IFACE, + NULL, + cups_backend->avahi_service_browser_paths[i], + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + avahi_service_browser_signal_handler, + user_data, + NULL); + + /* + * The general subscription for all service browsers is not needed + * now because we are already subscribed to service browsers + * specific to _ipp._tcp and _ipps._tcp services. + */ + if (cups_backend->avahi_service_browser_paths[0] && + cups_backend->avahi_service_browser_paths[1] && + cups_backend->avahi_service_browser_subscription_id > 0) + { + g_dbus_connection_signal_unsubscribe (cups_backend->dbus_connection, + cups_backend->avahi_service_browser_subscription_id); + cups_backend->avahi_service_browser_subscription_id = 0; + } - if (avahi_printers_removed) - { - avahi_data_free (backend); - avahi_request_printer_list (backend); - return FALSE; + g_variant_unref (output); } else { - return TRUE; + /* + * The creation of ServiceBrowser fails with G_IO_ERROR_DBUS_ERROR + * if Avahi is disabled. + */ + if (error->domain != G_IO_ERROR || + error->code != G_IO_ERROR_DBUS_ERROR) + g_warning ("%s", error->message); + g_error_free (error); } } static void -avahi_client_state_changed_cb (GaClient *ga_client, - GaClientState state, - gpointer user_data) +avahi_create_browsers (GObject *source_object, + GAsyncResult *res, + gpointer user_data) { - GtkPrintBackendCups *backend = GTK_PRINT_BACKEND_CUPS (user_data); - GtkPrinterCups *printer; - gboolean list_has_changed = FALSE; + GtkPrintBackendCups *cups_backend = GTK_PRINT_BACKEND_CUPS (user_data); GError *error = NULL; - GList *list; - GList *iter; - switch (state) + cups_backend->dbus_connection = g_bus_get_finish (res, &error); + if (!cups_backend->dbus_connection) { - case GA_CLIENT_STATE_FAILURE: - if (avahi_client_errno (ga_client->avahi_client) == AVAHI_ERR_DISCONNECTED) - { - list = gtk_print_backend_get_printer_list (GTK_PRINT_BACKEND (backend)); - - for (iter = list; iter; iter = iter->next) - { - printer = GTK_PRINTER_CUPS (iter->data); - if (printer->avahi_browsed) - { - g_signal_emit_by_name (backend, "printer-removed", printer); - gtk_print_backend_remove_printer (GTK_PRINT_BACKEND (backend), - GTK_PRINTER (printer)); - list_has_changed = TRUE; - } - } - - if (list_has_changed) - g_signal_emit_by_name (backend, "printer-list-changed"); - - g_idle_add (avahi_client_renew, backend); - - g_list_free (list); - } - break; - - case GA_CLIENT_STATE_S_RUNNING: - backend->avahi_ipp_browser = ga_service_browser_new ("_ipp._tcp"); - - g_signal_connect (backend->avahi_ipp_browser, "new-service", - G_CALLBACK (avahi_browser_new_service_cb), - user_data); - - g_signal_connect (backend->avahi_ipp_browser, "removed-service", - G_CALLBACK (avahi_browser_removed_service_cb), - user_data); - - if (!ga_service_browser_attach (backend->avahi_ipp_browser, - backend->avahi_client, - &error)) - { - GTK_NOTE (PRINTING, - g_warning ("CUPS Backend: Error getting printer list from Avahi: %s", - error->message)); - g_clear_object (&backend->avahi_ipp_browser); - g_clear_error (&error); - } - - backend->avahi_ipps_browser = ga_service_browser_new ("_ipps._tcp"); - - g_signal_connect (backend->avahi_ipps_browser, "new-service", - G_CALLBACK (avahi_browser_new_service_cb), - user_data); - - g_signal_connect (backend->avahi_ipps_browser, "removed-service", - G_CALLBACK (avahi_browser_removed_service_cb), - user_data); - - if (!ga_service_browser_attach (backend->avahi_ipps_browser, - backend->avahi_client, - &error)) - { - GTK_NOTE (PRINTING, - g_warning ("CUPS Backend: Error getting printer list from Avahi: %s", - error->message)); - g_clear_object (&backend->avahi_ipps_browser); - g_clear_error (&error); - } - break; - - default: - break; + g_debug ("Couldn't connect to D-Bus system bus, %s", error->message); + g_error_free (error); + return; } + + /* + * We need to subscribe to signals of service browser before + * we actually create it because it starts to emit them right + * after its creation. + */ + cups_backend->avahi_service_browser_subscription_id = + g_dbus_connection_signal_subscribe (cups_backend->dbus_connection, + NULL, + AVAHI_SERVICE_BROWSER_IFACE, + NULL, + NULL, + NULL, + G_DBUS_SIGNAL_FLAGS_NONE, + avahi_service_browser_signal_handler, + cups_backend, + NULL); + + /* + * Create service browsers for _ipp._tcp and _ipps._tcp services. + */ + g_dbus_connection_call (cups_backend->dbus_connection, + AVAHI_BUS, + "/", + AVAHI_SERVER_IFACE, + "ServiceBrowserNew", + g_variant_new ("(iissu)", + AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_ipp._tcp", + "", + 0), + G_VARIANT_TYPE ("(o)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + cups_backend->avahi_cancellable, + avahi_service_browser_new_cb, + cups_backend); + + g_dbus_connection_call (cups_backend->dbus_connection, + AVAHI_BUS, + "/", + AVAHI_SERVER_IFACE, + "ServiceBrowserNew", + g_variant_new ("(iissu)", + AVAHI_IF_UNSPEC, + AVAHI_PROTO_UNSPEC, + "_ipps._tcp", + "", + 0), + G_VARIANT_TYPE ("(o)"), + G_DBUS_CALL_FLAGS_NONE, + -1, + cups_backend->avahi_cancellable, + avahi_service_browser_new_cb, + cups_backend); } static void avahi_request_printer_list (GtkPrintBackendCups *cups_backend) { - GError *error = NULL; - - if (!cups_backend->avahi_client) - { - cups_backend->avahi_client = ga_client_new (GA_CLIENT_FLAG_NO_FAIL); - - g_signal_connect (cups_backend->avahi_client, "state-changed", - G_CALLBACK (avahi_client_state_changed_cb), - cups_backend); - - if (!ga_client_start (cups_backend->avahi_client, &error)) - { - GTK_NOTE (PRINTING, - g_warning ("CUPS Backend: Error getting printer list from Avahi: %s", - error->message)); - g_clear_object (&cups_backend->avahi_client); - g_clear_error (&error); - } - else - { - cups_backend->avahi_cancellable = g_cancellable_new (); - } - } + cups_backend->avahi_cancellable = g_cancellable_new (); + g_bus_get (G_BUS_TYPE_SYSTEM, NULL, avahi_create_browsers, cups_backend); } #endif @@ -3051,7 +3145,7 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend, { for (iter = removed_printer_checklist; iter; iter = iter->next) { -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 if (!GTK_PRINTER_CUPS (iter->data)->avahi_browsed) #endif { @@ -3075,7 +3169,7 @@ done: g_free (remote_default_printer); } -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 if (!cups_backend->got_default_printer && cups_backend->avahi_default_printer != NULL) { set_default_printer (cups_backend, cups_backend->avahi_default_printer); @@ -3171,7 +3265,7 @@ cups_get_printer_list (GtkPrintBackend *backend) (GSourceFunc) cups_request_printer_list, backend); -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 avahi_request_printer_list (cups_backend); #endif } @@ -3219,7 +3313,7 @@ cups_request_ppd_cb (GtkPrintBackendCups *print_backend, PPD files. */ if (((gtk_cups_result_get_error_type (result) == GTK_CUPS_ERROR_HTTP) && (gtk_cups_result_get_error_status (result) == HTTP_NOT_FOUND)) -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 || GTK_PRINTER_CUPS (printer)->avahi_browsed #endif ) diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c index f2adb0ce5..383bf9042 100644 --- a/modules/printbackends/cups/gtkprintercups.c +++ b/modules/printbackends/cups/gtkprintercups.c @@ -114,7 +114,7 @@ gtk_printer_cups_init (GtkPrinterCups *printer) printer->remote_cups_connection_test = NULL; printer->auth_info_required = NULL; printer->default_number_up = 1; -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 printer->avahi_browsed = FALSE; printer->avahi_name = NULL; printer->avahi_type = NULL; @@ -160,7 +160,7 @@ gtk_printer_cups_finalize (GObject *object) g_object_unref (printer->colord_profile); #endif -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 g_free (printer->avahi_name); g_free (printer->avahi_type); g_free (printer->avahi_domain); diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h index 7b14af618..10002cd72 100644 --- a/modules/printbackends/cups/gtkprintercups.h +++ b/modules/printbackends/cups/gtkprintercups.h @@ -75,7 +75,7 @@ struct _GtkPrinterCups gchar *colord_title; gchar *colord_qualifier; #endif -#ifdef HAVE_AVAHI_BROWSING +#ifdef HAVE_CUPS_API_1_6 gboolean avahi_browsed; gchar *avahi_name; gchar *avahi_type;