Compare commits

...

2 Commits

Author SHA1 Message Date
Marek Kasik
c4c3eeb38f 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
2019-02-26 18:47:19 +01:00
Marek Kasik
68bf781e63 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.
2019-01-25 16:50:28 +01:00

View File

@@ -81,6 +81,8 @@ typedef struct _GtkPrintBackendCupsClass GtkPrintBackendCupsClass;
#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"
#define PRINTER_NAME_ALLOWED_CHARACTERS "abcdefghijklmnopqrtsuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ0123456789-_"
#endif
/* define this to see warnings about ignored ppd options */
@@ -1961,6 +1963,7 @@ typedef struct
gboolean remote_printer;
#ifdef HAVE_CUPS_API_1_6
gboolean avahi_printer;
gchar *avahi_resource_path;
#endif
gchar **auth_info_required;
gint default_number_up;
@@ -2406,8 +2409,19 @@ 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);
#ifdef HAVE_CUPS_API_1_6
if (info->avahi_printer)
{
cups_printer->device_uri = g_strdup_printf ("/%s",
info->avahi_resource_path);
}
else
#else
{
cups_printer->device_uri = g_strdup_printf ("/printers/%s",
info->printer_name);
}
#endif
/* Check to see if we are looking at a class */
if (info->member_uris)
@@ -2656,17 +2670,33 @@ set_default_printer (GtkPrintBackendCups *cups_backend,
}
#ifdef HAVE_CUPS_API_1_6
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));
@@ -2699,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)
@@ -2752,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)
@@ -2770,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 = httpConnect (host, port);
if (http)
http = httpConnect (printer->hostname, printer->port);
if (http != NULL)
{
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,
@@ -2792,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),
@@ -2801,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);
}
}
@@ -2814,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;
@@ -2880,6 +2907,10 @@ 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;
if (data->got_printer_state)
{
@@ -2913,7 +2944,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);
@@ -2937,6 +2967,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;
@@ -2990,6 +3021,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);
@@ -3041,9 +3073,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;
@@ -3051,7 +3084,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,
@@ -3093,13 +3126,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)
{
@@ -3135,17 +3162,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;
@@ -3162,7 +3223,6 @@ avahi_service_resolver_cb (GObject *source_object,
backend->avahi_cancellable,
avahi_connection_test_cb,
data);
g_free (queue_name);
}
else
{
@@ -3817,10 +3877,7 @@ cups_request_ppd_cb (GtkPrintBackendCups *print_backend,
((gtk_cups_result_get_error_type (result) == GTK_CUPS_ERROR_HTTP) &&
(gtk_cups_result_get_error_status (result) == HTTP_NOT_FOUND))))
{
cups_request_printer_info (GTK_PRINTER_CUPS (printer)->printer_uri,
GTK_PRINTER_CUPS (printer)->hostname,
GTK_PRINTER_CUPS (printer)->port,
GTK_PRINT_BACKEND_CUPS (gtk_printer_get_backend (printer)));
cups_request_printer_info (GTK_PRINTER_CUPS (printer));
return;
}