#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
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;
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)
}
}
+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));
{
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)
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)
}
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,
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),
cups_request_execute (backend,
request,
(GtkPrintCupsResponseCallbackFunc) cups_request_printer_info_cb,
- http,
- (GDestroyNotify) httpClose);
+ data,
+ (GDestroyNotify) request_printer_info_data_free);
}
}
gint port;
gchar *printer_name;
gchar *name;
+ gchar *resource_path;
gboolean got_printer_type;
guint printer_type;
gboolean got_printer_state;
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;
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);
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;
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);
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;
gint interface;
gint protocol;
gint aprotocol;
- gint i;
+ gint i, j;
output = g_dbus_connection_call_finish (G_DBUS_CONNECTION (source_object),
res,
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)
{
}
}
- 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;
backend->avahi_cancellable,
avahi_connection_test_cb,
data);
- g_free (queue_name);
}
else
{
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;