From e54049bc2678e6b4bcf0c888a742433bf71f7e1a Mon Sep 17 00:00:00 2001 From: Marek Kasik Date: Fri, 25 Jan 2019 16:41:24 +0100 Subject: [PATCH 1/2] printing: Don't show Rejecting Jobs when we don't know Set reasonable default values for printers discovered by Avahi which do not have 'printer-type' attribute. This is the case for network printers which were not published by CUPS. Related to the issue #1509. --- modules/printbackends/gtkprintbackendcups.c | 3 +++ 1 file changed, 3 insertions(+) diff --git a/modules/printbackends/gtkprintbackendcups.c b/modules/printbackends/gtkprintbackendcups.c index c0f6d98439..c47c4bafd4 100644 --- a/modules/printbackends/gtkprintbackendcups.c +++ b/modules/printbackends/gtkprintbackendcups.c @@ -2887,6 +2887,9 @@ create_cups_printer_from_avahi_data (AvahiConnectionTestData *data) info->avahi_printer = TRUE; info->printer_name = data->printer_name; info->printer_uri = data->printer_uri; + info->default_printer = FALSE; + info->remote_printer = TRUE; + info->is_accepting_jobs = TRUE; if (data->got_printer_state) { From a6e3fc2d2f1554211376a9bac6093f5ff264788c Mon Sep 17 00:00:00 2001 From: Marek Kasik Date: Thu, 12 Dec 2019 16:56:37 +0100 Subject: [PATCH 2/2] printing: Fix getting info for standalone IPP printers Create printer name from name of the advertised service for standalone IPP printers as opposed to CUPS printers advertised via Avahi which get name from their resource path. This is similar to what cups-filters does. Pass GtkPrinter class to request for printer info so that it does not need to be searched for (such search could fail for standalone IPP printers). https://gitlab.gnome.org/GNOME/gtk/issues/1509 --- modules/printbackends/gtkprintbackendcups.c | 135 +++++++++++++------- 1 file changed, 90 insertions(+), 45 deletions(-) diff --git a/modules/printbackends/gtkprintbackendcups.c b/modules/printbackends/gtkprintbackendcups.c index c47c4bafd4..db8a985d82 100644 --- a/modules/printbackends/gtkprintbackendcups.c +++ b/modules/printbackends/gtkprintbackendcups.c @@ -80,6 +80,7 @@ typedef struct _GtkPrintBackendCupsClass GtkPrintBackendCupsClass; #define AVAHI_SERVICE_BROWSER_IFACE "org.freedesktop.Avahi.ServiceBrowser" #define AVAHI_SERVICE_RESOLVER_IFACE "org.freedesktop.Avahi.ServiceResolver" +#define PRINTER_NAME_ALLOWED_CHARACTERS "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_" /* define this to see warnings about ignored ppd options */ #undef PRINT_IGNORED_OPTIONS @@ -1964,6 +1965,7 @@ typedef struct gboolean got_printer_type; gboolean remote_printer; gboolean avahi_printer; + gchar *avahi_resource_path; gchar **auth_info_required; gint default_number_up; guchar ipp_version_major; @@ -2406,8 +2408,11 @@ cups_create_printer (GtkPrintBackendCups *cups_backend, cups_printer = gtk_printer_cups_new (info->printer_name, backend, NULL); #endif - cups_printer->device_uri = g_strdup_printf ("/printers/%s", - info->printer_name); + if (info->avahi_printer) + { + cups_printer->device_uri = g_strdup_printf ("/%s", + info->avahi_resource_path); + } /* Check to see if we are looking at a class */ if (info->member_uris) @@ -2665,17 +2670,33 @@ set_default_printer (GtkPrintBackendCups *cups_backend, } } +typedef struct { + GtkPrinterCups *printer; + http_t *http; +} RequestPrinterInfoData; + +static void +request_printer_info_data_free (RequestPrinterInfoData *data) +{ + GTK_NOTE (PRINTING, + g_print ("CUPS Backend: %s\n", G_STRFUNC)); + httpClose (data->http); + g_object_unref (data->printer); + g_free (data); +} + static void cups_request_printer_info_cb (GtkPrintBackendCups *cups_backend, GtkCupsResult *result, gpointer user_data) { - PrinterSetupInfo *info = g_slice_new0 (PrinterSetupInfo); - GtkPrintBackend *backend = GTK_PRINT_BACKEND (cups_backend); - ipp_attribute_t *attr; - GtkPrinter *printer; - gboolean status_changed = FALSE; - ipp_t *response; + RequestPrinterInfoData *data = (RequestPrinterInfoData *) user_data; + PrinterSetupInfo *info = g_slice_new0 (PrinterSetupInfo); + GtkPrintBackend *backend = GTK_PRINT_BACKEND (cups_backend); + ipp_attribute_t *attr; + GtkPrinter *printer = g_object_ref (GTK_PRINTER (data->printer)); + gboolean status_changed = FALSE; + ipp_t *response; GTK_NOTE (PRINTING, g_print ("CUPS Backend: %s\n", G_STRFUNC)); @@ -2708,12 +2729,6 @@ cups_request_printer_info_cb (GtkPrintBackendCups *cups_backend, { set_info_state_message (info); - printer = gtk_print_backend_find_printer (backend, info->printer_name); - if (printer != NULL) - g_object_ref (printer); - else - goto done; - if (info->got_printer_type && info->default_printer && cups_backend->avahi_default_printer == NULL) @@ -2761,13 +2776,12 @@ cups_request_printer_info_cb (GtkPrintBackendCups *cups_backend, if (status_changed) g_signal_emit_by_name (GTK_PRINT_BACKEND (backend), "printer-status-changed", printer); - - /* The ref is held by GtkPrintBackend, in add_printer() */ - g_object_unref (printer); } } done: + g_object_unref (printer); + if (!cups_backend->got_default_printer && gtk_print_backend_printer_list_is_done (backend) && cups_backend->avahi_default_printer != NULL) @@ -2779,17 +2793,20 @@ done: } static void -cups_request_printer_info (const gchar *printer_uri, - const gchar *host, - gint port, - GtkPrintBackendCups *backend) +cups_request_printer_info (GtkPrinterCups *printer) { - GtkCupsRequest *request; - http_t *http; + RequestPrinterInfoData *data; + GtkPrintBackendCups *backend = GTK_PRINT_BACKEND_CUPS (gtk_printer_get_backend (GTK_PRINTER (printer))); + GtkCupsRequest *request; + http_t *http; - http = httpConnect2 (host, port, NULL, AF_UNSPEC, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL); + http = httpConnect2 (printer->hostname, printer->port, NULL, AF_UNSPEC, HTTP_ENCRYPTION_IF_REQUESTED, 1, 30000, NULL); if (http) { + data = g_new0 (RequestPrinterInfoData, 1); + data->http = http; + data->printer = g_object_ref (printer); + request = gtk_cups_request_new_with_username (http, GTK_CUPS_POST, IPP_GET_PRINTER_ATTRIBUTES, @@ -2801,7 +2818,7 @@ cups_request_printer_info (const gchar *printer_uri, gtk_cups_request_set_ipp_version (request, 1, 1); gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION, IPP_TAG_URI, - "printer-uri", NULL, printer_uri); + "printer-uri", NULL, printer->printer_uri); gtk_cups_request_ipp_add_strings (request, IPP_TAG_OPERATION, IPP_TAG_KEYWORD, "requested-attributes", G_N_ELEMENTS (printer_attrs_detailed), @@ -2810,8 +2827,8 @@ cups_request_printer_info (const gchar *printer_uri, cups_request_execute (backend, request, (GtkPrintCupsResponseCallbackFunc) cups_request_printer_info_cb, - http, - (GDestroyNotify) httpClose); + data, + (GDestroyNotify) request_printer_info_data_free); } } @@ -2823,6 +2840,7 @@ typedef struct gint port; gchar *printer_name; gchar *name; + gchar *resource_path; gboolean got_printer_type; guint printer_type; gboolean got_printer_state; @@ -2887,6 +2905,7 @@ create_cups_printer_from_avahi_data (AvahiConnectionTestData *data) info->avahi_printer = TRUE; info->printer_name = data->printer_name; info->printer_uri = data->printer_uri; + info->avahi_resource_path = data->resource_path; info->default_printer = FALSE; info->remote_printer = TRUE; info->is_accepting_jobs = TRUE; @@ -2923,7 +2942,6 @@ 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); @@ -2947,6 +2965,7 @@ create_cups_printer_from_avahi_data (AvahiConnectionTestData *data) GTK_PRINTER_CUPS (printer)->avahi_name = g_strdup (data->name); GTK_PRINTER_CUPS (printer)->avahi_type = g_strdup (data->type); GTK_PRINTER_CUPS (printer)->avahi_domain = g_strdup (data->domain); + GTK_PRINTER_CUPS (printer)->printer_uri = g_strdup (data->printer_uri); g_free (GTK_PRINTER_CUPS (printer)->hostname); GTK_PRINTER_CUPS (printer)->hostname = g_strdup (data->host); GTK_PRINTER_CUPS (printer)->port = data->port; @@ -3000,6 +3019,7 @@ avahi_connection_test_cb (GObject *source_object, g_free (data->host); g_free (data->printer_name); g_free (data->name); + g_free (data->resource_path); g_free (data->type); g_free (data->domain); g_free (data); @@ -3051,9 +3071,10 @@ avahi_service_resolver_cb (GObject *source_object, guint32 flags; guint16 port; GError *error = NULL; - gchar *queue_name = NULL; gchar *tmp; gchar *printer_name; + gchar **printer_name_strv; + gchar **printer_name_compressed_strv; gchar *endptr; gchar *key; gchar *value; @@ -3061,7 +3082,7 @@ avahi_service_resolver_cb (GObject *source_object, gint interface; gint protocol; gint aprotocol; - gint i; + gint i, j; output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object), res, @@ -3103,13 +3124,7 @@ avahi_service_resolver_cb (GObject *source_object, if (g_strcmp0 (key, "rp") == 0) { - queue_name = g_strdup (value); - - printer_name = g_strrstr (queue_name, "/"); - if (printer_name != NULL) - data->printer_name = g_strdup (printer_name + 1); - else - data->printer_name = g_strdup (queue_name); + data->resource_path = g_strdup (value); } else if (g_strcmp0 (key, "note") == 0) { @@ -3145,17 +3160,51 @@ avahi_service_resolver_cb (GObject *source_object, } } - if (queue_name) + if (data->resource_path != NULL) { + if (data->got_printer_type && + (g_strcmp0 (data->resource_path, "printers/") == 0 || + g_strcmp0 (data->resource_path, "classes/") == 0)) + { + /* This is a CUPS printer advertised via Avahi */ + printer_name = g_strrstr (data->resource_path, "/"); + if (printer_name != NULL && printer_name[0] != '\0') + data->printer_name = g_strdup (printer_name + 1); + else + data->printer_name = g_strdup (data->resource_path); + } + else + { + printer_name = g_strdup (name); + g_strcanon (printer_name, PRINTER_NAME_ALLOWED_CHARACTERS, '-'); + + printer_name_strv = g_strsplit_set (printer_name, "-", -1); + printer_name_compressed_strv = g_new0 (gchar *, g_strv_length (printer_name_strv)); + for (i = 0, j = 0; printer_name_strv[i] != NULL; i++) + { + if (printer_name_strv[i][0] != '\0') + { + printer_name_compressed_strv[j] = printer_name_strv[i]; + j++; + } + } + + data->printer_name = g_strjoinv ("-", printer_name_compressed_strv); + + g_strfreev (printer_name_strv); + g_free (printer_name_compressed_strv); + g_free (printer_name); + } + if (g_strcmp0 (type, "_ipp._tcp") == 0) protocol_string = "ipp"; else protocol_string = "ipps"; if (aprotocol == AVAHI_PROTO_INET6) - data->printer_uri = g_strdup_printf ("%s://[%s]:%u/%s", protocol_string, address, port, queue_name); + data->printer_uri = g_strdup_printf ("%s://[%s]:%u/%s", protocol_string, address, port, data->resource_path); else - data->printer_uri = g_strdup_printf ("%s://%s:%u/%s", protocol_string, address, port, queue_name); + data->printer_uri = g_strdup_printf ("%s://%s:%u/%s", protocol_string, address, port, data->resource_path); data->host = g_strdup (address); data->port = port; @@ -3172,7 +3221,6 @@ avahi_service_resolver_cb (GObject *source_object, backend->avahi_cancellable, avahi_connection_test_cb, data); - g_free (queue_name); } else { @@ -3811,10 +3859,7 @@ cups_request_ppd_cb (GtkPrintBackendCups *print_backend, if (cups_printer->request_original_uri) cups_printer->request_original_uri = FALSE; - cups_request_printer_info (cups_printer->printer_uri, - cups_printer->hostname, - cups_printer->port, - GTK_PRINT_BACKEND_CUPS (gtk_printer_get_backend (printer))); + cups_request_printer_info (cups_printer); } return;