diff options
author | Matthias Clasen <mclasen@redhat.com> | 2008-09-17 22:07:10 +0000 |
---|---|---|
committer | Matthias Clasen <matthiasc@src.gnome.org> | 2008-09-17 22:07:10 +0000 |
commit | 8ec27f776004b14839742829a85be9e580ff2799 (patch) | |
tree | 021114df61a35a9a48121b0e49ecb2aea5300ca3 /modules | |
parent | df619a1370273305726416fc5eb04b46c267915c (diff) | |
download | gtk+-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.c | 38 | ||||
-rw-r--r-- | modules/printbackends/cups/gtkcupsutils.h | 86 | ||||
-rw-r--r-- | modules/printbackends/cups/gtkprintbackendcups.c | 163 |
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, |