root/trunk/libtinymailui-gtk/tny-gtk-password-dialog.c

Revision 3666 (checked in by jdapena, 6 months ago)

* Use GOnce registering all types in tinymail to make

registering thread-safe.

Line 
1 /* tinymail - Tiny Mail
2  * Copyright (C) 2006-2007 Philip Van Hoof <pvanhoof@gtk.org>
3  *
4  * This library is free software; you can redistribute it and/or
5  * modify it under the terms of the GNU Lesser General Public
6  * License as published by the Free Software Foundation; either
7  * version 2 of the License, or (at your option) any later version.
8  *
9  * This library is distributed in the hope that it will be useful,
10  * but WITHOUT ANY WARRANTY; without even the implied warranty of
11  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
12  * Lesser General Public License for more details.
13  *
14  * You should have received a copy of the GNU Lesser General Public
15  * License along with self library; if not, write to the
16  * Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
17  * Boston, MA 02110-1301, USA.
18  */
19
20 /**
21  * TnyGtkPasswordDialog:
22  *
23  * A #TnyPasswordGetter that will ask the user to enter the password in Gtk+
24  *
25  * free-function: g_object_unref
26  **/
27
28 #include <config.h>
29
30 #include <string.h>
31 #include <sys/mman.h>
32
33 #include <glib/gi18n-lib.h>
34
35 #include <gtk/gtk.h>
36 #include <tny-gtk-password-dialog.h>
37
38 #include <tny-account.h>
39
40 static GObjectClass *parent_class = NULL;
41 static GHashTable *passwords = NULL;
42
43 static const gchar*
44 tny_gtk_password_dialog_get_password (TnyPasswordGetter *self, const gchar *aid, const gchar *prompt, gboolean *cancel)
45 {
46         const gchar *accountid = aid;
47         const gchar *retval = NULL;
48
49         if (G_UNLIKELY (!passwords))
50                 passwords = g_hash_table_new (g_str_hash, g_str_equal);
51         retval = g_hash_table_lookup (passwords, accountid);
52
53         if (G_UNLIKELY (!retval))
54         {
55                 GtkDialog *dialog = NULL;
56                 GtkEntry *pwd_entry;
57                 GtkLabel *prompt_label;
58
59                 dialog = GTK_DIALOG (gtk_dialog_new_with_buttons (_("Password input"), NULL,
60                         GTK_DIALOG_MODAL,
61                         GTK_STOCK_OK, GTK_RESPONSE_OK,
62                         GTK_STOCK_CANCEL, GTK_RESPONSE_REJECT,
63                         NULL));
64
65                 gtk_window_set_title (GTK_WINDOW (dialog), _("Password input"));
66
67                 /* TODO: Add key icon or something */
68
69                 pwd_entry = GTK_ENTRY (gtk_entry_new ());
70                 prompt_label = GTK_LABEL (gtk_label_new (""));
71
72                 gtk_entry_set_visibility (pwd_entry, FALSE);
73
74                 gtk_widget_show (GTK_WIDGET (pwd_entry));
75                 gtk_widget_show (GTK_WIDGET (prompt_label));
76
77                 gtk_box_pack_start (GTK_BOX (dialog->vbox),
78                         GTK_WIDGET (prompt_label), TRUE, TRUE, 0);
79
80                 gtk_box_pack_start (GTK_BOX (dialog->vbox),
81                         GTK_WIDGET (pwd_entry), TRUE, TRUE, 0);
82
83                 gtk_label_set_text (prompt_label, prompt);
84
85                 if (G_LIKELY (gtk_dialog_run (dialog) == GTK_RESPONSE_OK))
86                 {
87                         const gchar *pwd = gtk_entry_get_text (pwd_entry);
88                         retval = g_strdup (pwd);
89                         mlock (pwd, strlen (pwd));
90                         mlock (retval, strlen (retval));
91                         *cancel = FALSE;
92                 } else {
93                         *cancel = TRUE;
94                 }
95
96                 gtk_widget_destroy (GTK_WIDGET (dialog));
97
98                 while (gtk_events_pending ())
99                         gtk_main_iteration ();
100         } else {
101                         *cancel = FALSE;
102         }
103
104         return retval;
105 }
106
107 static void
108 tny_gtk_password_dialog_forget_password (TnyPasswordGetter *self, const gchar *aid)
109 {
110         if (G_LIKELY (passwords))
111         {
112                 const gchar *accountid = aid;
113
114                 gchar *pwd = g_hash_table_lookup (passwords, accountid);
115
116                 if (G_LIKELY (pwd))
117                 {
118                         memset (pwd, 0, strlen (pwd));
119                         /* g_free (pwd); uhm, crashed once */
120                         g_hash_table_remove (passwords, accountid);
121                 }
122
123         }
124 }
125
126 /**
127  * tny_gtk_password_dialog_new:
128  *
129  * Create a dialog window that will ask the user for a password
130  *
131  * returns: (caller-owns): A new #GtkDialog password dialog
132  * since: 1.0
133  * audience: application-developer
134  **/
135 TnyPasswordGetter*
136 tny_gtk_password_dialog_new (void)
137 {
138         TnyGtkPasswordDialog *self = g_object_new (TNY_TYPE_GTK_PASSWORD_DIALOG, NULL);
139
140         return TNY_PASSWORD_GETTER (self);
141 }
142
143 static void
144 tny_gtk_password_dialog_instance_init (GTypeInstance *instance, gpointer g_class)
145 {
146         return;
147 }
148
149 static void
150 tny_gtk_password_dialog_finalize (GObject *object)
151 {
152         (*parent_class->finalize) (object);
153
154         return;
155 }
156
157
158
159 static void
160 tny_password_getter_init (gpointer g, gpointer iface_data)
161 {
162         TnyPasswordGetterIface *klass = (TnyPasswordGetterIface *)g;
163         klass->forget_password= tny_gtk_password_dialog_forget_password;
164         klass->get_password= tny_gtk_password_dialog_get_password;
165 }
166
167
168 static void
169 tny_gtk_password_dialog_class_init (TnyGtkPasswordDialogClass *class)
170 {
171         GObjectClass *object_class;
172
173         parent_class = g_type_class_peek_parent (class);
174         object_class = (GObjectClass*) class;
175         object_class->finalize = tny_gtk_password_dialog_finalize;
176
177         return;
178 }
179
180 static gpointer
181 tny_gtk_password_dialog_register_type (gpointer notused)
182 {
183         GType type = 0;
184
185         static const GTypeInfo info =
186                 {
187                   sizeof (TnyGtkPasswordDialogClass),
188                   NULL,   /* base_init */
189                   NULL,   /* base_finalize */
190                   (GClassInitFunc) tny_gtk_password_dialog_class_init,   /* class_init */
191                   NULL,   /* class_finalize */
192                   NULL,   /* class_data */
193                   sizeof (TnyGtkPasswordDialog),
194                   0,      /* n_preallocs */
195                   tny_gtk_password_dialog_instance_init    /* instance_init */
196                 };
197
198         static const GInterfaceInfo tny_password_getter_info =
199                 {
200                   (GInterfaceInitFunc) tny_password_getter_init, /* interface_init */
201                   NULL,         /* interface_finalize */
202                   NULL          /* interface_data */
203                 };
204
205         type = g_type_register_static (G_TYPE_OBJECT,
206                                        "TnyGtkPasswordDialog", &info, 0);
207        
208         g_type_add_interface_static (type, TNY_TYPE_PASSWORD_GETTER,
209                                      &tny_password_getter_info);
210
211         return GUINT_TO_POINTER (type);
212 }
213
214 GType
215 tny_gtk_password_dialog_get_type (void)
216 {
217         static GOnce once = G_ONCE_INIT;
218         g_once (&once, tny_gtk_password_dialog_register_type, NULL);
219         return GPOINTER_TO_UINT (once.retval);
220 }
Note: See TracBrowser for help on using the browser.