summaryrefslogtreecommitdiff
path: root/modules
diff options
context:
space:
mode:
authorMatthias Clasen <mclasen@redhat.com>2008-09-17 22:07:10 +0000
committerMatthias Clasen <matthiasc@src.gnome.org>2008-09-17 22:07:10 +0000
commit8ec27f776004b14839742829a85be9e580ff2799 (patch)
tree021114df61a35a9a48121b0e49ecb2aea5300ca3 /modules
parentdf619a1370273305726416fc5eb04b46c267915c (diff)
downloadgtk+-8ec27f776004b14839742829a85be9e580ff2799.tar.gz
Bug 346903 – gtk_enumerate_printers needs events to complete
2008-09-17 Matthias Clasen <mclasen@redhat.com> Bug 346903 – gtk_enumerate_printers needs events to complete * gtk/gtkprintbackend.h: * gtk/gtkprintbackend.c: Add a GtkPrintBackend::status property. * modules/printbackends/cups/gtkcupsutils.h: * modules/printbackends/cups/gtkcupsutils.c: Turn the connection test into a tristate available/unavailable/in progress. * modules/printbackends/cups/gtkprintbackendcups.c: Use a single connection test instance for getting the default printer and for getting the printer list. Set the GtkPrintBackend::status property according to the result of the connection test. Use the printer-type attribute to find the default printer, if cups supports it. * gtk/gtkprinter.c: When enumerating printers, give up when the backend status is 'unavailable'. * gtk/gtkprintunixdialog.c (printer_status_cb): Select the printer when it is the default and nothing else has been selected yet. svn path=/trunk/; revision=21417
Diffstat (limited to 'modules')
-rw-r--r--modules/printbackends/cups/gtkcupsutils.c38
-rw-r--r--modules/printbackends/cups/gtkcupsutils.h86
-rw-r--r--modules/printbackends/cups/gtkprintbackendcups.c163
3 files changed, 187 insertions, 100 deletions
diff --git a/modules/printbackends/cups/gtkcupsutils.c b/modules/printbackends/cups/gtkcupsutils.c
index 8abe8021e4..363f8f52e7 100644
--- a/modules/printbackends/cups/gtkcupsutils.c
+++ b/modules/printbackends/cups/gtkcupsutils.c
@@ -1220,9 +1220,9 @@ gtk_cups_connection_test_new (const char *server)
result->socket = -1;
result->current_addr = NULL;
- result->success_at_init = FALSE;
+ result->at_init = GTK_CUPS_CONNECTION_NOT_AVAILABLE;
- result->success_at_init = gtk_cups_connection_test_is_server_available (result);
+ result->at_init = gtk_cups_connection_test_get_state (result);
#else
result = g_new (GtkCupsConnectionTest, 1);
#endif
@@ -1236,22 +1236,23 @@ gtk_cups_connection_test_new (const char *server)
* - you need to check it more then once.
* The connection is closed after a successful connection.
*/
-gboolean
-gtk_cups_connection_test_is_server_available (GtkCupsConnectionTest *test)
+GtkCupsConnectionState
+gtk_cups_connection_test_get_state (GtkCupsConnectionTest *test)
{
#ifdef HAVE_CUPS_API_1_2
- http_addrlist_t *iter;
- gboolean result = FALSE;
- gint flags;
- gint code;
+ GtkCupsConnectionState result = GTK_CUPS_CONNECTION_NOT_AVAILABLE;
+ http_addrlist_t *iter;
+ gint error_code;
+ gint flags;
+ gint code;
if (test == NULL)
- return FALSE;
+ return GTK_CUPS_CONNECTION_NOT_AVAILABLE;
- if (test->success_at_init)
+ if (test->at_init == GTK_CUPS_CONNECTION_AVAILABLE)
{
- test->success_at_init = FALSE;
- return TRUE;
+ test->at_init = GTK_CUPS_CONNECTION_NOT_AVAILABLE;
+ return GTK_CUPS_CONNECTION_AVAILABLE;
}
else
{
@@ -1287,21 +1288,28 @@ gtk_cups_connection_test_is_server_available (GtkCupsConnectionTest *test)
&test->current_addr->addr.addr,
httpAddrLength (&test->current_addr->addr));
+ error_code = errno;
+
if (code == 0)
{
close (test->socket);
test->socket = -1;
test->current_addr = NULL;
- result = TRUE;
+ result = GTK_CUPS_CONNECTION_AVAILABLE;
}
else
- result = FALSE;
+ {
+ if (error_code == EALREADY || error_code == EINPROGRESS)
+ result = GTK_CUPS_CONNECTION_IN_PROGRESS;
+ else
+ result = GTK_CUPS_CONNECTION_NOT_AVAILABLE;
+ }
}
return result;
}
#else
- return TRUE;
+ return GTK_CUPS_CONNECTION_AVAILABLE;
#endif
}
diff --git a/modules/printbackends/cups/gtkcupsutils.h b/modules/printbackends/cups/gtkcupsutils.h
index a6314bb8a5..dcbb490ab6 100644
--- a/modules/printbackends/cups/gtkcupsutils.h
+++ b/modules/printbackends/cups/gtkcupsutils.h
@@ -59,6 +59,12 @@ typedef enum
GTK_CUPS_HTTP_WRITE
} GtkCupsPollState;
+typedef enum
+{
+ GTK_CUPS_CONNECTION_AVAILABLE,
+ GTK_CUPS_CONNECTION_NOT_AVAILABLE,
+ GTK_CUPS_CONNECTION_IN_PROGRESS
+} GtkCupsConnectionState;
struct _GtkCupsRequest
{
@@ -84,10 +90,10 @@ struct _GtkCupsRequest
struct _GtkCupsConnectionTest
{
#ifdef HAVE_CUPS_API_1_2
- http_addrlist_t *addrlist;
- http_addrlist_t *current_addr;
- gboolean success_at_init;
- gint socket;
+ GtkCupsConnectionState at_init;
+ http_addrlist_t *addrlist;
+ http_addrlist_t *current_addr;
+ gint socket;
#endif
};
@@ -116,42 +122,42 @@ enum
GTK_CUPS_GET_DONE = GTK_CUPS_REQUEST_DONE
};
-GtkCupsRequest * gtk_cups_request_new (http_t *connection,
- GtkCupsRequestType req_type,
- gint operation_id,
- GIOChannel *data_io,
- const char *server,
- const char *resource);
-void gtk_cups_request_ipp_add_string (GtkCupsRequest *request,
- ipp_tag_t group,
- ipp_tag_t tag,
- const char *name,
- const char *charset,
- const char *value);
-void gtk_cups_request_ipp_add_strings (GtkCupsRequest *request,
- ipp_tag_t group,
- ipp_tag_t tag,
- const char *name,
- int num_values,
- const char *charset,
- const char * const *values);
-gboolean gtk_cups_request_read_write (GtkCupsRequest *request);
-GtkCupsPollState gtk_cups_request_get_poll_state (GtkCupsRequest *request);
-void gtk_cups_request_free (GtkCupsRequest *request);
-GtkCupsResult * gtk_cups_request_get_result (GtkCupsRequest *request);
-gboolean gtk_cups_request_is_done (GtkCupsRequest *request);
-void gtk_cups_request_encode_option (GtkCupsRequest *request,
- const gchar *option,
- const gchar *value);
-gboolean gtk_cups_result_is_error (GtkCupsResult *result);
-ipp_t * gtk_cups_result_get_response (GtkCupsResult *result);
-GtkCupsErrorType gtk_cups_result_get_error_type (GtkCupsResult *result);
-int gtk_cups_result_get_error_status (GtkCupsResult *result);
-int gtk_cups_result_get_error_code (GtkCupsResult *result);
-const char * gtk_cups_result_get_error_string (GtkCupsResult *result);
-GtkCupsConnectionTest * gtk_cups_connection_test_new (const char *server);
-gboolean gtk_cups_connection_test_is_server_available (GtkCupsConnectionTest *test);
-void gtk_cups_connection_test_free (GtkCupsConnectionTest *test);
+GtkCupsRequest * gtk_cups_request_new (http_t *connection,
+ GtkCupsRequestType req_type,
+ gint operation_id,
+ GIOChannel *data_io,
+ const char *server,
+ const char *resource);
+void gtk_cups_request_ipp_add_string (GtkCupsRequest *request,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ const char *charset,
+ const char *value);
+void gtk_cups_request_ipp_add_strings (GtkCupsRequest *request,
+ ipp_tag_t group,
+ ipp_tag_t tag,
+ const char *name,
+ int num_values,
+ const char *charset,
+ const char * const *values);
+gboolean gtk_cups_request_read_write (GtkCupsRequest *request);
+GtkCupsPollState gtk_cups_request_get_poll_state (GtkCupsRequest *request);
+void gtk_cups_request_free (GtkCupsRequest *request);
+GtkCupsResult * gtk_cups_request_get_result (GtkCupsRequest *request);
+gboolean gtk_cups_request_is_done (GtkCupsRequest *request);
+void gtk_cups_request_encode_option (GtkCupsRequest *request,
+ const gchar *option,
+ const gchar *value);
+gboolean gtk_cups_result_is_error (GtkCupsResult *result);
+ipp_t * gtk_cups_result_get_response (GtkCupsResult *result);
+GtkCupsErrorType gtk_cups_result_get_error_type (GtkCupsResult *result);
+int gtk_cups_result_get_error_status (GtkCupsResult *result);
+int gtk_cups_result_get_error_code (GtkCupsResult *result);
+const char * gtk_cups_result_get_error_string (GtkCupsResult *result);
+GtkCupsConnectionTest * gtk_cups_connection_test_new (const char *server);
+GtkCupsConnectionState gtk_cups_connection_test_get_state (GtkCupsConnectionTest *test);
+void gtk_cups_connection_test_free (GtkCupsConnectionTest *test);
G_END_DECLS
#endif
diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c
index 4fe6748a3c..d4544c823e 100644
--- a/modules/printbackends/cups/gtkprintbackendcups.c
+++ b/modules/printbackends/cups/gtkprintbackendcups.c
@@ -107,7 +107,7 @@ struct _GtkPrintBackendCups
guint list_printers_pending : 1;
guint got_default_printer : 1;
guint default_printer_poll;
- GtkCupsConnectionTest *default_printer_connection_test;
+ GtkCupsConnectionTest *cups_connection_test;
char **covers;
char *default_cover_before;
@@ -123,6 +123,7 @@ static void gtk_print_backend_cups_finalize (GObject
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,
@@ -513,9 +514,9 @@ gtk_print_backend_cups_init (GtkPrintBackendCups *backend_cups)
backend_cups->number_of_covers = 0;
backend_cups->default_printer_poll = 0;
- backend_cups->default_printer_connection_test = NULL;
+ backend_cups->cups_connection_test = NULL;
- cups_get_default_printer (backend_cups);
+ cups_get_local_default_printer (backend_cups);
}
static void
@@ -537,8 +538,9 @@ gtk_print_backend_cups_finalize (GObject *object)
g_free (backend_cups->default_cover_before);
g_free (backend_cups->default_cover_after);
- gtk_cups_connection_test_free (backend_cups->default_printer_connection_test);
-
+ gtk_cups_connection_test_free (backend_cups->cups_connection_test);
+ backend_cups->cups_connection_test = NULL;
+
backend_parent_class->finalize (object);
}
@@ -1130,6 +1132,8 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
};
gboolean is_paused = FALSE;
gboolean is_accepting_jobs = TRUE;
+ gboolean default_printer = FALSE;
+ gboolean got_printer_type = FALSE;
/* Skip leading attributes until we hit a printer...
*/
@@ -1240,6 +1244,14 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
}
}
}
+ else if (strcmp (attr->name, "printer-type") == 0)
+ {
+ got_printer_type = TRUE;
+ if (attr->values[0].integer & 0x00020000)
+ default_printer = TRUE;
+ else
+ default_printer = FALSE;
+ }
else
{
GTK_NOTE (PRINTING,
@@ -1257,7 +1269,21 @@ cups_request_printer_list_cb (GtkPrintBackendCups *cups_backend,
else
continue;
}
-
+
+ if (got_printer_type)
+ {
+ if (default_printer && !cups_backend->got_default_printer)
+ {
+ cups_backend->got_default_printer = TRUE;
+ cups_backend->default_printer = g_strdup (printer_name);
+ }
+ }
+ else
+ {
+ if (!cups_backend->got_default_printer)
+ cups_get_default_printer (cups_backend);
+ }
+
/* remove name from checklist if it was found */
node = g_list_find_custom (removed_printer_checklist, printer_name, (GCompareFunc) find_printer);
removed_printer_checklist = g_list_delete_link (removed_printer_checklist, node);
@@ -1473,9 +1499,26 @@ done:
GDK_THREADS_LEAVE ();
}
+static void
+update_backend_status (GtkPrintBackendCups *cups_backend,
+ GtkCupsConnectionState state)
+{
+ switch (state)
+ {
+ case GTK_CUPS_CONNECTION_NOT_AVAILABLE:
+ g_object_set (cups_backend, "status", GTK_PRINT_BACKEND_STATUS_UNAVAILABLE, NULL);
+ break;
+ case GTK_CUPS_CONNECTION_AVAILABLE:
+ g_object_set (cups_backend, "status", GTK_PRINT_BACKEND_STATUS_OK, NULL);
+ break;
+ default: ;
+ }
+}
+
static gboolean
cups_request_printer_list (GtkPrintBackendCups *cups_backend)
{
+ GtkCupsConnectionState state;
GtkCupsRequest *request;
static const char * const pattrs[] = /* Attributes we're interested in */
{
@@ -1490,11 +1533,17 @@ cups_request_printer_list (GtkPrintBackendCups *cups_backend)
"queued-job-count",
"printer-is-accepting-jobs",
"job-sheets-supported",
- "job-sheets-default"
+ "job-sheets-default",
+ "printer-type"
};
-
- if (cups_backend->list_printers_pending ||
- !cups_backend->got_default_printer)
+
+ if (cups_backend->list_printers_pending)
+ return TRUE;
+
+ state = gtk_cups_connection_test_get_state (cups_backend->cups_connection_test);
+ update_backend_status (cups_backend, state);
+
+ if (state == GTK_CUPS_CONNECTION_IN_PROGRESS || state == GTK_CUPS_CONNECTION_NOT_AVAILABLE)
return TRUE;
cups_backend->list_printers_pending = TRUE;
@@ -1525,10 +1574,14 @@ cups_get_printer_list (GtkPrintBackend *backend)
GtkPrintBackendCups *cups_backend;
cups_backend = GTK_PRINT_BACKEND_CUPS (backend);
+
+ if (cups_backend->cups_connection_test == NULL)
+ cups_backend->cups_connection_test = gtk_cups_connection_test_new (NULL);
+
if (cups_backend->list_printers_poll == 0)
{
- cups_request_printer_list (cups_backend);
- cups_backend->list_printers_poll = gdk_threads_add_timeout_seconds (3,
+ if (cups_request_printer_list (cups_backend))
+ cups_backend->list_printers_poll = gdk_threads_add_timeout_seconds (3,
(GSourceFunc) cups_request_printer_list,
backend);
}
@@ -1850,13 +1903,46 @@ cups_get_default_printer (GtkPrintBackendCups *backend)
cups_backend = backend;
- cups_backend->default_printer_connection_test = gtk_cups_connection_test_new (NULL);
+ if (cups_backend->cups_connection_test == NULL)
+ cups_backend->cups_connection_test = gtk_cups_connection_test_new (NULL);
+
if (cups_backend->default_printer_poll == 0)
{
if (cups_request_default_printer (cups_backend))
- cups_backend->default_printer_poll = gdk_threads_add_timeout_seconds (1,
- (GSourceFunc) cups_request_default_printer,
- backend);
+ cups_backend->default_printer_poll = gdk_threads_add_timeout (500,
+ (GSourceFunc) cups_request_default_printer,
+ backend);
+ }
+}
+
+/* This function gets default printer from local settings.*/
+static void
+cups_get_local_default_printer (GtkPrintBackendCups *backend)
+{
+ const char *str;
+ char *name = NULL;
+
+ if ((str = g_getenv ("LPDEST")) != NULL)
+ {
+ backend->default_printer = g_strdup (str);
+ backend->got_default_printer = TRUE;
+ return;
+ }
+ else if ((str = g_getenv ("PRINTER")) != NULL &&
+ strcmp (str, "lp") != 0)
+ {
+ backend->default_printer = g_strdup (str);
+ backend->got_default_printer = TRUE;
+ return;
+ }
+
+ /* Figure out user setting for default printer */
+ cups_get_user_default_printer (&name);
+ if (name != NULL)
+ {
+ backend->default_printer = name;
+ backend->got_default_printer = TRUE;
+ return;
}
}
@@ -1867,6 +1953,7 @@ cups_request_default_printer_cb (GtkPrintBackendCups *print_backend,
{
ipp_t *response;
ipp_attribute_t *attr;
+ GtkPrinter *printer;
GDK_THREADS_ENTER ();
@@ -1877,6 +1964,16 @@ cups_request_default_printer_cb (GtkPrintBackendCups *print_backend,
print_backend->got_default_printer = TRUE;
+ if (print_backend->default_printer != NULL)
+ {
+ printer = gtk_print_backend_find_printer (GTK_PRINT_BACKEND (print_backend), print_backend->default_printer);
+ if (printer != NULL)
+ {
+ gtk_printer_set_is_default (printer, TRUE);
+ g_signal_emit_by_name (GTK_PRINT_BACKEND (print_backend), "printer-status-changed", printer);
+ }
+ }
+
/* Make sure to kick off get_printers if we are polling it,
* as we could have blocked this reading the default printer
*/
@@ -1889,38 +1986,14 @@ cups_request_default_printer_cb (GtkPrintBackendCups *print_backend,
static gboolean
cups_request_default_printer (GtkPrintBackendCups *print_backend)
{
+ GtkCupsConnectionState state;
GtkCupsRequest *request;
- const char *str;
- char *name = NULL;
-
- if (!gtk_cups_connection_test_is_server_available (print_backend->default_printer_connection_test))
- return TRUE;
- gtk_cups_connection_test_free (print_backend->default_printer_connection_test);
- print_backend->default_printer_connection_test = NULL;
+ state = gtk_cups_connection_test_get_state (print_backend->cups_connection_test);
+ update_backend_status (print_backend, state);
- if ((str = g_getenv ("LPDEST")) != NULL)
- {
- print_backend->default_printer = g_strdup (str);
- print_backend->got_default_printer = TRUE;
- return FALSE;
- }
- else if ((str = g_getenv ("PRINTER")) != NULL &&
- strcmp (str, "lp") != 0)
- {
- print_backend->default_printer = g_strdup (str);
- print_backend->got_default_printer = TRUE;
- return FALSE;
- }
-
- /* Figure out user setting for default printer */
- cups_get_user_default_printer (&name);
- if (name != NULL)
- {
- print_backend->default_printer = name;
- print_backend->got_default_printer = TRUE;
- return FALSE;
- }
+ if (state == GTK_CUPS_CONNECTION_IN_PROGRESS || state == GTK_CUPS_CONNECTION_NOT_AVAILABLE)
+ return TRUE;
request = gtk_cups_request_new (NULL,
GTK_CUPS_POST,