diff options
author | Marek Kasik <mkasik@redhat.com> | 2014-10-10 13:36:30 +0200 |
---|---|---|
committer | Marek Kasik <mkasik@redhat.com> | 2014-10-13 11:58:18 +0200 |
commit | 493aa4e9b3b7ef673a3f0a7b49a6416e9ad8c5c2 (patch) | |
tree | 702ec5f6b0794de4378ebad913ec1d365c3e3917 /modules | |
parent | ea21c4563b8b9d977722436a9b43657435e6c5e8 (diff) | |
download | gtk+-493aa4e9b3b7ef673a3f0a7b49a6416e9ad8c5c2.tar.gz |
Get duplex option via IPP
Request "sides-supported" and "sides-default" attributes through
IPP if there is no PPD for selected printer.
Pass "sides" option with other options in printer_get_options().
Add function setup_ipp_option() for creating of IPP option
of given name with passed choices and default value.
Mark such an option as "is-ipp-option" so we can distinguish it
later.
https://bugzilla.gnome.org/show_bug.cgi?id=725441
Diffstat (limited to 'modules')
-rw-r--r-- | modules/printbackends/cups/gtkprintbackendcups.c | 290 | ||||
-rw-r--r-- | modules/printbackends/cups/gtkprintercups.c | 5 | ||||
-rw-r--r-- | modules/printbackends/cups/gtkprintercups.h | 2 |
3 files changed, 276 insertions, 21 deletions
diff --git a/modules/printbackends/cups/gtkprintbackendcups.c b/modules/printbackends/cups/gtkprintbackendcups.c index 7cdb43ebaf..db2f5557ed 100644 --- a/modules/printbackends/cups/gtkprintbackendcups.c +++ b/modules/printbackends/cups/gtkprintbackendcups.c @@ -360,6 +360,26 @@ gtk_print_backend_cups_class_init (GtkPrintBackendCupsClass *class) backend_class->set_password = gtk_print_backend_cups_set_password; } +static gboolean +option_is_ipp_option (GtkPrinterOption *option) +{ + gpointer data = g_object_get_data (G_OBJECT (option), "is-ipp-option"); + + if (data != NULL) + return GPOINTER_TO_UINT (data) != 0; + else + return FALSE; +} + +static void +option_set_is_ipp_option (GtkPrinterOption *option, + gboolean is_ipp_option) +{ + g_object_set_data (G_OBJECT (option), + "is-ipp-option", + GUINT_TO_POINTER (is_ipp_option ? 1 : 0)); +} + static cairo_status_t _cairo_write_to_cups (void *closure, const unsigned char *data, @@ -1891,6 +1911,8 @@ static const char * const printer_attrs_detailed[] = "media-right-margin-supported", "media-bottom-margin-supported", "media-top-margin-supported", + "sides-default", + "sides-supported", }; typedef enum @@ -1944,6 +1966,8 @@ typedef struct float media_left_margin_default; float media_right_margin_default; gboolean media_margin_default_set; + gchar *sides_default; + GList *sides_supported; } PrinterSetupInfo; static void @@ -2200,6 +2224,17 @@ cups_printer_handle_attribute (GtkPrintBackendCups *cups_backend, } } } + else if (g_strcmp0 (ippGetName (attr), "sides-default") == 0) + { + info->sides_default = g_strdup (ippGetString (attr, 0, NULL)); + } + else if (g_strcmp0 (ippGetName (attr), "sides-supported") == 0) + { + for (i = 0; i < ippGetCount (attr); i++) + info->sides_supported = g_list_prepend (info->sides_supported, g_strdup (ippGetString (attr, i, NULL))); + + info->sides_supported = g_list_reverse (info->sides_supported); + } else if (g_strcmp0 (ippGetName (attr), "media-default") == 0) { if (ippGetValueTag (attr) == IPP_TAG_KEYWORD || @@ -2606,6 +2641,8 @@ cups_request_printer_info_cb (GtkPrintBackendCups *cups_backend, GTK_PRINTER_CUPS (printer)->media_left_margin_default = info->media_left_margin_default; GTK_PRINTER_CUPS (printer)->media_right_margin_default = info->media_right_margin_default; } + GTK_PRINTER_CUPS (printer)->sides_default = info->sides_default; + GTK_PRINTER_CUPS (printer)->sides_supported = info->sides_supported; gtk_printer_set_has_details (printer, TRUE); g_signal_emit_by_name (printer, "details-acquired", TRUE); @@ -4222,6 +4259,26 @@ static const struct { }; static const struct { + const char *ipp_option_name; + const char *gtk_option_name; + const char *translation; +} ipp_option_translations[] = { + { "sides", "gtk-duplex", N_("Two Sided") }, +}; + +static const struct { + const char *ipp_option_name; + const char *ipp_choice; + const char *translation; +} ipp_choice_translations[] = { + { "sides", "one-sided", NC_("sides", "One Sided") }, + /* Translators: this is an option of "Two Sided" */ + { "sides", "two-sided-long-edge", NC_("sides", "Long Edge (Standard)") }, + /* Translators: this is an option of "Two Sided" */ + { "sides", "two-sided-short-edge", NC_("sides", "Short Edge (Flip)") }, +}; + +static const struct { const char *lpoption; const char *name; } lpoption_names[] = { @@ -4914,6 +4971,144 @@ colord_printer_option_set_changed_cb (GtkPrinterOptionSet *set, } #endif +/* + * Lookup translation and Gtk+ name of given IPP option name. + */ +static gboolean +get_ipp_option_translation (const gchar *ipp_option_name, + gchar **gtk_option_name, + gchar **translation) +{ + gint i; + + *gtk_option_name = NULL; + *translation = NULL; + + for (i = 0; i < G_N_ELEMENTS (ipp_option_translations); i++) + { + if (g_strcmp0 (ipp_option_translations[i].ipp_option_name, ipp_option_name) == 0) + { + *gtk_option_name = g_strdup (ipp_option_translations[i].gtk_option_name); + *translation = g_strdup (_(ipp_option_translations[i].translation)); + return TRUE; + } + } + + return FALSE; +} + +/* + * Lookup translation of given IPP choice. + */ +static gchar * +get_ipp_choice_translation (const gchar *ipp_option_name, + const gchar *ipp_choice) +{ + gchar *translation = NULL; + gint i; + + for (i = 0; i < G_N_ELEMENTS (ipp_choice_translations); i++) + { + if (g_strcmp0 (ipp_choice_translations[i].ipp_option_name, ipp_option_name) == 0 && + g_strcmp0 (ipp_choice_translations[i].ipp_choice, ipp_choice) == 0) + { + translation = g_strdup (g_dpgettext2 (GETTEXT_PACKAGE, + ipp_option_name, + ipp_choice_translations[i].translation)); + break; + } + } + + return translation; +} + +/* + * Look the IPP option up in given set of options. + * Create it if it doesn't exist and set its default value + * if available. + */ +static GtkPrinterOption * +setup_ipp_option (gchar *ipp_option_name, + gchar *ipp_choice_default, + GList *ipp_choices, + GtkPrinterOptionSet *set) +{ + GtkPrinterOption *option = NULL; + gchar *gtk_option_name = NULL; + gchar *translation = NULL; + gchar *ipp_choice; + gsize i; + + get_ipp_option_translation (ipp_option_name, + >k_option_name, + &translation); + + /* Look the option up in the given set of options. */ + if (gtk_option_name != NULL) + option = gtk_printer_option_set_lookup (set, gtk_option_name); + + /* The option was not found, create it from given choices. */ + if (option == NULL && + ipp_choices != NULL) + { + GList *iter; + gsize length; + char **choices = NULL; + char **choices_display = NULL; + + option = gtk_printer_option_new (gtk_option_name, + translation, + GTK_PRINTER_OPTION_TYPE_PICKONE); + + length = g_list_length (ipp_choices); + + choices = g_new0 (char *, length); + choices_display = g_new0 (char *, length); + + i = 0; + for (iter = ipp_choices; iter != NULL; iter = iter->next) + { + ipp_choice = (gchar *) iter->data; + + choices[i] = g_strdup (ipp_choice); + + translation = get_ipp_choice_translation (ipp_option_name, + ipp_choice); + if (translation != NULL) + choices_display[i] = translation; + else + choices_display[i] = g_strdup (ipp_choice); + + i++; + } + + if (choices != NULL && + choices_display != NULL) + { + gtk_printer_option_choices_from_array (option, + length, + choices, + choices_display); + } + + option_set_is_ipp_option (option, TRUE); + + gtk_printer_option_set_add (set, option); + + g_free (choices); + g_free (choices_display); + } + + /* The option exists. Set its default value if available. */ + if (option != NULL && + ipp_choice_default != NULL) + { + gtk_printer_option_set (option, ipp_choice_default); + } + + return option; +} + static GtkPrinterOptionSet * cups_printer_get_options (GtkPrinter *printer, GtkPrintSettings *settings, @@ -5154,6 +5349,18 @@ cups_printer_get_options (GtkPrinter *printer, for (i = 0; i < ppd_file->num_groups; i++) handle_group (set, ppd_file, &ppd_file->groups[i], &ppd_file->groups[i], settings); } + else + { + /* Try IPP options */ + + option = setup_ipp_option ("sides", + cups_printer->sides_default, + cups_printer->sides_supported, + set); + + if (option != NULL) + set_option_from_settings (option, settings); + } /* Now honor the user set defaults for this printer */ num_opts = cups_get_user_options (gtk_printer_get_name (printer), 0, &opts); @@ -5207,10 +5414,17 @@ cups_printer_get_options (GtkPrinter *printer, option = gtk_printer_option_set_lookup (set, "gtk-duplex"); if (option && opts[i].value) { - if (strcmp (opts[i].value, "two-sided-short-edge") == 0) - gtk_printer_option_set (option, "DuplexTumble"); - else if (strcmp (opts[i].value, "two-sided-long-edge") == 0) - gtk_printer_option_set (option, "DuplexNoTumble"); + if (!option_is_ipp_option (option)) + { + if (strcmp (opts[i].value, "two-sided-short-edge") == 0) + gtk_printer_option_set (option, "DuplexTumble"); + else if (strcmp (opts[i].value, "two-sided-long-edge") == 0) + gtk_printer_option_set (option, "DuplexNoTumble"); + } + else + { + gtk_printer_option_set (option, opts[i].value); + } } } else @@ -5376,11 +5590,13 @@ map_settings_to_option (GtkPrinterOption *option, gint n_elements, GtkPrintSettings *settings, const gchar *standard_name, - const gchar *cups_name) + const gchar *cups_name, + const gchar *ipp_name) { int i; char *name; const char *cups_value; + const char *ipp_value; const char *standard_value; /* If the cups-specific setting is set, always use that */ @@ -5394,6 +5610,17 @@ map_settings_to_option (GtkPrinterOption *option, return; } + /* If the IPP-specific setting is set, use that */ + name = g_strdup_printf ("cups-%s", ipp_name); + ipp_value = gtk_print_settings_get (settings, name); + g_free (name); + + if (ipp_value != NULL) + { + gtk_printer_option_set (option, ipp_value); + return; + } + /* Otherwise we try to convert from the general setting */ standard_value = gtk_print_settings_get (settings, standard_name); if (standard_value == NULL) @@ -5426,7 +5653,9 @@ map_option_to_settings (const gchar *value, gint n_elements, GtkPrintSettings *settings, const gchar *standard_name, - const gchar *cups_name) + const gchar *cups_name, + const gchar *ipp_name, + gboolean is_ipp_option) { int i; char *name; @@ -5460,8 +5689,13 @@ map_option_to_settings (const gchar *value, } /* Always set the corresponding cups-specific setting */ - name = g_strdup_printf ("cups-%s", cups_name); + if (is_ipp_option) + name = g_strdup_printf ("cups-%s", ipp_name); + else + name = g_strdup_printf ("cups-%s", cups_name); + gtk_print_settings_set (settings, name, value); + g_free (name); } @@ -5522,16 +5756,20 @@ set_option_from_settings (GtkPrinterOption *option, if (strcmp (option->name, "gtk-paper-source") == 0) map_settings_to_option (option, paper_source_map, G_N_ELEMENTS (paper_source_map), - settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE, "InputSlot"); + settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE, + "InputSlot", NULL); else if (strcmp (option->name, "gtk-output-tray") == 0) map_settings_to_option (option, output_tray_map, G_N_ELEMENTS (output_tray_map), - settings, GTK_PRINT_SETTINGS_OUTPUT_BIN, "OutputBin"); + settings, GTK_PRINT_SETTINGS_OUTPUT_BIN, + "OutputBin", NULL); else if (strcmp (option->name, "gtk-duplex") == 0) map_settings_to_option (option, duplex_map, G_N_ELEMENTS (duplex_map), - settings, GTK_PRINT_SETTINGS_DUPLEX, "Duplex"); + settings, GTK_PRINT_SETTINGS_DUPLEX, + "Duplex", "sides"); else if (strcmp (option->name, "cups-OutputMode") == 0) map_settings_to_option (option, output_mode_map, G_N_ELEMENTS (output_mode_map), - settings, GTK_PRINT_SETTINGS_QUALITY, "OutputMode"); + settings, GTK_PRINT_SETTINGS_QUALITY, + "OutputMode", NULL); else if (strcmp (option->name, "cups-Resolution") == 0) { cups_value = gtk_print_settings_get (settings, option->name); @@ -5565,16 +5803,19 @@ set_option_from_settings (GtkPrinterOption *option, } else if (strcmp (option->name, "gtk-paper-type") == 0) map_settings_to_option (option, media_type_map, G_N_ELEMENTS (media_type_map), - settings, GTK_PRINT_SETTINGS_MEDIA_TYPE, "MediaType"); + settings, GTK_PRINT_SETTINGS_MEDIA_TYPE, + "MediaType", NULL); else if (strcmp (option->name, "gtk-n-up") == 0) { map_settings_to_option (option, all_map, G_N_ELEMENTS (all_map), - settings, GTK_PRINT_SETTINGS_NUMBER_UP, "number-up"); + settings, GTK_PRINT_SETTINGS_NUMBER_UP, + "number-up", NULL); } else if (strcmp (option->name, "gtk-n-up-layout") == 0) { map_settings_to_option (option, all_map, G_N_ELEMENTS (all_map), - settings, GTK_PRINT_SETTINGS_NUMBER_UP_LAYOUT, "number-up-layout"); + settings, GTK_PRINT_SETTINGS_NUMBER_UP_LAYOUT, + "number-up-layout", NULL); } else if (strcmp (option->name, "gtk-billing-info") == 0) { @@ -5632,16 +5873,20 @@ foreach_option_get_settings (GtkPrinterOption *option, if (strcmp (option->name, "gtk-paper-source") == 0) map_option_to_settings (value, paper_source_map, G_N_ELEMENTS (paper_source_map), - settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE, "InputSlot"); + settings, GTK_PRINT_SETTINGS_DEFAULT_SOURCE, + "InputSlot", NULL, FALSE); else if (strcmp (option->name, "gtk-output-tray") == 0) map_option_to_settings (value, output_tray_map, G_N_ELEMENTS (output_tray_map), - settings, GTK_PRINT_SETTINGS_OUTPUT_BIN, "OutputBin"); + settings, GTK_PRINT_SETTINGS_OUTPUT_BIN, + "OutputBin", NULL, FALSE); else if (strcmp (option->name, "gtk-duplex") == 0) map_option_to_settings (value, duplex_map, G_N_ELEMENTS (duplex_map), - settings, GTK_PRINT_SETTINGS_DUPLEX, "Duplex"); + settings, GTK_PRINT_SETTINGS_DUPLEX, + "Duplex", "sides", option_is_ipp_option (option)); else if (strcmp (option->name, "cups-OutputMode") == 0) map_option_to_settings (value, output_mode_map, G_N_ELEMENTS (output_mode_map), - settings, GTK_PRINT_SETTINGS_QUALITY, "OutputMode"); + settings, GTK_PRINT_SETTINGS_QUALITY, + "OutputMode", NULL, FALSE); else if (strcmp (option->name, "cups-Resolution") == 0) { int res, res_x, res_y; @@ -5661,13 +5906,16 @@ foreach_option_get_settings (GtkPrinterOption *option, } else if (strcmp (option->name, "gtk-paper-type") == 0) map_option_to_settings (value, media_type_map, G_N_ELEMENTS (media_type_map), - settings, GTK_PRINT_SETTINGS_MEDIA_TYPE, "MediaType"); + settings, GTK_PRINT_SETTINGS_MEDIA_TYPE, + "MediaType", NULL, FALSE); else if (strcmp (option->name, "gtk-n-up") == 0) map_option_to_settings (value, all_map, G_N_ELEMENTS (all_map), - settings, GTK_PRINT_SETTINGS_NUMBER_UP, "number-up"); + settings, GTK_PRINT_SETTINGS_NUMBER_UP, + "number-up", NULL, FALSE); else if (strcmp (option->name, "gtk-n-up-layout") == 0) map_option_to_settings (value, all_map, G_N_ELEMENTS (all_map), - settings, GTK_PRINT_SETTINGS_NUMBER_UP_LAYOUT, "number-up-layout"); + settings, GTK_PRINT_SETTINGS_NUMBER_UP_LAYOUT, + "number-up-layout", NULL, FALSE); else if (strcmp (option->name, "gtk-billing-info") == 0 && strlen (value) > 0) gtk_print_settings_set (settings, "cups-job-billing", value); else if (strcmp (option->name, "gtk-job-prio") == 0) diff --git a/modules/printbackends/cups/gtkprintercups.c b/modules/printbackends/cups/gtkprintercups.c index 7fd828e99d..1e7188e34b 100644 --- a/modules/printbackends/cups/gtkprintercups.c +++ b/modules/printbackends/cups/gtkprintercups.c @@ -133,6 +133,8 @@ gtk_printer_cups_init (GtkPrinterCups *printer) printer->media_left_margin_default = 0; printer->media_right_margin_default = 0; printer->media_margin_default_set = FALSE; + printer->sides_default = NULL; + printer->sides_supported = NULL; } static void @@ -181,6 +183,9 @@ gtk_printer_cups_finalize (GObject *object) g_list_free_full (printer->media_supported, g_free); g_list_free_full (printer->media_size_supported, g_free); + g_free (printer->sides_default); + g_list_free_full (printer->sides_supported, g_free); + if (printer->get_remote_ppd_poll > 0) g_source_remove (printer->get_remote_ppd_poll); printer->get_remote_ppd_attempts = 0; diff --git a/modules/printbackends/cups/gtkprintercups.h b/modules/printbackends/cups/gtkprintercups.h index aeded4ff22..170a4a2119 100644 --- a/modules/printbackends/cups/gtkprintercups.h +++ b/modules/printbackends/cups/gtkprintercups.h @@ -66,6 +66,8 @@ struct _GtkPrinterCups gint media_left_margin_default; gint media_right_margin_default; gboolean media_margin_default_set; + gchar *sides_default; + GList *sides_supported; gchar *default_cover_before; gchar *default_cover_after; |