Commit ed6f046f authored by Adam Schreiber's avatar Adam Schreiber

Use GTK+ GtkEntryBuffer for secure password entry.

Remove our own copy of GtkEntry, and use the new GtkEntryBuffer
in GTK+ 2.18. Bump requred GTK+ version.  These changes are copied
from seahorse an modified slightly.  The author of
seahorse-secure-buffer.[ch] is Stef Walter.
parent aab8e97a
......@@ -43,7 +43,7 @@ libseahorse_a_SOURCES = \
seahorse-gconf.c seahorse-gconf.h \
seahorse-gtkstock.c seahorse-gtkstock.h \
seahorse-secure-memory.c seahorse-secure-memory.h \
seahorse-secure-entry.c seahorse-secure-entry.h \
seahorse-secure-buffer.c seahorse-secure-buffer.h \
seahorse-algo.c seahorse-algo.h \
seahorse-unix-signal.c seahorse-unix-signal.h \
$(BUILT_SOURCES) \
......
......@@ -46,7 +46,7 @@
#include "seahorse-widget.h"
#include "seahorse-util.h"
#include "seahorse-passphrase.h"
#include "seahorse-secure-entry.h"
#include "seahorse-secure-buffer.h"
#include "seahorse-gpg-options.h"
#include "agent/seahorse-agent.h"
......@@ -122,7 +122,7 @@ static void
confirm_callback (GtkWidget *widget, GtkDialog *dialog)
{
GtkWidget *entry = GTK_WIDGET (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
g_assert (SEAHORSE_IS_SECURE_ENTRY (entry));
g_assert (GTK_IS_ENTRY (entry));
gtk_widget_grab_focus (entry);
}
......@@ -136,14 +136,14 @@ enter_callback (GtkWidget *widget, GtkDialog *dialog)
static void
entry_changed (GtkEditable *editable, GtkDialog *dialog)
{
SeahorseSecureEntry *entry, *confirm;
GtkEntry *entry, *confirm;
entry = SEAHORSE_SECURE_ENTRY (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
confirm = SEAHORSE_SECURE_ENTRY (g_object_get_data (G_OBJECT (dialog), "confirm-entry"));
entry = GTK_ENTRY (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
confirm = GTK_ENTRY (g_object_get_data (G_OBJECT (dialog), "confirm-entry"));
gtk_dialog_set_response_sensitive (dialog, GTK_RESPONSE_ACCEPT,
strcmp (seahorse_secure_entry_get_text (entry),
seahorse_secure_entry_get_text (confirm)) == 0);
strcmp (gtk_entry_get_text (entry),
gtk_entry_get_text (confirm)) == 0);
}
static gboolean
......@@ -185,7 +185,8 @@ seahorse_passphrase_prompt_show (const gchar *title, const gchar *description,
const gchar *prompt, const gchar *check,
gboolean confirm)
{
SeahorseSecureEntry *entry;
GtkEntryBuffer *buffer;
GtkEntry *entry;
GtkDialog *dialog;
GtkWidget *w;
GtkWidget *box;
......@@ -251,7 +252,9 @@ seahorse_passphrase_prompt_show (const gchar *title, const gchar *description,
g_free (msg);
gtk_table_attach (table, w, 0, 1, 0, 1, GTK_FILL, 0, 0, 0);
entry = SEAHORSE_SECURE_ENTRY (seahorse_secure_entry_new ());
buffer = seahorse_secure_buffer_new ();
entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
g_object_unref (buffer);
gtk_widget_set_size_request (GTK_WIDGET (entry), 200, -1);
g_object_set_data (G_OBJECT (dialog), "confirm-entry", entry);
g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (confirm_callback), dialog);
......@@ -267,7 +270,9 @@ seahorse_passphrase_prompt_show (const gchar *title, const gchar *description,
g_free (msg);
gtk_table_attach (table, w, 0, 1, 1, 2, GTK_FILL, 0, 0, 0);
entry = SEAHORSE_SECURE_ENTRY (seahorse_secure_entry_new ());
buffer = seahorse_secure_buffer_new ();
entry = GTK_ENTRY (gtk_entry_new_with_buffer (buffer));
g_object_unref (buffer);
gtk_widget_set_size_request (GTK_WIDGET (entry), 200, -1);
g_object_set_data (G_OBJECT (dialog), "secure-entry", entry);
g_signal_connect (G_OBJECT (entry), "activate", G_CALLBACK (enter_callback), dialog);
......@@ -315,10 +320,10 @@ seahorse_passphrase_prompt_show (const gchar *title, const gchar *description,
const gchar*
seahorse_passphrase_prompt_get (GtkDialog *dialog)
{
SeahorseSecureEntry *entry;
GtkEntry *entry;
entry = SEAHORSE_SECURE_ENTRY (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
return seahorse_secure_entry_get_text (entry);
entry = GTK_ENTRY (g_object_get_data (G_OBJECT (dialog), "secure-entry"));
return gtk_entry_get_text (entry);
}
gboolean
......
......@@ -32,7 +32,7 @@
#include "seahorse-check-button-control.h"
#include "seahorse-gconf.h"
#include "seahorse-gtkstock.h"
#include "seahorse-secure-entry.h"
#include "seahorse-secure-buffer.h"
#include "seahorse-widget.h"
/* From seahorse-prefs-cache.c */
......
/*
* Seahorse
*
* Copyright (C) 2010 Stefan Walter
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#include "config.h"
#include "seahorse-secure-buffer.h"
#include <gnome-keyring-memory.h>
#include <string.h>
/* Initial size of buffer, in bytes */
#define MIN_SIZE 16
struct _SeahorseSecureBufferPrivate
{
gchar *text;
gsize text_size;
gsize text_bytes;
guint text_chars;
};
G_DEFINE_TYPE (SeahorseSecureBuffer, seahorse_secure_buffer, GTK_TYPE_ENTRY_BUFFER);
/* --------------------------------------------------------------------------------
* SECURE IMPLEMENTATIONS OF TEXT BUFFER
*/
static const gchar*
seahorse_secure_buffer_real_get_text (GtkEntryBuffer *buffer, gsize *n_bytes)
{
SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (buffer);
if (n_bytes)
*n_bytes = self->priv->text_bytes;
if (!self->priv->text)
return "";
return self->priv->text;
}
static guint
seahorse_secure_buffer_real_get_length (GtkEntryBuffer *buffer)
{
SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (buffer);
return self->priv->text_chars;
}
static guint
seahorse_secure_buffer_real_insert_text (GtkEntryBuffer *buffer, guint position,
const gchar *chars, guint n_chars)
{
SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (buffer);
SeahorseSecureBufferPrivate *pv = self->priv;
gsize n_bytes;
gsize at;
n_bytes = g_utf8_offset_to_pointer (chars, n_chars) - chars;
/* Need more memory */
if (n_bytes + pv->text_bytes + 1 > pv->text_size) {
/* Calculate our new buffer size */
while (n_bytes + pv->text_bytes + 1 > pv->text_size) {
if (pv->text_size == 0) {
pv->text_size = MIN_SIZE;
} else {
if (2 * pv->text_size < GTK_ENTRY_BUFFER_MAX_SIZE) {
pv->text_size *= 2;
} else {
pv->text_size = GTK_ENTRY_BUFFER_MAX_SIZE;
if (n_bytes > pv->text_size - pv->text_bytes - 1) {
n_bytes = pv->text_size - pv->text_bytes - 1;
n_bytes = g_utf8_find_prev_char (chars, chars + n_bytes + 1) - chars;
n_chars = g_utf8_strlen (chars, n_bytes);
}
break;
}
}
}
pv->text = gnome_keyring_memory_realloc (pv->text, pv->text_size);
}
/* Actual text insertion */
at = g_utf8_offset_to_pointer (pv->text, position) - pv->text;
g_memmove (pv->text + at + n_bytes, pv->text + at, pv->text_bytes - at);
memcpy (pv->text + at, chars, n_bytes);
/* Book keeping */
pv->text_bytes += n_bytes;
pv->text_chars += n_chars;
pv->text[pv->text_bytes] = '\0';
gtk_entry_buffer_emit_inserted_text (buffer, position, chars, n_chars);
return n_chars;
}
static guint
seahorse_secure_buffer_real_delete_text (GtkEntryBuffer *buffer, guint position, guint n_chars)
{
SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (buffer);
SeahorseSecureBufferPrivate *pv = self->priv;
gsize start, end;
if (position > pv->text_chars)
position = pv->text_chars;
if (position + n_chars > pv->text_chars)
n_chars = pv->text_chars - position;
if (n_chars > 0) {
start = g_utf8_offset_to_pointer (pv->text, position) - pv->text;
end = g_utf8_offset_to_pointer (pv->text, position + n_chars) - pv->text;
g_memmove (pv->text + start, pv->text + end, pv->text_bytes + 1 - end);
pv->text_chars -= n_chars;
pv->text_bytes -= (end - start);
gtk_entry_buffer_emit_deleted_text (buffer, position, n_chars);
}
return n_chars;
}
/* --------------------------------------------------------------------------------
*
*/
static void
seahorse_secure_buffer_init (SeahorseSecureBuffer *self)
{
SeahorseSecureBufferPrivate *pv;
pv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, SEAHORSE_TYPE_SECURE_BUFFER, SeahorseSecureBufferPrivate);
pv->text = NULL;
pv->text_chars = 0;
pv->text_bytes = 0;
pv->text_size = 0;
}
static void
seahorse_secure_buffer_finalize (GObject *obj)
{
SeahorseSecureBuffer *self = SEAHORSE_SECURE_BUFFER (obj);
SeahorseSecureBufferPrivate *pv = self->priv;
if (pv->text) {
gnome_keyring_memory_free (pv->text);
pv->text = NULL;
pv->text_bytes = pv->text_size = 0;
pv->text_chars = 0;
}
G_OBJECT_CLASS (seahorse_secure_buffer_parent_class)->finalize (obj);
}
static void
seahorse_secure_buffer_class_init (SeahorseSecureBufferClass *klass)
{
GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
GtkEntryBufferClass *buffer_class = GTK_ENTRY_BUFFER_CLASS (klass);
gobject_class->finalize = seahorse_secure_buffer_finalize;
buffer_class->get_text = seahorse_secure_buffer_real_get_text;
buffer_class->get_length = seahorse_secure_buffer_real_get_length;
buffer_class->insert_text = seahorse_secure_buffer_real_insert_text;
buffer_class->delete_text = seahorse_secure_buffer_real_delete_text;
g_type_class_add_private (gobject_class, sizeof (SeahorseSecureBufferPrivate));
}
/* --------------------------------------------------------------------------------
*
*/
GtkEntryBuffer*
seahorse_secure_buffer_new (void)
{
return g_object_new (SEAHORSE_TYPE_SECURE_BUFFER, NULL);
}
/*
* Seahorse
*
* Copyright (C) 2010 Stefan Walter
*
* This program is free software; you can redistribute it and/or modify
* it under the terms of the GNU Lesser General Public License as
* published by the Free Software Foundation; either version 2.1 of
* the License, or (at your option) any later version.
*
* This program is distributed in the hope that it will be useful, but
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
*
* You should have received a copy of the GNU Lesser General Public
* License along with this program; if not, write to the Free Software
* Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
* 02111-1307, USA.
*/
#ifndef __SEAHORSE_SECURE_BUFFER_H__
#define __SEAHORSE_SECURE_BUFFER_H__
#include <gtk/gtk.h>
G_BEGIN_DECLS
#define SEAHORSE_TYPE_SECURE_BUFFER (seahorse_secure_buffer_get_type ())
#define SEAHORSE_SECURE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), SEAHORSE_TYPE_SECURE_BUFFER, SeahorseSecureBuffer))
#define SEAHORSE_SECURE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), SEAHORSE_TYPE_SECURE_BUFFER, SeahorseSecureBufferClass))
#define SEAHORSE_IS_SECURE_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SEAHORSE_TYPE_SECURE_BUFFER))
#define SEAHORSE_IS_SECURE_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), SEAHORSE_TYPE_SECURE_BUFFER))
#define SEAHORSE_SECURE_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), SEAHORSE_TYPE_SECURE_BUFFER, SeahorseSecureBufferClass))
typedef struct _SeahorseSecureBuffer SeahorseSecureBuffer;
typedef struct _SeahorseSecureBufferClass SeahorseSecureBufferClass;
typedef struct _SeahorseSecureBufferPrivate SeahorseSecureBufferPrivate;
struct _SeahorseSecureBuffer
{
GtkEntryBuffer parent;
SeahorseSecureBufferPrivate *priv;
};
struct _SeahorseSecureBufferClass
{
GtkEntryBufferClass parent_class;
};
GType seahorse_secure_buffer_get_type (void) G_GNUC_CONST;
GtkEntryBuffer* seahorse_secure_buffer_new (void);
G_END_DECLS
#endif /* __SEAHORSE_SECURE_BUFFER_H__ */
/*
* GTK - The GIMP Toolkit
* Copyright (C) 1995-1997 Peter Mattis, Spencer Kimball and Josh MacDonald
*
* This library is free software; you can redistribute it and/or
* modify it under the terms of the GNU Lesser General Public
* License as published by the Free Software Foundation; either
* version 2 of the License, or (at your option) any later version.
*
* This library is distributed in the hope that it will be useful,
* but WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* 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.
*/
/*
* Modified by the GTK+ Team and others 1997-2000. See the AUTHORS
* file for a list of people on the GTK+ Team. See the ChangeLog
* files for a list of changes. These files are distributed with
* GTK+ at ftp://ftp.gtk.org/pub/gtk/.
*/
/*
* Heavily stripped down for use in pinentry-gtk-2 by Albrecht Dreß
* <albrecht.dress@arcor.de> Feb. 2004.
*
* (C) by Albrecht Dreß 2004 unter the terms of the GNU Lesser General
* Public License.
*
* The entry is invisible by default, uses secure memory methods to
* allocate the text memory, and all potentially dangerous methods
* (copy & paste, popup, etc.) have been removed.
*/
/*
* Modified for inclusion into seahorse by Stef Walter
*/
#include <stdlib.h>
#include <string.h>
#include <gdk/gdkkeysyms.h>
#include <gtk/gtk.h>
#include "seahorse-secure-entry.h"
#include "seahorse-secure-memory.h"
#define MIN_SECURE_ENTRY_WIDTH 150
#define DRAW_TIMEOUT 20
#define INNER_BORDER 2
/* Initial size of buffer, in bytes */
#define MIN_SIZE 16
/* Maximum size of text buffer, in bytes */
#define MAX_SIZE G_MAXUSHORT
enum {
ACTIVATE,
MOVE_CURSOR,
INSERT_AT_CURSOR,
DELETE_FROM_CURSOR,
LAST_SIGNAL
};
enum {
PROP_0,
PROP_CURSOR_POSITION,
PROP_SELECTION_BOUND,
PROP_MAX_LENGTH,
PROP_HAS_FRAME,
PROP_INVISIBLE_CHAR,
PROP_ACTIVATES_DEFAULT,
PROP_WIDTH_CHARS,
PROP_SCROLL_OFFSET,
PROP_TEXT,
PROP_VISIBILITY
};
static guint signals[LAST_SIGNAL] = { 0 };
/* GObject, GtkObject methods */
static void seahorse_secure_entry_class_init (SeahorseSecureEntryClass *klass);
static void seahorse_secure_entry_editable_init (GtkEditableClass *iface);
static void seahorse_secure_entry_cell_editable_init (GtkCellEditableIface *iface);
static void seahorse_secure_entry_init (SeahorseSecureEntry *entry);
static void seahorse_secure_entry_set_property (GObject *object, guint prop_id,
const GValue *value, GParamSpec *pspec);
static void seahorse_secure_entry_get_property (GObject *object, guint prop_id,
GValue *value, GParamSpec *pspec);
static void seahorse_secure_entry_finalize (GObject *object);
/* GtkWidget methods */
static void seahorse_secure_entry_realize (GtkWidget *widget);
static void seahorse_secure_entry_unrealize (GtkWidget *widget);
static void seahorse_secure_entry_size_request (GtkWidget *widget, GtkRequisition *requisition);
static void seahorse_secure_entry_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
static void seahorse_secure_entry_draw_frame (GtkWidget *widget);
static gint seahorse_secure_entry_expose (GtkWidget *widget, GdkEventExpose *event);
static gint seahorse_secure_entry_button_press (GtkWidget *widget, GdkEventButton *event);
static gint seahorse_secure_entry_button_release (GtkWidget *widget, GdkEventButton *event);
static gint seahorse_secure_entry_motion_notify (GtkWidget *widget, GdkEventMotion *event);
static gint seahorse_secure_entry_key_press (GtkWidget *widget, GdkEventKey *event);
static gint seahorse_secure_entry_key_release (GtkWidget *widget, GdkEventKey *event);
static gint seahorse_secure_entry_focus_in (GtkWidget *widget, GdkEventFocus *event);
static gint seahorse_secure_entry_focus_out (GtkWidget *widget, GdkEventFocus *event);
static void seahorse_secure_entry_grab_focus (GtkWidget *widget);
static void seahorse_secure_entry_style_set (GtkWidget *widget, GtkStyle *previous_style);
static void seahorse_secure_entry_direction_changed (GtkWidget *widget, GtkTextDirection previous_dir);
static void seahorse_secure_entry_state_changed (GtkWidget *widget, GtkStateType previous_state);
static void seahorse_secure_entry_screen_changed (GtkWidget *widget, GdkScreen *old_screen);
/* GtkEditable method implementations */
static void seahorse_secure_entry_insert_text (GtkEditable *editable, const gchar *new_text,
gint new_text_length, gint *position);
static void seahorse_secure_entry_delete_text (GtkEditable *editable, gint start_pos, gint end_pos);
static void seahorse_secure_entry_real_set_position (GtkEditable *editable, gint position);
static gint seahorse_secure_entry_get_position (GtkEditable *editable);
static void seahorse_secure_entry_set_selection_bounds (GtkEditable *editable, gint start, gint end);
static gboolean seahorse_secure_entry_get_selection_bounds (GtkEditable *editable, gint *start, gint *end);
/* GtkCellEditable method implementations */
static void seahorse_secure_entry_start_editing (GtkCellEditable *cell_editable, GdkEvent *event);
/* Default signal handlers */
static void seahorse_secure_entry_real_insert_text (GtkEditable *editable, const gchar *new_text,
gint new_text_length, gint *position);
static void seahorse_secure_entry_real_delete_text (GtkEditable *editable, gint start_pos, gint end_pos);
static void seahorse_secure_entry_move_cursor (SeahorseSecureEntry *entry, GtkMovementStep step,
gint count, gboolean extend_selection);
static void seahorse_secure_entry_insert_at_cursor (SeahorseSecureEntry *entry, const gchar *str);
static void seahorse_secure_entry_delete_from_cursor (SeahorseSecureEntry *entry, GtkDeleteType type, gint count);
static void seahorse_secure_entry_real_activate (SeahorseSecureEntry *entry);
static void seahorse_secure_entry_keymap_direction_changed (GdkKeymap *keymap, SeahorseSecureEntry *entry);
/* IM Context Callbacks */
static void seahorse_secure_entry_commit_cb(GtkIMContext *context, const gchar *str, SeahorseSecureEntry *entry);
static void seahorse_secure_entry_preedit_changed_cb (GtkIMContext * context, SeahorseSecureEntry *entry);
static gboolean seahorse_secure_entry_retrieve_surrounding_cb (GtkIMContext *context, SeahorseSecureEntry *entry);
static gboolean seahorse_secure_entry_delete_surrounding_cb (GtkIMContext *context, gint offset,
gint n_chars, SeahorseSecureEntry *entry);
/* Internal routines */
static void seahorse_secure_entry_enter_text (SeahorseSecureEntry *entry, const gchar *str);
static void seahorse_secure_entry_set_positions (SeahorseSecureEntry *entry, gint current_pos, gint selection_bound);
static void seahorse_secure_entry_draw_text (SeahorseSecureEntry *entry);
static void seahorse_secure_entry_draw_cursor (SeahorseSecureEntry *entry);
static PangoLayout *seahorse_secure_entry_ensure_layout(SeahorseSecureEntry *entry, gboolean include_preedit);
static void seahorse_secure_entry_reset_layout (SeahorseSecureEntry *entry);
static void seahorse_secure_entry_queue_draw (SeahorseSecureEntry *entry);
static void seahorse_secure_entry_reset_im_context (SeahorseSecureEntry *entry);
static void seahorse_secure_entry_recompute (SeahorseSecureEntry *entry);
static gint seahorse_secure_entry_find_position (SeahorseSecureEntry *entry, gint x);
static void seahorse_secure_entry_get_cursor_locations (SeahorseSecureEntry *entry, gint *strong_x, gint *weak_x);
static void seahorse_secure_entry_adjust_scroll (SeahorseSecureEntry *entry);
static gint seahorse_secure_entry_move_visually (SeahorseSecureEntry *editable, gint start, gint count);
static gint seahorse_secure_entry_move_logically (SeahorseSecureEntry *entry, gint start, gint count);
static gboolean seahorse_secure_entry_mnemonic_activate (GtkWidget *widget, gboolean group_cycling);
static void seahorse_secure_entry_state_changed (GtkWidget *widget, GtkStateType previous_state);
static void seahorse_secure_entry_check_cursor_blink (SeahorseSecureEntry *entry);
static void seahorse_secure_entry_pend_cursor_blink (SeahorseSecureEntry *entry);
static void get_text_area_size (SeahorseSecureEntry *entry, gint *x, gint *y, gint *width, gint *height);
static void get_widget_window_size (SeahorseSecureEntry *entry, gint *x, gint *y, gint *width, gint *height);
#define _gtk_marshal_VOID__VOID g_cclosure_marshal_VOID__VOID
#define _gtk_marshal_VOID__STRING g_cclosure_marshal_VOID__STRING
static void _gtk_marshal_VOID__ENUM_INT_BOOLEAN (GClosure *closure, GValue *return_value,
guint n_param_values, const GValue *param_values,
gpointer invocation_hint, gpointer marshal_data);
static void _gtk_marshal_VOID__ENUM_INT (GClosure *closure, GValue *return_value, guint n_param_values,
const GValue *param_values, gpointer invocation_hint, gpointer marshal_data);
static GtkWidgetClass *parent_class = NULL;
GType
seahorse_secure_entry_get_type(void)
{
static GType entry_type = 0;
if (!entry_type) {
static const GTypeInfo entry_info = {
sizeof(SeahorseSecureEntryClass),
NULL, /* base_init */
NULL, /* base_finalize */
(GClassInitFunc) seahorse_secure_entry_class_init,
NULL, /* class_finalize */
NULL, /* class_data */
sizeof(SeahorseSecureEntry),
0, /* n_preallocs */
(GInstanceInitFunc) seahorse_secure_entry_init,
};
static const GInterfaceInfo editable_info = {
(GInterfaceInitFunc) seahorse_secure_entry_editable_init, /* interface_init */
NULL, /* interface_finalize */
NULL /* interface_data */
};
static const GInterfaceInfo cell_editable_info = {
(GInterfaceInitFunc) seahorse_secure_entry_cell_editable_init, /* interface_init */
NULL, /* interface_finalize */
NULL /* interface_data */
};
entry_type = g_type_register_static(GTK_TYPE_WIDGET, "SeahorseSecureEntry", &entry_info, 0);
g_type_add_interface_static(entry_type, GTK_TYPE_EDITABLE, &editable_info);
g_type_add_interface_static(entry_type, GTK_TYPE_CELL_EDITABLE, &cell_editable_info);
}
return entry_type;
}
static void
add_move_binding (GtkBindingSet *binding_set, guint keyval, guint modmask,
GtkMovementStep step, gint count)
{
g_return_if_fail ((modmask & GDK_SHIFT_MASK) == 0);
gtk_binding_entry_add_signal (binding_set, keyval, modmask, "move_cursor", 3,
G_TYPE_ENUM, step, G_TYPE_INT, count, G_TYPE_BOOLEAN, FALSE);
/* Selection-extending version */
gtk_binding_entry_add_signal (binding_set, keyval, modmask | GDK_SHIFT_MASK, "move_cursor",
3, G_TYPE_ENUM, step, G_TYPE_INT, count, G_TYPE_BOOLEAN, TRUE);
}
static void
seahorse_secure_entry_class_init(SeahorseSecureEntryClass *class)
{
GObjectClass *gobject_class = G_OBJECT_CLASS(class);
GtkWidgetClass *widget_class;
GtkBindingSet *binding_set;
widget_class = (GtkWidgetClass*) class;
parent_class = g_type_class_peek_parent (class);
gobject_class->finalize = seahorse_secure_entry_finalize;
gobject_class->set_property = seahorse_secure_entry_set_property;
gobject_class->get_property = seahorse_secure_entry_get_property;
widget_class->realize = seahorse_secure_entry_realize;
widget_class->unrealize = seahorse_secure_entry_unrealize;
widget_class->size_request = seahorse_secure_entry_size_request;
widget_class->size_allocate = seahorse_secure_entry_size_allocate;
widget_class->expose_event = seahorse_secure_entry_expose;
widget_class->button_press_event = seahorse_secure_entry_button_press;
widget_class->button_release_event = seahorse_secure_entry_button_release;
widget_class->motion_notify_event = seahorse_secure_entry_motion_notify;
widget_class->key_press_event = seahorse_secure_entry_key_press;
widget_class->key_release_event = seahorse_secure_entry_key_release;
widget_class->focus_in_event = seahorse_secure_entry_focus_in;
widget_class->focus_out_event = seahorse_secure_entry_focus_out;
widget_class->grab_focus = seahorse_secure_entry_grab_focus;
widget_class->style_set = seahorse_secure_entry_style_set;
widget_class->direction_changed = seahorse_secure_entry_direction_changed;
widget_class->state_changed = seahorse_secure_entry_state_changed;
widget_class->screen_changed = seahorse_secure_entry_screen_changed;
widget_class->mnemonic_activate = seahorse_secure_entry_mnemonic_activate;
class->move_cursor = seahorse_secure_entry_move_cursor;
class->insert_at_cursor = seahorse_secure_entry_insert_at_cursor;
class->delete_from_cursor = seahorse_secure_entry_delete_from_cursor;
class->activate = seahorse_secure_entry_real_activate;
g_object_class_install_property (gobject_class, PROP_CURSOR_POSITION,
g_param_spec_int ("cursor_position", "Cursor Position", "The current position of the insertion cursor in chars",
0, MAX_SIZE, 0, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_SELECTION_BOUND,
g_param_spec_int ("selection_bound", "Selection Bound", "The position of the opposite end of the selection from the cursor in chars",
0, MAX_SIZE, 0, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_MAX_LENGTH,
g_param_spec_int ("max_length", "Maximum length", "Maximum number of characters for this entry. Zero if no maximum",
0, MAX_SIZE, 0, G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_HAS_FRAME,
g_param_spec_boolean("has_frame", "Has Frame", "FALSE removes outside bevel from entry",
TRUE, G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_INVISIBLE_CHAR,
g_param_spec_unichar("invisible_char", "Invisible character", "The character to use when masking entry contents (in \"password mode\")",
'*', G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_ACTIVATES_DEFAULT,
g_param_spec_boolean ("activates_default", "Activates default", "Whether to activate the default widget (such as the default button in a dialog) when Enter is pressed",
FALSE, G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_WIDTH_CHARS,
g_param_spec_int ("width_chars", "Width in chars", "Number of characters to leave space for in the entry",
-1, G_MAXINT, -1, G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_SCROLL_OFFSET,
g_param_spec_int("scroll_offset", "Scroll offset", "Number of pixels of the entry scrolled off the screen to the left",
0, G_MAXINT, 0, G_PARAM_READABLE));
g_object_class_install_property (gobject_class, PROP_TEXT,
g_param_spec_string("text", "Text", "The contents of the entry",
"", G_PARAM_READABLE | G_PARAM_WRITABLE));
g_object_class_install_property (gobject_class, PROP_VISIBILITY,
g_param_spec_boolean ("visibility", "Visibility", "Whether contents are drawn using invisible character",
FALSE, G_PARAM_READWRITE));
/* Action signals */
signals[ACTIVATE] = g_signal_new ("activate", G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (SeahorseSecureEntryClass, activate),
NULL, NULL, _gtk_marshal_VOID__VOID, G_TYPE_NONE, 0);
widget_class->activate_signal = signals[ACTIVATE];
signals[MOVE_CURSOR] = g_signal_new ("move_cursor", G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (SeahorseSecureEntryClass, move_cursor),
NULL, NULL, _gtk_marshal_VOID__ENUM_INT_BOOLEAN,
G_TYPE_NONE, 3, GTK_TYPE_MOVEMENT_STEP, G_TYPE_INT, G_TYPE_BOOLEAN);
signals[INSERT_AT_CURSOR] = g_signal_new("insert_at_cursor", G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (SeahorseSecureEntryClass, insert_at_cursor),
NULL, NULL, _gtk_marshal_VOID__STRING, G_TYPE_NONE, 1, G_TYPE_STRING);
signals[DELETE_FROM_CURSOR] = g_signal_new("delete_from_cursor", G_OBJECT_CLASS_TYPE (gobject_class),
G_SIGNAL_RUN_LAST | G_SIGNAL_ACTION,
G_STRUCT_OFFSET (SeahorseSecureEntryClass, delete_from_cursor),
NULL, NULL, _gtk_marshal_VOID__ENUM_INT, G_TYPE_NONE, 2,
GTK_TYPE_DELETE_TYPE, G_TYPE_INT);
/* Key bindings */
binding_set = gtk_binding_set_by_class(class);
/* Moving the insertion point */
add_move_binding(binding_set, GDK_Right, 0, GTK_MOVEMENT_VISUAL_POSITIONS, 1);
add_move_binding(binding_set, GDK_Left, 0, GTK_MOVEMENT_VISUAL_POSITIONS, -1);
add_move_binding(binding_set, GDK_KP_Right, 0, GTK_MOVEMENT_VISUAL_POSITIONS, 1);
add_move_binding(binding_set, GDK_KP_Left, 0, GTK_MOVEMENT_VISUAL_POSITIONS, -1);
add_move_binding(binding_set, GDK_Right, GDK_CONTROL_MASK, GTK_MOVEMENT_WORDS, 1);
add_move_binding(binding_set, GDK_Left, GDK_CONTROL_MASK, GTK_MOVEMENT_WORDS, -1);
add_move_binding(binding_set, GDK_KP_Right, GDK_CONTROL_MASK, GTK_MOVEMENT_WORDS, 1);
add_move_binding(binding_set, GDK_KP_Left, GDK_CONTROL_MASK, GTK_MOVEMENT_WORDS, -1);
add_move_binding(binding_set, GDK_Home, 0, GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
add_move_binding(binding_set, GDK_End, 0, GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);
add_move_binding(binding_set, GDK_KP_Home, 0, GTK_MOVEMENT_DISPLAY_LINE_ENDS, -1);
add_move_binding(binding_set, GDK_KP_End, 0, GTK_MOVEMENT_DISPLAY_LINE_ENDS, 1);
add_move_binding(binding_set, GDK_Home, GDK_CONTROL_MASK, GTK_MOVEMENT_BUFFER_ENDS, -1);
add_move_binding(binding_set, GDK_End, GDK_CONTROL_MASK, GTK_MOVEMENT_BUFFER_ENDS, 1);
add_move_binding(binding_set, GDK_KP_Home, GDK_CONTROL_MASK, GTK_MOVEMENT_BUFFER_ENDS, -1);
add_move_binding(binding_set, GDK_KP_End, GDK_CONTROL_MASK, GTK_MOVEMENT_BUFFER_ENDS, 1);
/* Select all */
gtk_binding_entry_add_signal (binding_set, GDK_a, GDK_CONTROL_MASK, "move_cursor", 3,
GTK_TYPE_MOVEMENT_STEP, GTK_MOVEMENT_BUFFER_ENDS, G_TYPE_INT, -1,