X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=modules%2Fprintbackends%2Fcups%2Fgtkprintbackendcups.c;h=bc1f30508c1fdd7f06ca2e7daba9293ae7ef80fa;hb=9d0febc9a64a5bfb0fcfc3a88de4757f6c1ff090;hp=e45decfd5e68eb06b68724e602931e2e1256adc4;hpb=fd5035c2bdbb8f53d98f948e3ad0a69c52ecd7c1;p=~andy%2Fgtk
diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c
index e45decfd5..bc1f30508 100644
--- a/modules/printbackends/cups/gtkprintbackendcups.c
+++ b/modules/printbackends/cups/gtkprintbackendcups.c
@@ -14,17 +14,20 @@
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
- * License along with this library; if not, write to the
- * Free Software Foundation, Inc., 59 Temple Place - Suite 330,
- * Boston, MA 02111-1307, USA.
+ * License along with this library. If not, see .
*/
-#include
+#ifdef __linux__
+#define _GNU_SOURCE
+#endif
+
+#include "config.h"
#include
#include
#include
#include
#include
+#include
#include
#include
@@ -39,18 +42,19 @@
#include
#include
-#include
-#include
+#include
#include
-#include
+#include
#include
#include "gtkprintbackendcups.h"
#include "gtkprintercups.h"
#include "gtkcupsutils.h"
-#include "gtkdebug.h"
+#ifdef HAVE_COLORD
+#include
+#endif
typedef struct _GtkPrintBackendCupsClass GtkPrintBackendCupsClass;
@@ -89,8 +93,11 @@ typedef struct
http_t *http;
GtkCupsRequest *request;
+ GtkCupsPollState poll_state;
GPollFD *data_poll;
GtkPrintBackendCups *backend;
+ GtkPrintCupsResponseCallbackFunc callback;
+ gpointer callback_data;
} GtkPrintCupsDispatchWatch;
@@ -107,7 +114,22 @@ struct _GtkPrintBackendCups
guint list_printers_poll;
guint list_printers_pending : 1;
+ gint list_printers_attempts;
guint got_default_printer : 1;
+ guint default_printer_poll;
+ GtkCupsConnectionTest *cups_connection_test;
+ gint reading_ppds;
+
+ char **covers;
+ int number_of_covers;
+
+ GList *requests;
+ GHashTable *auth;
+ gchar *username;
+ gboolean authentication_lock;
+#ifdef HAVE_COLORD
+ CdClient *colord_client;
+#endif
};
static GObjectClass *backend_parent_class;
@@ -117,6 +139,8 @@ static void gtk_print_backend_cups_init (GtkPrintBack
static void gtk_print_backend_cups_finalize (GObject *object);
static void gtk_print_backend_cups_dispose (GObject *object);
static void cups_get_printer_list (GtkPrintBackend *print_backend);
+static void cups_get_default_printer (GtkPrintBackendCups *print_backend);
+static void cups_get_local_default_printer (GtkPrintBackendCups *print_backend);
static void cups_request_execute (GtkPrintBackendCups *print_backend,
GtkCupsRequest *request,
GtkPrintCupsResponseCallbackFunc callback,
@@ -138,13 +162,13 @@ static void cups_printer_prepare_for_print (GtkPrinter
static GList * cups_printer_list_papers (GtkPrinter *printer);
static GtkPageSetup * cups_printer_get_default_page_size (GtkPrinter *printer);
static void cups_printer_request_details (GtkPrinter *printer);
-static void cups_request_default_printer (GtkPrintBackendCups *print_backend);
-static void cups_request_ppd (GtkPrinter *printer);
-static void cups_printer_get_hard_margins (GtkPrinter *printer,
- double *top,
- double *bottom,
- double *left,
- double *right);
+static gboolean cups_request_default_printer (GtkPrintBackendCups *print_backend);
+static gboolean cups_request_ppd (GtkPrinter *printer);
+static gboolean cups_printer_get_hard_margins (GtkPrinter *printer,
+ gdouble *top,
+ gdouble *bottom,
+ gdouble *left,
+ gdouble *right);
static GtkPrintCapabilities cups_printer_get_capabilities (GtkPrinter *printer);
static void set_option_from_settings (GtkPrinterOption *option,
GtkPrintSettings *setting);
@@ -164,11 +188,18 @@ static cairo_surface_t * cups_printer_create_cairo_surface (GtkPrinter
gdouble height,
GIOChannel *cache_io);
+static void gtk_print_backend_cups_set_password (GtkPrintBackend *backend,
+ gchar **auth_info_required,
+ gchar **auth_info);
+
+void overwrite_and_free (gpointer data);
+static gboolean is_address_local (const gchar *address);
+static gboolean request_auth_info (gpointer data);
static void
gtk_print_backend_cups_register_type (GTypeModule *module)
{
- static const GTypeInfo print_backend_cups_info =
+ const GTypeInfo print_backend_cups_info =
{
sizeof (GtkPrintBackendCupsClass),
NULL, /* base_init */
@@ -259,6 +290,7 @@ gtk_print_backend_cups_class_init (GtkPrintBackendCupsClass *class)
backend_class->printer_get_default_page_size = cups_printer_get_default_page_size;
backend_class->printer_get_hard_margins = cups_printer_get_hard_margins;
backend_class->printer_get_capabilities = cups_printer_get_capabilities;
+ backend_class->set_password = gtk_print_backend_cups_set_password;
}
static cairo_status_t
@@ -290,7 +322,7 @@ _cairo_write_to_cups (void *closure,
}
GTK_NOTE (PRINTING,
- g_print ("CUPS Backend: Wrote %i bytes to temp file\n", written));
+ g_print ("CUPS Backend: Wrote %"G_GSIZE_FORMAT" bytes to temp file\n", written));
data += written;
length -= written;
@@ -306,14 +338,84 @@ cups_printer_create_cairo_surface (GtkPrinter *printer,
gdouble height,
GIOChannel *cache_io)
{
- cairo_surface_t *surface;
-
- /* TODO: check if it is a ps or pdf printer */
-
- surface = cairo_ps_surface_create_for_stream (_cairo_write_to_cups, cache_io, width, height);
+ cairo_surface_t *surface;
+ ppd_file_t *ppd_file = NULL;
+ ppd_attr_t *ppd_attr = NULL;
+ ppd_attr_t *ppd_attr_res = NULL;
+ ppd_attr_t *ppd_attr_screen_freq = NULL;
+ ppd_attr_t *ppd_attr_res_screen_freq = NULL;
+ gchar *res_string = NULL;
+ gint level = 2;
+
+ if (gtk_printer_accepts_pdf (printer))
+ surface = cairo_pdf_surface_create_for_stream (_cairo_write_to_cups, cache_io, width, height);
+ else
+ surface = cairo_ps_surface_create_for_stream (_cairo_write_to_cups, cache_io, width, height);
+
+ ppd_file = gtk_printer_cups_get_ppd (GTK_PRINTER_CUPS (printer));
+
+ if (ppd_file != NULL)
+ {
+ ppd_attr = ppdFindAttr (ppd_file, "LanguageLevel", NULL);
+
+ if (ppd_attr != NULL)
+ level = atoi (ppd_attr->value);
+
+ if (gtk_print_settings_get_resolution (settings) == 0)
+ {
+ ppd_attr_res = ppdFindAttr (ppd_file, "DefaultResolution", NULL);
+
+ if (ppd_attr_res != NULL)
+ {
+ int res, res_x, res_y;
+
+ if (sscanf (ppd_attr_res->value, "%dx%ddpi", &res_x, &res_y) == 2)
+ {
+ if (res_x > 0 && res_y > 0)
+ gtk_print_settings_set_resolution_xy (settings, res_x, res_y);
+ }
+ else if (sscanf (ppd_attr_res->value, "%ddpi", &res) == 1)
+ {
+ if (res > 0)
+ gtk_print_settings_set_resolution (settings, res);
+ }
+ }
+ }
+
+ res_string = g_strdup_printf ("%ddpi",
+ gtk_print_settings_get_resolution (settings));
+ ppd_attr_res_screen_freq = ppdFindAttr (ppd_file, "ResScreenFreq", res_string);
+ g_free (res_string);
+
+ if (ppd_attr_res_screen_freq == NULL)
+ {
+ res_string = g_strdup_printf ("%dx%ddpi",
+ gtk_print_settings_get_resolution_x (settings),
+ gtk_print_settings_get_resolution_y (settings));
+ ppd_attr_res_screen_freq = ppdFindAttr (ppd_file, "ResScreenFreq", res_string);
+ g_free (res_string);
+ }
+
+ ppd_attr_screen_freq = ppdFindAttr (ppd_file, "ScreenFreq", NULL);
+
+ if (ppd_attr_res_screen_freq != NULL && atof (ppd_attr_res_screen_freq->value) > 0.0)
+ gtk_print_settings_set_printer_lpi (settings, atof (ppd_attr_res_screen_freq->value));
+ else if (ppd_attr_screen_freq != NULL && atof (ppd_attr_screen_freq->value) > 0.0)
+ gtk_print_settings_set_printer_lpi (settings, atof (ppd_attr_screen_freq->value));
+ }
+
+ if (cairo_surface_get_type (surface) == CAIRO_SURFACE_TYPE_PS)
+ {
+ if (level == 2)
+ cairo_ps_surface_restrict_to_level (surface, CAIRO_PS_LEVEL_2);
+
+ if (level == 3)
+ cairo_ps_surface_restrict_to_level (surface, CAIRO_PS_LEVEL_3);
+ }
- /* TODO: DPI from settings object? */
- cairo_surface_set_fallback_resolution (surface, 300, 300);
+ cairo_surface_set_fallback_resolution (surface,
+ 2.0 * gtk_print_settings_get_printer_lpi (settings),
+ 2.0 * gtk_print_settings_get_printer_lpi (settings));
return surface;
}
@@ -385,22 +487,68 @@ cups_print_cb (GtkPrintBackendCups *print_backend,
GDK_THREADS_LEAVE ();
}
+typedef struct {
+ GtkCupsRequest *request;
+ GtkPrinterCups *printer;
+} CupsOptionsData;
+
static void
add_cups_options (const gchar *key,
const gchar *value,
gpointer user_data)
{
- GtkCupsRequest *request = user_data;
+ CupsOptionsData *data = (CupsOptionsData *) user_data;
+ GtkCupsRequest *request = data->request;
+ GtkPrinterCups *printer = data->printer;
+ gboolean custom_value = FALSE;
+ gchar *new_value = NULL;
+ gint i;
+
+ if (!key || !value)
+ return;
if (!g_str_has_prefix (key, "cups-"))
return;
if (strcmp (value, "gtk-ignore-value") == 0)
return;
-
+
key = key + strlen ("cups-");
- gtk_cups_request_encode_option (request, key, value);
+ if (printer && printer->ppd_file)
+ {
+ ppd_coption_t *coption;
+ gboolean found = FALSE;
+ gboolean custom_values_enabled = FALSE;
+
+ coption = ppdFindCustomOption (printer->ppd_file, key);
+ if (coption && coption->option)
+ {
+ for (i = 0; i < coption->option->num_choices; i++)
+ {
+ /* Are custom values enabled ? */
+ if (g_str_equal (coption->option->choices[i].choice, "Custom"))
+ custom_values_enabled = TRUE;
+
+ /* Is the value among available choices ? */
+ if (g_str_equal (coption->option->choices[i].choice, value))
+ found = TRUE;
+ }
+
+ if (custom_values_enabled && !found)
+ custom_value = TRUE;
+ }
+ }
+
+ /* Add "Custom." prefix to custom values. */
+ if (custom_value)
+ {
+ new_value = g_strdup_printf ("Custom.%s", value);
+ gtk_cups_request_encode_option (request, key, new_value);
+ g_free (new_value);
+ }
+ else
+ gtk_cups_request_encode_option (request, key, value);
}
static void
@@ -413,9 +561,11 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend,
{
GtkPrinterCups *cups_printer;
CupsPrintStreamData *ps;
+ CupsOptionsData *options_data;
GtkCupsRequest *request;
GtkPrintSettings *settings;
const gchar *title;
+ char printer_absolute_uri[HTTP_MAX_URI];
GTK_NOTE (PRINTING,
g_print ("CUPS Backend: %s\n", G_STRFUNC));
@@ -423,16 +573,35 @@ 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);
- request = gtk_cups_request_new (NULL,
- GTK_CUPS_POST,
- IPP_PRINT_JOB,
- data_io,
- cups_printer->hostname,
- cups_printer->device_uri);
+ request = gtk_cups_request_new_with_username (NULL,
+ GTK_CUPS_POST,
+ IPP_PRINT_JOB,
+ data_io,
+ NULL,
+ cups_printer->device_uri,
+ GTK_PRINT_BACKEND_CUPS (print_backend)->username);
+
+#if (CUPS_VERSION_MAJOR == 1 && CUPS_VERSION_MINOR >= 2) || CUPS_VERSION_MAJOR > 1
+ httpAssembleURIf (HTTP_URI_CODING_ALL,
+ printer_absolute_uri,
+ sizeof (printer_absolute_uri),
+ "ipp",
+ NULL,
+ "localhost",
+ ippPort (),
+ "/printers/%s",
+ gtk_printer_get_name (gtk_print_job_get_printer (job)));
+#else
+ g_snprintf (printer_absolute_uri,
+ sizeof (printer_absolute_uri),
+ "ipp://localhost:%d/printers/%s",
+ ippPort (),
+ gtk_printer_get_name (gtk_print_job_get_printer (job)));
+#endif
gtk_cups_request_ipp_add_string (request, IPP_TAG_OPERATION,
IPP_TAG_URI, "printer-uri",
- NULL, cups_printer->printer_uri);
+ NULL, printer_absolute_uri);
title = gtk_print_job_get_title (job);
if (title)
@@ -440,14 +609,21 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend,
IPP_TAG_NAME, "job-name",
NULL, title);
- gtk_print_settings_foreach (settings, add_cups_options, request);
-
+ options_data = g_new0 (CupsOptionsData, 1);
+ options_data->request = request;
+ options_data->printer = cups_printer;
+ gtk_print_settings_foreach (settings, add_cups_options, options_data);
+ g_free (options_data);
+
ps = g_new0 (CupsPrintStreamData, 1);
ps->callback = callback;
ps->user_data = user_data;
ps->dnotify = dnotify;
ps->job = g_object_ref (job);
+ request->need_auth_info = cups_printer->auth_info_required != NULL;
+ request->auth_info_required = g_strdupv (cups_printer->auth_info_required);
+
cups_request_execute (GTK_PRINT_BACKEND_CUPS (print_backend),
request,
(GtkPrintCupsResponseCallbackFunc) cups_print_cb,
@@ -455,6 +631,16 @@ gtk_print_backend_cups_print_stream (GtkPrintBackend *print_backend,
(GDestroyNotify)cups_free_print_stream_data);
}
+void overwrite_and_free (gpointer data)
+{
+ gchar *password = (gchar *) data;
+
+ if (password != NULL)
+ {
+ memset (password, 0, strlen (password));
+ g_free (password);
+ }
+}
static void
gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups)
@@ -462,8 +648,26 @@ gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups)
backend_cups->list_printers_poll = FALSE;
backend_cups->got_default_printer = FALSE;
backend_cups->list_printers_pending = FALSE;
+ backend_cups->list_printers_attempts = 0;
+ backend_cups->reading_ppds = 0;
- cups_request_default_printer (backend_cups);
+ backend_cups->requests = NULL;
+ backend_cups->auth = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, overwrite_and_free);
+ backend_cups->authentication_lock = FALSE;
+
+ backend_cups->covers = NULL;
+ backend_cups->number_of_covers = 0;
+
+ backend_cups->default_printer_poll = 0;
+ backend_cups->cups_connection_test = NULL;
+
+ backend_cups->username = NULL;
+
+#ifdef HAVE_COLORD
+ backend_cups->colord_client = cd_client_new ();
+#endif
+
+ cups_get_local_default_printer (backend_cups);
}
static void
@@ -478,7 +682,21 @@ gtk_print_backend_cups_finalize (GObject *object)
g_free (backend_cups->default_printer);
backend_cups->default_printer = NULL;
-
+
+ g_strfreev (backend_cups->covers);
+ backend_cups->number_of_covers = 0;
+
+ gtk_cups_connection_test_free (backend_cups->cups_connection_test);
+ backend_cups->cups_connection_test = NULL;
+
+ g_hash_table_destroy (backend_cups->auth);
+
+ g_free (backend_cups->username);
+
+#ifdef HAVE_COLORD
+ g_object_unref (backend_cups->colord_client);
+#endif
+
backend_parent_class->finalize (object);
}
@@ -495,60 +713,476 @@ gtk_print_backend_cups_dispose (GObject *object)
if (backend_cups->list_printers_poll > 0)
g_source_remove (backend_cups->list_printers_poll);
backend_cups->list_printers_poll = 0;
+ backend_cups->list_printers_attempts = 0;
+ if (backend_cups->default_printer_poll > 0)
+ g_source_remove (backend_cups->default_printer_poll);
+ backend_cups->default_printer_poll = 0;
+
backend_parent_class->dispose (object);
}
+static gboolean
+is_address_local (const gchar *address)
+{
+ if (address[0] == '/' ||
+ strcmp (address, "127.0.0.1") == 0 ||
+ strcmp (address, "[::1]") == 0)
+ return TRUE;
+ else
+ return FALSE;
+}
+
+#ifndef HAVE_CUPS_API_1_2
+/* Included from CUPS library because of backward compatibility */
+const char *
+httpGetHostname(http_t *http,
+ char *s,
+ int slen)
+{
+ struct hostent *host;
+
+ if (!s || slen <= 1)
+ return (NULL);
+
+ if (http)
+ {
+ if (http->hostname[0] == '/')
+ g_strlcpy (s, "localhost", slen);
+ else
+ g_strlcpy (s, http->hostname, slen);
+ }
+ else
+ {
+ if (gethostname (s, slen) < 0)
+ g_strlcpy (s, "localhost", slen);
+
+ if (!strchr (s, '.'))
+ {
+ if ((host = gethostbyname (s)) != NULL && host->h_name)
+ g_strlcpy (s, host->h_name, slen);
+ }
+ }
+ return (s);
+}
+#endif
+
+static void
+gtk_print_backend_cups_set_password (GtkPrintBackend *backend,
+ gchar **auth_info_required,
+ gchar **auth_info)
+{
+ GtkPrintBackendCups *cups_backend = GTK_PRINT_BACKEND_CUPS (backend);
+ GList *l;
+ char dispatch_hostname[HTTP_MAX_URI];
+ gchar *username = NULL;
+ gchar *hostname = NULL;
+ gchar *password = NULL;
+ gint length;
+ gint i;
+
+ length = g_strv_length (auth_info_required);
+
+ if (auth_info != NULL)
+ for (i = 0; i < length; i++)
+ {
+ if (g_strcmp0 (auth_info_required[i], "username") == 0)
+ username = g_strdup (auth_info[i]);
+ else if (g_strcmp0 (auth_info_required[i], "hostname") == 0)
+ hostname = g_strdup (auth_info[i]);
+ else if (g_strcmp0 (auth_info_required[i], "password") == 0)
+ password = g_strdup (auth_info[i]);
+ }
+
+ if (hostname != NULL && username != NULL && password != NULL)
+ {
+ gchar *key = g_strconcat (username, "@", hostname, NULL);
+ g_hash_table_insert (cups_backend->auth, key, g_strdup (password));
+ GTK_NOTE (PRINTING,
+ g_print ("CUPS backend: storing password for %s\n", key));
+ }
+
+ g_free (cups_backend->username);
+ cups_backend->username = g_strdup (username);
+
+
+ for (l = cups_backend->requests; l; l = l->next)
+ {
+ GtkPrintCupsDispatchWatch *dispatch = l->data;
+
+ httpGetHostname (dispatch->request->http, dispatch_hostname, sizeof (dispatch_hostname));
+ if (is_address_local (dispatch_hostname))
+ strcpy (dispatch_hostname, "localhost");
+
+ if (dispatch->request->need_auth_info)
+ {
+ if (auth_info != NULL)
+ {
+ dispatch->request->auth_info = g_new0 (gchar *, length + 1);
+ for (i = 0; i < length; i++)
+ dispatch->request->auth_info[i] = g_strdup (auth_info[i]);
+ }
+ dispatch->backend->authentication_lock = FALSE;
+ dispatch->request->need_auth_info = FALSE;
+ }
+ else if (dispatch->request->password_state == GTK_CUPS_PASSWORD_REQUESTED || auth_info == NULL)
+ {
+ overwrite_and_free (dispatch->request->password);
+ dispatch->request->password = g_strdup (password);
+ g_free (dispatch->request->username);
+ dispatch->request->username = g_strdup (username);
+ dispatch->request->password_state = GTK_CUPS_PASSWORD_HAS;
+ dispatch->backend->authentication_lock = FALSE;
+ }
+ }
+}
static gboolean
-cups_dispatch_watch_check (GSource *source)
+request_password (gpointer data)
+{
+ GtkPrintCupsDispatchWatch *dispatch = data;
+ const gchar *username;
+ gchar *password;
+ gchar *prompt = NULL;
+ gchar *key = NULL;
+ char hostname[HTTP_MAX_URI];
+ gchar **auth_info_required;
+ gchar **auth_info_default;
+ gchar **auth_info_display;
+ gboolean *auth_info_visible;
+ gint length = 3;
+ gint i;
+
+ if (dispatch->backend->authentication_lock)
+ return G_SOURCE_REMOVE;
+
+ httpGetHostname (dispatch->request->http, hostname, sizeof (hostname));
+ if (is_address_local (hostname))
+ strcpy (hostname, "localhost");
+
+ if (dispatch->backend->username != NULL)
+ username = dispatch->backend->username;
+ else
+ username = cupsUser ();
+
+ auth_info_required = g_new0 (gchar*, length + 1);
+ auth_info_required[0] = g_strdup ("hostname");
+ auth_info_required[1] = g_strdup ("username");
+ auth_info_required[2] = g_strdup ("password");
+
+ auth_info_default = g_new0 (gchar*, length + 1);
+ auth_info_default[0] = g_strdup (hostname);
+ auth_info_default[1] = g_strdup (username);
+
+ auth_info_display = g_new0 (gchar*, length + 1);
+ auth_info_display[1] = g_strdup (_("Username:"));
+ auth_info_display[2] = g_strdup (_("Password:"));
+
+ auth_info_visible = g_new0 (gboolean, length + 1);
+ auth_info_visible[1] = TRUE;
+
+ key = g_strconcat (username, "@", hostname, NULL);
+ password = g_hash_table_lookup (dispatch->backend->auth, key);
+
+ if (password && dispatch->request->password_state != GTK_CUPS_PASSWORD_NOT_VALID)
+ {
+ GTK_NOTE (PRINTING,
+ g_print ("CUPS backend: using stored password for %s\n", key));
+
+ overwrite_and_free (dispatch->request->password);
+ dispatch->request->password = g_strdup (password);
+ g_free (dispatch->request->username);
+ dispatch->request->username = g_strdup (username);
+ dispatch->request->password_state = GTK_CUPS_PASSWORD_HAS;
+ }
+ else
+ {
+ const char *job_title = gtk_cups_request_ipp_get_string (dispatch->request, IPP_TAG_NAME, "job-name");
+ const char *printer_uri = gtk_cups_request_ipp_get_string (dispatch->request, IPP_TAG_URI, "printer-uri");
+ char *printer_name = NULL;
+
+ if (printer_uri != NULL && strrchr (printer_uri, '/') != NULL)
+ printer_name = g_strdup (strrchr (printer_uri, '/') + 1);
+
+ if (dispatch->request->password_state == GTK_CUPS_PASSWORD_NOT_VALID)
+ g_hash_table_remove (dispatch->backend->auth, key);
+
+ dispatch->request->password_state = GTK_CUPS_PASSWORD_REQUESTED;
+
+ dispatch->backend->authentication_lock = TRUE;
+
+ switch (dispatch->request->ipp_request->request.op.operation_id)
+ {
+ case IPP_PRINT_JOB:
+ if (job_title != NULL && printer_name != NULL)
+ prompt = g_strdup_printf ( _("Authentication is required to print document '%s' on printer %s"), job_title, printer_name);
+ else
+ prompt = g_strdup_printf ( _("Authentication is required to print a document on %s"), hostname);
+ break;
+ case IPP_GET_JOB_ATTRIBUTES:
+ if (job_title != NULL)
+ prompt = g_strdup_printf ( _("Authentication is required to get attributes of job '%s'"), job_title);
+ else
+ prompt = g_strdup ( _("Authentication is required to get attributes of a job"));
+ break;
+ case IPP_GET_PRINTER_ATTRIBUTES:
+ if (printer_name != NULL)
+ prompt = g_strdup_printf ( _("Authentication is required to get attributes of printer %s"), printer_name);
+ else
+ prompt = g_strdup ( _("Authentication is required to get attributes of a printer"));
+ break;
+ case CUPS_GET_DEFAULT:
+ prompt = g_strdup_printf ( _("Authentication is required to get default printer of %s"), hostname);
+ break;
+ case CUPS_GET_PRINTERS:
+ prompt = g_strdup_printf ( _("Authentication is required to get printers from %s"), hostname);
+ break;
+ default:
+ /* work around gcc warning about 0 not being a value for this enum */
+ if (dispatch->request->ipp_request->request.op.operation_id == 0)
+ prompt = g_strdup_printf ( _("Authentication is required to get a file from %s"), hostname);
+ else
+ prompt = g_strdup_printf ( _("Authentication is required on %s"), hostname);
+ break;
+ }
+
+ g_free (printer_name);
+
+ g_signal_emit_by_name (dispatch->backend, "request-password",
+ auth_info_required, auth_info_default, auth_info_display, auth_info_visible, prompt);
+
+ g_free (prompt);
+ }
+
+ for (i = 0; i < length; i++)
+ {
+ g_free (auth_info_required[i]);
+ g_free (auth_info_default[i]);
+ g_free (auth_info_display[i]);
+ }
+
+ g_free (auth_info_required);
+ g_free (auth_info_default);
+ g_free (auth_info_display);
+ g_free (auth_info_visible);
+ g_free (key);
+
+ return G_SOURCE_REMOVE;
+}
+
+static void
+cups_dispatch_add_poll (GSource *source)
{
GtkPrintCupsDispatchWatch *dispatch;
GtkCupsPollState poll_state;
- gboolean result;
-
- GTK_NOTE (PRINTING,
- g_print ("CUPS Backend: %s