From 52e3c095bfdfb697e33509e0cef3bb5bf5ed7625 Mon Sep 17 00:00:00 2001 From: Marek Kasik Date: Wed, 30 Aug 2017 17:56:00 +0200 Subject: [PATCH] printing: Don't show duplicate printers Check UUID for printers obtained via DNSSD whether they are already installed on local CUPS server. Don't show such printers. Not all printers published via DNSSD have UUID entry though. https://bugzilla.gnome.org/show_bug.cgi?id=786794 --- .../printbackends/cups/gtkprintbackendcups.c | 64 ++++++++++++++++++- modules/printbackends/cups/gtkprintercups.c | 2 + modules/printbackends/cups/gtkprintercups.h | 1 + 3 files changed, 66 insertions(+), 1 deletion(-) diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c index 2056434bea..f391c695b1 100644 --- a/modules/printbackends/cups/gtkprintbackendcups.c +++ b/modules/printbackends/cups/gtkprintbackendcups.c @@ -1899,7 +1899,8 @@ static const char * const printer_attrs[] = "ipp-versions-supported", "multiple-document-handling-supported", "copies-supported", - "number-up-supported" + "number-up-supported", + "device-uri" }; /* Attributes we're interested in for printers without PPD */ @@ -1996,11 +1997,13 @@ typedef struct int number_of_covers; gchar *output_bin_default; GList *output_bin_supported; + gchar *original_device_uri; } PrinterSetupInfo; static void printer_setup_info_free (PrinterSetupInfo *info) { + g_free (info->original_device_uri); g_free (info->state_msg); g_strfreev (info->covers); g_slice_free (PrinterSetupInfo, info); @@ -2376,6 +2379,10 @@ cups_printer_handle_attribute (GtkPrintBackendCups *cups_backend, info->output_bin_supported = g_list_reverse (info->output_bin_supported); } + else if (g_strcmp0 (ippGetName (attr), "device-uri") == 0) + { + info->original_device_uri = g_strdup (ippGetString (attr, 0, NULL)); + } else { GTK_NOTE (PRINTING, @@ -2464,6 +2471,7 @@ cups_create_printer (GtkPrintBackendCups *cups_backend, cups_printer->default_cover_before = g_strdup (info->default_cover_before); cups_printer->default_cover_after = g_strdup (info->default_cover_after); + cups_printer->original_device_uri = g_strdup (info->original_device_uri); if (info->default_number_up > 0) cups_printer->default_number_up = info->default_number_up; @@ -2830,9 +2838,54 @@ typedef struct guint printer_state; gchar *type; gchar *domain; + gchar *UUID; GtkPrintBackendCups *backend; } AvahiConnectionTestData; +static GtkPrinter * +find_printer_by_uuid (GtkPrintBackendCups *backend, + const gchar *UUID) +{ + GtkPrinterCups *printer; + GtkPrinter *result = NULL; + GList *printers; + GList *iter; + gchar *printer_uuid; + + printers = gtk_print_backend_get_printer_list (GTK_PRINT_BACKEND (backend)); + for (iter = printers; iter != NULL; iter = iter->next) + { + printer = GTK_PRINTER_CUPS (iter->data); + if (printer->original_device_uri != NULL) + { + printer_uuid = g_strrstr (printer->original_device_uri, "uuid="); + if (printer_uuid != NULL && strlen (printer_uuid) >= 41) + { + printer_uuid += 5; + printer_uuid = g_strndup (printer_uuid, 36); + +#if GLIB_CHECK_VERSION(2, 52, 0) + if (g_uuid_string_is_valid (printer_uuid)) +#endif + { + if (g_strcmp0 (printer_uuid, UUID) == 0) + { + result = GTK_PRINTER (printer); + g_free (printer_uuid); + break; + } + } + + g_free (printer_uuid); + } + } + } + + g_list_free (printers); + + return result; +} + /* * Create new GtkPrinter from informations included in TXT records. */ @@ -2878,6 +2931,10 @@ create_cups_printer_from_avahi_data (AvahiConnectionTestData *data) set_info_state_message (info); printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (data->backend), data->printer_name); + + if (printer == NULL && data->UUID != NULL) + printer = find_printer_by_uuid (data->backend, data->UUID); + if (printer == NULL) { printer = cups_create_printer (data->backend, info); @@ -3080,6 +3137,11 @@ avahi_service_resolver_cb (GObject *source_object, if (data->printer_state != 0 || endptr != value) data->got_printer_state = TRUE; } + else if (g_strcmp0 (key, "UUID") == 0) + { + if (*value != '\0') + data->UUID = g_strdup (value); + } g_clear_pointer (&key, g_free); g_clear_pointer (&value, g_free); diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c index 4a94cbd09d..068aba74c5 100644 --- a/modules/printbackends/cups/gtkprintercups.c +++ b/modules/printbackends/cups/gtkprintercups.c @@ -100,6 +100,7 @@ static void gtk_printer_cups_init (GtkPrinterCups *printer) { printer->device_uri = NULL; + printer->original_device_uri = NULL; printer->printer_uri = NULL; printer->state = 0; printer->hostname = NULL; @@ -151,6 +152,7 @@ gtk_printer_cups_finalize (GObject *object) printer = GTK_PRINTER_CUPS (object); g_free (printer->device_uri); + g_free (printer->original_device_uri); g_free (printer->printer_uri); g_free (printer->hostname); g_free (printer->ppd_name); diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h index 837035a9c6..f26bbab677 100644 --- a/modules/printbackends/cups/gtkprintercups.h +++ b/modules/printbackends/cups/gtkprintercups.h @@ -48,6 +48,7 @@ struct _GtkPrinterCups GtkPrinter parent_instance; gchar *device_uri; + gchar *original_device_uri; gchar *printer_uri; gchar *hostname; gint port;