X-Git-Url: http://pileus.org/git/?a=blobdiff_plain;f=gtk%2Fgtkprintbackend.c;h=93dcb7aa31dada35397e975265259727b4daddce;hb=HEAD;hp=a2af6c4865326437fd2bf0fb93fb788df7d50239;hpb=c8cbe9a1bc4d26f84b89b88e5051b7b774897e6f;p=~andy%2Fgtk diff --git a/gtk/gtkprintbackend.c b/gtk/gtkprintbackend.c index a2af6c486..93dcb7aa3 100644 --- a/gtk/gtkprintbackend.c +++ b/gtk/gtkprintbackend.c @@ -13,9 +13,7 @@ * 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 "config.h" @@ -25,20 +23,30 @@ #include "gtkintl.h" #include "gtkmodules.h" +#include "gtkmodulesprivate.h" +#include "gtkmarshalers.h" #include "gtkprivate.h" #include "gtkprintbackend.h" -#include "gtkalias.h" -#define GTK_PRINT_BACKEND_GET_PRIVATE(o) \ - (G_TYPE_INSTANCE_GET_PRIVATE ((o), GTK_TYPE_PRINT_BACKEND, GtkPrintBackendPrivate)) -static void gtk_print_backend_dispose (GObject *object); +static void gtk_print_backend_dispose (GObject *object); +static void gtk_print_backend_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec); +static void gtk_print_backend_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec); struct _GtkPrintBackendPrivate { GHashTable *printers; guint printer_list_requested : 1; guint printer_list_done : 1; + GtkPrintBackendStatus status; + char **auth_info_required; + char **auth_info; }; enum { @@ -47,11 +55,18 @@ enum { PRINTER_ADDED, PRINTER_REMOVED, PRINTER_STATUS_CHANGED, + REQUEST_PASSWORD, LAST_SIGNAL }; static guint signals[LAST_SIGNAL] = { 0 }; +enum +{ + PROP_ZERO, + PROP_STATUS +}; + static GObjectClass *backend_parent_class; GQuark @@ -88,6 +103,8 @@ struct _GtkPrintBackendModuleClass GTypeModuleClass parent_class; }; +GType _gtk_print_backend_module_get_type (void); + G_DEFINE_TYPE (GtkPrintBackendModule, _gtk_print_backend_module, G_TYPE_TYPE_MODULE) #define GTK_TYPE_PRINT_BACKEND_MODULE (_gtk_print_backend_module_get_type ()) #define GTK_PRINT_BACKEND_MODULE(module) (G_TYPE_CHECK_INSTANCE_CAST ((module), GTK_TYPE_PRINT_BACKEND_MODULE, GtkPrintBackendModule)) @@ -103,7 +120,7 @@ gtk_print_backend_module_load (GTypeModule *module) pb_module->library = g_module_open (pb_module->path, G_MODULE_BIND_LAZY | G_MODULE_BIND_LOCAL); if (!pb_module->library) { - g_warning (g_module_error()); + g_warning ("%s", g_module_error()); return FALSE; } @@ -115,7 +132,7 @@ gtk_print_backend_module_load (GTypeModule *module) !g_module_symbol (pb_module->library, "pb_module_create", &createp)) { - g_warning (g_module_error()); + g_warning ("%s", g_module_error()); g_module_close (pb_module->library); return FALSE; @@ -125,7 +142,7 @@ gtk_print_backend_module_load (GTypeModule *module) pb_module->exit = exitp; pb_module->create = createp; - /* call the filesystems's init function to let it */ + /* call the printbackend's init function to let it */ /* setup anything it needs to set up. */ pb_module->init (module); @@ -172,6 +189,46 @@ _gtk_print_backend_module_class_init (GtkPrintBackendModuleClass *class) gobject_class->finalize = gtk_print_backend_module_finalize; } +static void +gtk_print_backend_set_property (GObject *object, + guint prop_id, + const GValue *value, + GParamSpec *pspec) +{ + GtkPrintBackend *backend = GTK_PRINT_BACKEND (object); + GtkPrintBackendPrivate *priv = backend->priv; + + switch (prop_id) + { + case PROP_STATUS: + priv->status = g_value_get_int (value); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + +static void +gtk_print_backend_get_property (GObject *object, + guint prop_id, + GValue *value, + GParamSpec *pspec) +{ + GtkPrintBackend *backend = GTK_PRINT_BACKEND (object); + GtkPrintBackendPrivate *priv = backend->priv; + + switch (prop_id) + { + case PROP_STATUS: + g_value_set_int (value, priv->status); + break; + default: + G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); + break; + } +} + static void _gtk_print_backend_module_init (GtkPrintBackendModule *pb_module) { @@ -191,16 +248,15 @@ _gtk_print_backend_module_create (GtkPrintBackendModule *pb_module) return NULL; } -GtkPrintBackend * -_gtk_print_backend_create (const char *backend_name) +static GtkPrintBackend * +_gtk_print_backend_create (const gchar *backend_name) { GSList *l; - char *module_path; - char *full_name; + gchar *module_path; + gchar *full_name; GtkPrintBackendModule *pb_module; GtkPrintBackend *pb; - /* TODO: make module loading code work */ for (l = loaded_backends; l != NULL; l = l->next) { pb_module = l->data; @@ -229,8 +285,9 @@ _gtk_print_backend_create (const char *backend_name) pb = _gtk_print_backend_module_create (pb_module); /* Increase use-count so that we don't unload print backends. - There is a problem with module unloading in the cups module, - see cups_dispatch_watch_finalize for details. */ + * There is a problem with module unloading in the cups module, + * see cups_dispatch_watch_finalize for details. + */ g_type_module_use (G_TYPE_MODULE (pb_module)); } @@ -238,31 +295,15 @@ _gtk_print_backend_create (const char *backend_name) } return pb; - - return NULL; } -static void -gtk_print_backend_initialize (void) -{ - static gboolean initialized = FALSE; - - if (!initialized) - { - gtk_settings_install_property (g_param_spec_string ("gtk-print-backends", - P_("Default print backend"), - P_("List of the GtkPrintBackend backends to use by default"), - GTK_PRINT_BACKENDS, - GTK_PARAM_READWRITE)); - - initialized = TRUE; - } -} - - - +/** + * gtk_print_backend_load_modules: + * + * Return value: (element-type GtkPrintBackend) (transfer container): + */ GList * -gtk_print_backend_load_modules () +gtk_print_backend_load_modules (void) { GList *result; GtkPrintBackend *backend; @@ -273,11 +314,11 @@ gtk_print_backend_load_modules () result = NULL; - gtk_print_backend_initialize (); - settings = gtk_settings_get_default (); - - g_object_get (settings, "gtk-print-backends", &setting, NULL); + if (settings) + g_object_get (settings, "gtk-print-backends", &setting, NULL); + else + setting = g_strdup (GTK_PRINT_BACKENDS); backends = g_strsplit (setting, ",", -1); @@ -303,16 +344,23 @@ gtk_print_backend_load_modules () G_DEFINE_TYPE (GtkPrintBackend, gtk_print_backend, G_TYPE_OBJECT) -static void fallback_printer_request_details (GtkPrinter *printer); -static gboolean fallback_printer_mark_conflicts (GtkPrinter *printer, - GtkPrinterOptionSet *options); -static void fallback_printer_get_hard_margins (GtkPrinter *printer, - double *top, - double *bottom, - double *left, - double *right); -static GList * fallback_printer_list_papers (GtkPrinter *printer); -static GtkPrintCapabilities fallback_printer_get_capabilities (GtkPrinter *printer); +static void fallback_printer_request_details (GtkPrinter *printer); +static gboolean fallback_printer_mark_conflicts (GtkPrinter *printer, + GtkPrinterOptionSet *options); +static gboolean fallback_printer_get_hard_margins (GtkPrinter *printer, + gdouble *top, + gdouble *bottom, + gdouble *left, + gdouble *right); +static GList * fallback_printer_list_papers (GtkPrinter *printer); +static GtkPageSetup * fallback_printer_get_default_page_size (GtkPrinter *printer); +static GtkPrintCapabilities fallback_printer_get_capabilities (GtkPrinter *printer); +static void request_password (GtkPrintBackend *backend, + gpointer auth_info_required, + gpointer auth_info_default, + gpointer auth_info_display, + gpointer auth_info_visible, + const gchar *prompt); static void gtk_print_backend_class_init (GtkPrintBackendClass *class) @@ -323,13 +371,27 @@ gtk_print_backend_class_init (GtkPrintBackendClass *class) backend_parent_class = g_type_class_peek_parent (class); object_class->dispose = gtk_print_backend_dispose; + object_class->set_property = gtk_print_backend_set_property; + object_class->get_property = gtk_print_backend_get_property; class->printer_request_details = fallback_printer_request_details; class->printer_mark_conflicts = fallback_printer_mark_conflicts; class->printer_get_hard_margins = fallback_printer_get_hard_margins; class->printer_list_papers = fallback_printer_list_papers; + class->printer_get_default_page_size = fallback_printer_get_default_page_size; class->printer_get_capabilities = fallback_printer_get_capabilities; + class->request_password = request_password; + g_object_class_install_property (object_class, + PROP_STATUS, + g_param_spec_int ("status", + "Status", + "The status of the print backend", + GTK_PRINT_BACKEND_STATUS_UNKNOWN, + GTK_PRINT_BACKEND_STATUS_UNAVAILABLE, + GTK_PRINT_BACKEND_STATUS_UNKNOWN, + GTK_PARAM_READWRITE)); + g_type_class_add_private (class, sizeof (GtkPrintBackendPrivate)); signals[PRINTER_LIST_CHANGED] = @@ -372,6 +434,14 @@ gtk_print_backend_class_init (GtkPrintBackendClass *class) NULL, NULL, g_cclosure_marshal_VOID__OBJECT, G_TYPE_NONE, 1, GTK_TYPE_PRINTER); + signals[REQUEST_PASSWORD] = + g_signal_new (I_("request-password"), + G_TYPE_FROM_CLASS (class), + G_SIGNAL_RUN_LAST, + G_STRUCT_OFFSET (GtkPrintBackendClass, request_password), + NULL, NULL, + _gtk_marshal_VOID__POINTER_POINTER_POINTER_POINTER_STRING, + G_TYPE_NONE, 5, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_POINTER, G_TYPE_STRING); } static void @@ -379,11 +449,15 @@ gtk_print_backend_init (GtkPrintBackend *backend) { GtkPrintBackendPrivate *priv; - priv = backend->priv = GTK_PRINT_BACKEND_GET_PRIVATE (backend); + priv = backend->priv = G_TYPE_INSTANCE_GET_PRIVATE (backend, + GTK_TYPE_PRINT_BACKEND, + GtkPrintBackendPrivate); priv->printers = g_hash_table_new_full (g_str_hash, g_str_equal, (GDestroyNotify) g_free, (GDestroyNotify) g_object_unref); + priv->auth_info_required = NULL; + priv->auth_info = NULL; } static void @@ -396,7 +470,8 @@ gtk_print_backend_dispose (GObject *object) priv = backend->priv; /* We unref the printers in dispose, not in finalize so that - we can break refcount cycles with gtk_print_backend_destroy */ + * we can break refcount cycles with gtk_print_backend_destroy + */ if (priv->printers) { g_hash_table_destroy (priv->printers); @@ -413,23 +488,20 @@ fallback_printer_request_details (GtkPrinter *printer) } static gboolean -fallback_printer_mark_conflicts (GtkPrinter *printer, +fallback_printer_mark_conflicts (GtkPrinter *printer, GtkPrinterOptionSet *options) { return FALSE; } -static void +static gboolean fallback_printer_get_hard_margins (GtkPrinter *printer, - double *top, - double *bottom, - double *left, - double *right) + gdouble *top, + gdouble *bottom, + gdouble *left, + gdouble *right) { - *top = 0; - *bottom = 0; - *left = 0; - *right = 0; + return FALSE; } static GList * @@ -438,6 +510,12 @@ fallback_printer_list_papers (GtkPrinter *printer) return NULL; } +static GtkPageSetup * +fallback_printer_get_default_page_size (GtkPrinter *printer) +{ + return NULL; +} + static GtkPrintCapabilities fallback_printer_get_capabilities (GtkPrinter *printer) { @@ -446,9 +524,9 @@ fallback_printer_get_capabilities (GtkPrinter *printer) static void -printer_hash_to_sorted_active_list (const gchar *key, - gpointer value, - GList **out_list) +printer_hash_to_sorted_active_list (const gchar *key, + gpointer value, + GList **out_list) { GtkPrinter *printer; @@ -466,7 +544,7 @@ printer_hash_to_sorted_active_list (const gchar *key, void gtk_print_backend_add_printer (GtkPrintBackend *backend, - GtkPrinter *printer) + GtkPrinter *printer) { GtkPrintBackendPrivate *priv; @@ -484,7 +562,7 @@ gtk_print_backend_add_printer (GtkPrintBackend *backend, void gtk_print_backend_remove_printer (GtkPrintBackend *backend, - GtkPrinter *printer) + GtkPrinter *printer) { GtkPrintBackendPrivate *priv; @@ -509,6 +587,15 @@ gtk_print_backend_set_list_done (GtkPrintBackend *backend) } +/** + * gtk_print_backend_get_printer_list: + * + * Returns the current list of printers. + * + * Return value: (element-type GtkPrinter) (transfer container): + * A list of #GtkPrinter objects. The list should be freed + * with g_list_free(). + */ GList * gtk_print_backend_get_printer_list (GtkPrintBackend *backend) { @@ -531,8 +618,8 @@ gtk_print_backend_get_printer_list (GtkPrintBackend *backend) GTK_PRINT_BACKEND_GET_CLASS (backend)->request_printer_list (backend); priv->printer_list_requested = TRUE; } - - return result;; + + return result; } gboolean @@ -545,7 +632,7 @@ gtk_print_backend_printer_list_is_done (GtkPrintBackend *print_backend) GtkPrinter * gtk_print_backend_find_printer (GtkPrintBackend *backend, - const gchar *printer_name) + const gchar *printer_name) { GtkPrintBackendPrivate *priv; GtkPrinter *printer; @@ -563,34 +650,193 @@ gtk_print_backend_find_printer (GtkPrintBackend *backend, } void -gtk_print_backend_print_stream (GtkPrintBackend *backend, - GtkPrintJob *job, - gint data_fd, +gtk_print_backend_print_stream (GtkPrintBackend *backend, + GtkPrintJob *job, + GIOChannel *data_io, GtkPrintJobCompleteFunc callback, - gpointer user_data, - GDestroyNotify dnotify) + gpointer user_data, + GDestroyNotify dnotify) { g_return_if_fail (GTK_IS_PRINT_BACKEND (backend)); GTK_PRINT_BACKEND_GET_CLASS (backend)->print_stream (backend, job, - data_fd, + data_io, callback, user_data, dnotify); } +void +gtk_print_backend_set_password (GtkPrintBackend *backend, + gchar **auth_info_required, + gchar **auth_info) +{ + g_return_if_fail (GTK_IS_PRINT_BACKEND (backend)); + + if (GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password) + GTK_PRINT_BACKEND_GET_CLASS (backend)->set_password (backend, auth_info_required, auth_info); +} + +static void +store_entry (GtkEntry *entry, + gpointer user_data) +{ + gchar **data = (gchar **) user_data; + + if (*data != NULL) + { + memset (*data, 0, strlen (*data)); + g_free (*data); + } + + *data = g_strdup (gtk_entry_get_text (entry)); +} + +static void +password_dialog_response (GtkWidget *dialog, + gint response_id, + GtkPrintBackend *backend) +{ + GtkPrintBackendPrivate *priv = backend->priv; + gint i; + + if (response_id == GTK_RESPONSE_OK) + gtk_print_backend_set_password (backend, priv->auth_info_required, priv->auth_info); + else + gtk_print_backend_set_password (backend, priv->auth_info_required, NULL); + + for (i = 0; i < g_strv_length (priv->auth_info_required); i++) + if (priv->auth_info[i] != NULL) + { + memset (priv->auth_info[i], 0, strlen (priv->auth_info[i])); + g_free (priv->auth_info[i]); + priv->auth_info[i] = NULL; + } + g_free (priv->auth_info); + priv->auth_info = NULL; + + g_strfreev (priv->auth_info_required); + + gtk_widget_destroy (dialog); + + g_object_unref (backend); +} + +static void +request_password (GtkPrintBackend *backend, + gpointer auth_info_required, + gpointer auth_info_default, + gpointer auth_info_display, + gpointer auth_info_visible, + const gchar *prompt) +{ + GtkPrintBackendPrivate *priv = backend->priv; + GtkWidget *dialog, *box, *main_box, *label, *icon, *vbox, *entry; + GtkWidget *focus = NULL; + GtkWidget *content_area; + gchar *markup; + gint length; + gint i; + gchar **ai_required = (gchar **) auth_info_required; + gchar **ai_default = (gchar **) auth_info_default; + gchar **ai_display = (gchar **) auth_info_display; + gboolean *ai_visible = (gboolean *) auth_info_visible; + + priv->auth_info_required = g_strdupv (ai_required); + length = g_strv_length (ai_required); + priv->auth_info = g_new0 (gchar *, length); + + dialog = gtk_dialog_new_with_buttons ( _("Authentication"), NULL, GTK_DIALOG_MODAL, + GTK_STOCK_CANCEL, GTK_RESPONSE_CANCEL, + GTK_STOCK_OK, GTK_RESPONSE_OK, + NULL); + + gtk_dialog_set_default_response (GTK_DIALOG (dialog), GTK_RESPONSE_OK); + + main_box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + + /* Left */ + icon = gtk_image_new_from_stock (GTK_STOCK_DIALOG_AUTHENTICATION, GTK_ICON_SIZE_DIALOG); + gtk_widget_set_halign (icon, GTK_ALIGN_CENTER); + gtk_widget_set_valign (icon, GTK_ALIGN_START); + g_object_set (icon, "margin", 6, NULL); + + /* Right */ + vbox = gtk_box_new (GTK_ORIENTATION_VERTICAL, 0); + gtk_widget_set_size_request (GTK_WIDGET (vbox), 320, -1); + + /* Right - 1. */ + label = gtk_label_new (NULL); + markup = g_markup_printf_escaped ("%s", prompt); + gtk_label_set_markup (GTK_LABEL (label), markup); + gtk_label_set_line_wrap (GTK_LABEL (label), TRUE); + gtk_widget_set_size_request (GTK_WIDGET (label), 320, -1); + g_free (markup); + + + /* Packing */ + content_area = gtk_dialog_get_content_area (GTK_DIALOG (dialog)); + gtk_box_pack_start (GTK_BOX (content_area), main_box, TRUE, FALSE, 0); + + gtk_box_pack_start (GTK_BOX (main_box), icon, FALSE, FALSE, 6); + gtk_box_pack_start (GTK_BOX (main_box), vbox, FALSE, FALSE, 6); + + gtk_box_pack_start (GTK_BOX (vbox), label, FALSE, TRUE, 6); + + /* Right - 2. */ + for (i = 0; i < length; i++) + { + priv->auth_info[i] = g_strdup (ai_default[i]); + if (ai_display[i] != NULL) + { + box = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0); + gtk_box_set_homogeneous (GTK_BOX (box), TRUE); + + label = gtk_label_new (ai_display[i]); + gtk_widget_set_halign (label, GTK_ALIGN_START); + gtk_widget_set_valign (label, GTK_ALIGN_CENTER); + + entry = gtk_entry_new (); + focus = entry; + + if (ai_default[i] != NULL) + gtk_entry_set_text (GTK_ENTRY (entry), ai_default[i]); + + gtk_entry_set_visibility (GTK_ENTRY (entry), ai_visible[i]); + gtk_entry_set_activates_default (GTK_ENTRY (entry), TRUE); + + gtk_box_pack_start (GTK_BOX (vbox), box, FALSE, TRUE, 6); + + gtk_box_pack_start (GTK_BOX (box), label, TRUE, TRUE, 0); + gtk_box_pack_start (GTK_BOX (box), entry, TRUE, TRUE, 0); + + g_signal_connect (entry, "changed", + G_CALLBACK (store_entry), &(priv->auth_info[i])); + } + } + + if (focus != NULL) + { + gtk_widget_grab_focus (focus); + focus = NULL; + } + + g_object_ref (backend); + g_signal_connect (G_OBJECT (dialog), "response", + G_CALLBACK (password_dialog_response), backend); + + gtk_widget_show_all (dialog); +} + void gtk_print_backend_destroy (GtkPrintBackend *print_backend) { /* The lifecycle of print backends and printers are tied, such that - the backend owns the printers, but the printers also ref the backend. - This is so that if the app has a reference to a printer its backend - will be around. However, this results in a cycle, which we break - with this call, which causes the print backend to release its printers. - */ + * the backend owns the printers, but the printers also ref the backend. + * This is so that if the app has a reference to a printer its backend + * will be around. However, this results in a cycle, which we break + * with this call, which causes the print backend to release its printers. + */ g_object_run_dispose (G_OBJECT (print_backend)); } - -#define __GTK_PRINT_BACKEND_C__ -#include "gtkaliasdef.c"