/* unselect - work around a bug in GTK+ that permits word-selection to work on the invisible passphrase */ static void unselect(GtkWidget *w, GdkEventButton *e) { static gint lastpos; if (e->button == 1) { if (e->type == GDK_BUTTON_PRESS) { lastpos = gtk_editable_get_position(GTK_EDITABLE(entry)); } else if (e->type == GDK_2BUTTON_PRESS || e->type == GDK_3BUTTON_PRESS) { gtk_secure_entry_set_position(GTK_SECURE_ENTRY(w), lastpos); gtk_secure_entry_select_region(GTK_SECURE_ENTRY(w), 0, 0); } } }
static void button_clicked (GtkWidget *widget, gpointer data) { if (data) { const char *s; /* Okay button or enter used in text field. */ #ifdef ENABLE_ENHANCED /* FIXME: This is not compatible with assuan. We can't just print stuff on stdout. */ if (pinentry->enhanced) printf ("Options: %s\nTimeout: %d\n\n", gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (insure)) ? "insure" : "", gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (time_out))); #endif s = gtk_secure_entry_get_text (GTK_SECURE_ENTRY (entry)); if (!s) s = ""; passphrase_ok = 1; pinentry_setbufferlen (pinentry, strlen (s) + 1); if (pinentry->pin) strcpy (pinentry->pin, s); } gtk_main_quit (); }
static void button_clicked (GtkWidget *widget, gpointer data) { if (data) { /* Okay button hit or Enter used in the text field. */ const char *s; char *s_utf8; char *s_buffer; if (pinentry->enhanced) { printf("Options: %s\nTimeout: %d\n\n", gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(insure)) ? "insure" : "", gtk_spin_button_get_value_as_int(GTK_SPIN_BUTTON(time_out))); } pinentry->locale_err = 1; s = gtk_secure_entry_get_text (GTK_SECURE_ENTRY(entry)); if (!s) s = ""; s_buffer = secmem_malloc (strlen (s) + 1); if (s_buffer) { strcpy (s_buffer, s); s_utf8 = pinentry_local_to_utf8 (pinentry->lc_ctype, s_buffer, 1); secmem_free (s_buffer); if (s_utf8) { passphrase_ok = 1; pinentry_setbufferlen (pinentry, strlen (s_utf8) + 1); if (pinentry->pin) strcpy (pinentry->pin, s_utf8); secmem_free (s_utf8); pinentry->locale_err = 0; } } } gtk_main_quit (); }
/* Handler called for "changed". We use it to update the quality indicator. */ static void changed_text_handler (GtkWidget *widget) { char textbuf[50]; const char *s; int length; int percent; GdkColor color = { 0, 0, 0, 0}; got_input = TRUE; if (!qualitybar || !pinentry->quality_bar) return; s = gtk_secure_entry_get_text (GTK_SECURE_ENTRY (widget)); if (!s) s = ""; length = strlen (s); percent = length? pinentry_inq_quality (pinentry, s, length) : 0; if (!length) { strcpy(textbuf, QUALITYBAR_EMPTY_TEXT); color.red = 0xffff; } else if (percent < 0) { snprintf (textbuf, sizeof textbuf, "(%d%%)", -percent); color.red = 0xffff; percent = -percent; } else { snprintf (textbuf, sizeof textbuf, "%d%%", percent); color.green = 0xffff; } gtk_progress_bar_set_fraction (GTK_PROGRESS_BAR (qualitybar), (double)percent/100.0); gtk_progress_bar_set_text (GTK_PROGRESS_BAR (qualitybar), textbuf); gtk_widget_modify_bg (qualitybar, GTK_STATE_PRELIGHT, &color); }
static GtkWidget * create_window (int confirm_mode) { GtkWidget *w; GtkWidget *win, *box, *ebox; GtkWidget *sbox, *bbox; GtkAccelGroup *acc; /* fixme: check the grabbing code against the one we used with the old gpg-agent */ win = gtk_window_new (GTK_WINDOW_TOPLEVEL); acc = gtk_accel_group_new (); gtk_signal_connect (GTK_OBJECT (win), "delete_event", GTK_SIGNAL_FUNC (delete_event), NULL); #if 0 gtk_signal_connect (GTK_OBJECT(win), "destroy", gtk_main_quit, NULL); #endif gtk_signal_connect (GTK_OBJECT(win), "size-request", constrain_size, NULL); if (!confirm_mode) { gtk_signal_connect (GTK_OBJECT(win), pinentry->grab ? "map-event" : "focus-in-event", grab_keyboard, NULL); gtk_signal_connect (GTK_OBJECT(win), pinentry->grab ? "unmap-event" : "focus-out-event", ungrab_keyboard, NULL); } gtk_accel_group_attach(acc, GTK_OBJECT(win)); box = gtk_vbox_new (FALSE, 5); gtk_container_add (GTK_CONTAINER(win), box); gtk_container_set_border_width (GTK_CONTAINER (box), 5); if (pinentry->description) { w = create_utf8_label (pinentry->description); gtk_box_pack_start (GTK_BOX(box), w, TRUE, FALSE, 0); } if (pinentry->error && !confirm_mode) { GtkStyle *style; GdkColormap *cmap; GdkColor color[1] = {{0, 0xffff, 0, 0}}; gboolean success[1]; w = create_utf8_label (pinentry->error); gtk_box_pack_start (GTK_BOX(box), w, TRUE, FALSE, 5); /* fixme: Do we need to release something, or is there a more easy way to set a text color? */ gtk_widget_realize (win); cmap = gdk_window_get_colormap (win->window); assert (cmap); gdk_colormap_alloc_colors (cmap, color, 1, FALSE, TRUE, success); if (success[0]) { gtk_widget_ensure_style(w); style = gtk_style_copy(gtk_widget_get_style(w)); style->fg[GTK_STATE_NORMAL] = color[0]; gtk_widget_set_style(w, style); } } ebox = gtk_hbox_new (FALSE, 5); gtk_box_pack_start (GTK_BOX(box), ebox, FALSE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (ebox), 5); if (!confirm_mode) { if (pinentry->prompt) { w = create_utf8_label (pinentry->prompt); gtk_box_pack_start (GTK_BOX(ebox), w, FALSE, FALSE, 0); } entry = gtk_secure_entry_new (); gtk_signal_connect (GTK_OBJECT (entry), "activate", GTK_SIGNAL_FUNC (enter_callback), entry); gtk_box_pack_start (GTK_BOX(ebox), entry, TRUE, TRUE, 0); gtk_secure_entry_set_visibility (GTK_SECURE_ENTRY(entry), FALSE); gtk_signal_connect_after (GTK_OBJECT(entry), "button_press_event", unselect, NULL); gtk_widget_grab_focus (entry); gtk_widget_show (entry); if (pinentry->enhanced) { sbox = gtk_hbox_new(FALSE, 5); gtk_box_pack_start(GTK_BOX(box), sbox, FALSE, FALSE, 0); w = gtk_label_new ("Forget secret after"); gtk_box_pack_start(GTK_BOX(sbox), w, FALSE, FALSE, 0); gtk_widget_show(w); time_out = gtk_spin_button_new (GTK_ADJUSTMENT(gtk_adjustment_new(0, 0, HUGE_VAL, 1, 60, 60)),2,0); gtk_box_pack_start (GTK_BOX(sbox), time_out, FALSE, FALSE, 0); gtk_widget_show (time_out); w = gtk_label_new ("seconds"); gtk_box_pack_start (GTK_BOX(sbox), w, FALSE, FALSE, 0); gtk_widget_show (w); gtk_widget_show (sbox); insure = gtk_check_button_new_with_label ("ask before giving out secret"); gtk_box_pack_start (GTK_BOX(box), insure, FALSE, FALSE, 0); gtk_widget_show (insure); } } bbox = gtk_hbutton_box_new(); gtk_box_pack_start (GTK_BOX(box), bbox, TRUE, FALSE, 0); gtk_container_set_border_width (GTK_CONTAINER (bbox), 5); w = gtk_button_new_with_label (pinentry->ok ? pinentry->ok : "OK"); gtk_container_add (GTK_CONTAINER(bbox), w); if (!confirm_mode) { gtk_signal_connect (GTK_OBJECT(w), "clicked", button_clicked, "ok"); GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); gtk_widget_grab_default (w); gtk_signal_connect_object (GTK_OBJECT (entry), "focus_in_event", GTK_SIGNAL_FUNC (gtk_widget_grab_default), GTK_OBJECT (w)); } else { gtk_signal_connect (GTK_OBJECT(w), "clicked", confirm_button_clicked, "ok"); GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); } gtk_widget_show (w); if (!pinentry->one_button) { w = gtk_button_new_with_label (pinentry->cancel ? pinentry->cancel : "Cancel"); gtk_container_add (GTK_CONTAINER(bbox), w); gtk_accel_group_add (acc, GDK_Escape, 0, 0, GTK_OBJECT(w), "clicked"); gtk_signal_connect (GTK_OBJECT(w), "clicked", confirm_mode? confirm_button_clicked: button_clicked, NULL); GTK_WIDGET_SET_FLAGS (w, GTK_CAN_DEFAULT); } gtk_window_set_position (GTK_WINDOW (win), GTK_WIN_POS_CENTER); gtk_widget_show_all (win); return win; }