aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorChristian Grothoff <christian@grothoff.org>2021-12-30 00:06:10 +0100
committerChristian Grothoff <christian@grothoff.org>2021-12-30 00:06:10 +0100
commitd77e7cab65c416f72ff1b52fa590b24ede512e75 (patch)
treef69e8c038d4723c60c348342b03e11ecb1611401
parent987f3f2f2d4f7fd61c115323fb17e6889f1e1120 (diff)
downloadanastasis-gtk-d77e7cab65c416f72ff1b52fa590b24ede512e75.tar.gz
anastasis-gtk-d77e7cab65c416f72ff1b52fa590b24ede512e75.zip
simplify pin entry by breaking up into groups and auto-completion (#7088)
-rw-r--r--contrib/anastasis_gtk_challenge_code.glade1
-rw-r--r--src/anastasis/anastasis-gtk_autocomplete.c100
-rw-r--r--src/anastasis/anastasis-gtk_handle-challenge-code.c25
3 files changed, 101 insertions, 25 deletions
diff --git a/contrib/anastasis_gtk_challenge_code.glade b/contrib/anastasis_gtk_challenge_code.glade
index 8b4113e..176660e 100644
--- a/contrib/anastasis_gtk_challenge_code.glade
+++ b/contrib/anastasis_gtk_challenge_code.glade
@@ -235,6 +235,7 @@ Author: Christian Grothoff
235 <property name="primary-icon-stock">gtk-dialog-authentication</property> 235 <property name="primary-icon-stock">gtk-dialog-authentication</property>
236 <property name="placeholder-text" translatable="no">A-</property> 236 <property name="placeholder-text" translatable="no">A-</property>
237 <signal name="changed" handler="anastasis_gtk_c_code_dialog_answer_entry_changed_cb" swapped="no"/> 237 <signal name="changed" handler="anastasis_gtk_c_code_dialog_answer_entry_changed_cb" swapped="no"/>
238 <signal name="insert-text" handler="anastasis_gtk_pin_autocomplete_insert_text" swapped="no"/>
238 </object> 239 </object>
239 <packing> 240 <packing>
240 <property name="expand">False</property> 241 <property name="expand">False</property>
diff --git a/src/anastasis/anastasis-gtk_autocomplete.c b/src/anastasis/anastasis-gtk_autocomplete.c
index 1e3da34..c941d25 100644
--- a/src/anastasis/anastasis-gtk_autocomplete.c
+++ b/src/anastasis/anastasis-gtk_autocomplete.c
@@ -50,12 +50,41 @@ lookup_autocomplete (GtkEditable *editable)
50 } 50 }
51 json_array_foreach (ra, index, a) 51 json_array_foreach (ra, index, a)
52 { 52 {
53 const char *widget_name = json_string_value (json_object_get (a, 53 const char *autocomplete = NULL;
54 "widget")); 54 const char *widget_name = NULL;
55 if (editable == 55 const char *type = NULL;
56 GTK_EDITABLE (GCG_get_main_window_object (ai[i].widget_name))) 56 char *data_name;
57 return json_string_value (json_object_get (a, 57 bool match;
58 "autocomplete")); 58 struct GNUNET_JSON_Specification spec[] = {
59 GNUNET_JSON_spec_mark_optional (
60 GNUNET_JSON_spec_string ("widget",
61 &widget_name)),
62 GNUNET_JSON_spec_mark_optional (
63 GNUNET_JSON_spec_string ("autocomplete",
64 &autocomplete)),
65 GNUNET_JSON_spec_string ("type",
66 &type),
67 GNUNET_JSON_spec_end ()
68 };
69
70 if (GNUNET_OK !=
71 GNUNET_JSON_parse (a,
72 spec,
73 NULL, NULL))
74 {
75 GNUNET_break (0);
76 continue;
77 }
78 if ( (NULL == autocomplete) ||
79 (NULL == widget_name) )
80 continue;
81 data_name = AG_expand_name (widget_name,
82 type);
83 match = (editable ==
84 GTK_EDITABLE (GCG_get_main_window_object (data_name)));
85 GNUNET_free (data_name);
86 if (match)
87 return autocomplete;
59 } 88 }
60 GNUNET_break (0); 89 GNUNET_break (0);
61 return NULL; 90 return NULL;
@@ -115,10 +144,10 @@ anastasis_gtk_autocomplete_insert_text (GtkEditable *editable,
115 void *user_data) 144 void *user_data)
116{ 145{
117 const char *ac; 146 const char *ac;
118 (void) user_data;
119 gint pos; 147 gint pos;
120 char *replacement; 148 char *replacement;
121 149
150 (void) user_data;
122 ac = lookup_autocomplete (editable); 151 ac = lookup_autocomplete (editable);
123 if (NULL == ac) 152 if (NULL == ac)
124 return; 153 return;
@@ -141,3 +170,60 @@ anastasis_gtk_autocomplete_insert_text (GtkEditable *editable,
141 GNUNET_free (replacement); 170 GNUNET_free (replacement);
142 } 171 }
143} 172}
173
174
175/**
176 * Function called from an auto-completed PIN widget upon text insertion.
177 *
178 * @param editable the widget
179 * @param new_text inserted text
180 * @param new_text_length number of bytes in @a new_text
181 * @param position insertion position
182 * @param user_data unused
183 */
184void
185anastasis_gtk_pin_autocomplete_insert_text (GtkEditable *editable,
186 const char *new_text,
187 int new_text_length,
188 gpointer position,
189 void *user_data)
190{
191 /* Use \? to break up trigraphs */
192 const char *acn = "????\?-??\?-???\?-??\?";
193 const char *aca = "A-????\?-??\?-???\?-??\?";
194 const char *ac;
195 gint pos;
196 char *replacement;
197 gchar *pfx;
198
199 (void) user_data;
200 pfx = gtk_editable_get_chars (editable,
201 0,
202 2);
203 if (0 == strncasecmp (pfx,
204 "A-",
205 2))
206 ac = aca;
207 else
208 ac = acn;
209 g_free (pfx);
210
211 pos = gtk_editable_get_position (editable);
212 if (strlen (ac) <= pos + new_text_length)
213 return;
214 if (ac[pos+new_text_length] != '?')
215 {
216 g_signal_stop_emission_by_name (editable,
217 "insert-text");
218 GNUNET_asprintf (&replacement,
219 "%.*s%c",
220 new_text_length,
221 new_text,
222 ac[pos+new_text_length]);
223 gtk_editable_insert_text (editable,
224 replacement,
225 -1,
226 position);
227 GNUNET_free (replacement);
228 }
229}
diff --git a/src/anastasis/anastasis-gtk_handle-challenge-code.c b/src/anastasis/anastasis-gtk_handle-challenge-code.c
index 7a993da..4f42023 100644
--- a/src/anastasis/anastasis-gtk_handle-challenge-code.c
+++ b/src/anastasis/anastasis-gtk_handle-challenge-code.c
@@ -49,6 +49,7 @@ anastasis_gtk_c_code_dialog_response_cb (GtkDialog *dialog,
49 json_t *args; 49 json_t *args;
50 unsigned long long pin; 50 unsigned long long pin;
51 char dummy; 51 char dummy;
52 char s[16];
52 53
53 if (GTK_RESPONSE_OK != response_id) 54 if (GTK_RESPONSE_OK != response_id)
54 { 55 {
@@ -65,20 +66,15 @@ anastasis_gtk_c_code_dialog_response_cb (GtkDialog *dialog,
65 q = GTK_ENTRY (gtk_builder_get_object (builder, 66 q = GTK_ENTRY (gtk_builder_get_object (builder,
66 "anastasis_gtk_c_code_entry")); 67 "anastasis_gtk_c_code_entry"));
67 qs = gtk_entry_get_text (q); 68 qs = gtk_entry_get_text (q);
68 if ( (NULL != qs) && 69 if (! ANASTASIS_scan_pin (qs,
69 (0 == strncasecmp ("a-", qs, 2)) ) 70 &pin))
70 qs += 2; /* skip "A-" prefix if present */
71 if (1 != sscanf (qs,
72 "%llu%c",
73 &pin,
74 &dummy))
75 { 71 {
76 GNUNET_break (0); 72 GNUNET_break (0);
77 return; 73 return;
78 } 74 }
79 args = GNUNET_JSON_PACK ( 75 args = GNUNET_JSON_PACK (
80 GNUNET_JSON_pack_uint64 ("pin", 76 GNUNET_JSON_pack_uint64 ("pin",
81 pin)); 77 (uint64_t) pin));
82 gtk_widget_destroy (GTK_WIDGET (dialog)); 78 gtk_widget_destroy (GTK_WIDGET (dialog));
83 g_object_unref (G_OBJECT (builder)); 79 g_object_unref (G_OBJECT (builder));
84 AG_freeze (); 80 AG_freeze ();
@@ -98,21 +94,14 @@ anastasis_gtk_c_code_dialog_answer_entry_changed_cb (GtkEntry *entry,
98 GtkBuilder *builder = GTK_BUILDER (user_data); 94 GtkBuilder *builder = GTK_BUILDER (user_data);
99 GtkEntry *a; 95 GtkEntry *a;
100 const char *as; 96 const char *as;
101 unsigned int pin; 97 unsigned long long pin;
102 char dummy;
103 bool ok; 98 bool ok;
104 99
105 a = GTK_ENTRY (gtk_builder_get_object (builder, 100 a = GTK_ENTRY (gtk_builder_get_object (builder,
106 "anastasis_gtk_c_code_entry")); 101 "anastasis_gtk_c_code_entry"));
107 as = gtk_entry_get_text (a); 102 as = gtk_entry_get_text (a);
108 if ( (NULL != as) && 103 ok = ANASTASIS_scan_pin (as,
109 (0 == strncasecmp ("a-", as, 2)) ) 104 &pin);
110 as += 2; /* skip "A-" prefix if present */
111 ok = ( (NULL != as) &&
112 (1 == sscanf (as,
113 "%u%c",
114 &pin,
115 &dummy)) );
116 gtk_widget_set_sensitive ( 105 gtk_widget_set_sensitive (
117 GTK_WIDGET (gtk_builder_get_object (builder, 106 GTK_WIDGET (gtk_builder_get_object (builder,
118 "anastasis_gtk_c_code_dialog_btn_ok")), 107 "anastasis_gtk_c_code_dialog_btn_ok")),