summaryrefslogtreecommitdiff
path: root/egg
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2009-12-19 19:00:01 +0000
committerStef Walter <stef@memberwebs.com>2009-12-19 19:00:01 +0000
commit17fa2269587102149148bea3ea859fea91415370 (patch)
tree241dbb0a8003209ddd9f3c73673f573460e0cb52 /egg
parenteab98c612084be6bfb2e7bb011e87879cc10940f (diff)
downloadgcr-17fa2269587102149148bea3ea859fea91415370.tar.gz
[daemon] Large refactoring of prompting for pkcs11 logins.
* Remove old ask code. * Remove old async code, location code daemon util code. * Move our custom GtkEntryBuffer into egg. * Remove old EggSecureEntry stuff. * Rework how threading works in pkcs11 daemon auth and prompting. * Use new prompting stuff for pkcs11 logins. * Make several fixes to the daemon/login code.
Diffstat (limited to 'egg')
-rw-r--r--egg/Makefile.am10
-rw-r--r--egg/egg-entry-buffer.c198
-rw-r--r--egg/egg-entry-buffer.h59
-rw-r--r--egg/egg-secure-entry.c2754
-rw-r--r--egg/egg-secure-entry.h187
5 files changed, 262 insertions, 2946 deletions
diff --git a/egg/Makefile.am b/egg/Makefile.am
index 21125f8..a065f84 100644
--- a/egg/Makefile.am
+++ b/egg/Makefile.am
@@ -6,7 +6,7 @@ noinst_LTLIBRARIES = \
libegg-dbus.la \
libegg-secure.la \
libegg-prompt.la \
- libegg-secure-entry.la
+ libegg-entry-buffer.la
BUILT_SOURCES = \
asn1-def-pk.h asn1-def-pkix.h
@@ -53,12 +53,12 @@ DISTCLEANFILES = \
# COMMON STUFF COMPILED INTO SMALLER COMPONENTS
libegg_secure_la_SOURCES = \
- egg-secure-memory.c egg-secure-memory.h
+ egg-secure-memory.c egg-secure-memory.h
-libegg_secure_entry_la_SOURCES = \
- egg-secure-entry.c egg-secure-entry.h
+libegg_entry_buffer_la_SOURCES = \
+ egg-entry-buffer.c egg-entry-buffer.h
-libegg_secure_entry_la_CFLAGS = \
+libegg_entry_buffer_la_CFLAGS = \
$(GOBJECT_CFLAGS) \
$(GLIB_CFLAGS) \
$(GTK_CFLAGS)
diff --git a/egg/egg-entry-buffer.c b/egg/egg-entry-buffer.c
new file mode 100644
index 0000000..afb4093
--- /dev/null
+++ b/egg/egg-entry-buffer.c
@@ -0,0 +1,198 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-secure-buffer.c - secure memory gtkentry buffer
+
+ Copyright (C) 2009 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef@memberwebs.com>
+*/
+
+#include "config.h"
+
+#include "egg-entry-buffer.h"
+#include "egg-secure-memory.h"
+
+#include <string.h>
+
+/* Initial size of buffer, in bytes */
+#define MIN_SIZE 16
+
+struct _EggEntryBufferPrivate
+{
+ gchar *text;
+ gsize text_size;
+ gsize text_bytes;
+ guint text_chars;
+};
+
+G_DEFINE_TYPE (EggEntryBuffer, egg_entry_buffer, GTK_TYPE_ENTRY_BUFFER);
+
+/* --------------------------------------------------------------------------------
+ * SECURE IMPLEMENTATIONS OF TEXT BUFFER
+ */
+
+static const gchar*
+egg_entry_buffer_real_get_text (GtkEntryBuffer *buffer, gsize *n_bytes)
+{
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (buffer);
+ if (n_bytes)
+ *n_bytes = self->priv->text_bytes;
+ if (!self->priv->text)
+ return "";
+ return self->priv->text;
+}
+
+static guint
+egg_entry_buffer_real_get_length (GtkEntryBuffer *buffer)
+{
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (buffer);
+ return self->priv->text_chars;
+}
+
+static guint
+egg_entry_buffer_real_insert_text (GtkEntryBuffer *buffer, guint position,
+ const gchar *chars, guint n_chars)
+{
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (buffer);
+ EggEntryBufferPrivate *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 = egg_secure_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
+egg_entry_buffer_real_delete_text (GtkEntryBuffer *buffer, guint position, guint n_chars)
+{
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (buffer);
+ EggEntryBufferPrivate *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
+egg_entry_buffer_init (EggEntryBuffer *self)
+{
+ EggEntryBufferPrivate *pv;
+ pv = self->priv = G_TYPE_INSTANCE_GET_PRIVATE (self, EGG_TYPE_ENTRY_BUFFER, EggEntryBufferPrivate);
+
+ pv->text = NULL;
+ pv->text_chars = 0;
+ pv->text_bytes = 0;
+ pv->text_size = 0;
+}
+
+static void
+egg_entry_buffer_finalize (GObject *obj)
+{
+ EggEntryBuffer *self = EGG_ENTRY_BUFFER (obj);
+ EggEntryBufferPrivate *pv = self->priv;
+
+ if (pv->text) {
+ egg_secure_strfree (pv->text);
+ pv->text = NULL;
+ pv->text_bytes = pv->text_size = 0;
+ pv->text_chars = 0;
+ }
+
+ G_OBJECT_CLASS (egg_entry_buffer_parent_class)->finalize (obj);
+}
+
+static void
+egg_entry_buffer_class_init (EggEntryBufferClass *klass)
+{
+ GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+ GtkEntryBufferClass *buffer_class = GTK_ENTRY_BUFFER_CLASS (klass);
+
+ gobject_class->finalize = egg_entry_buffer_finalize;
+
+ buffer_class->get_text = egg_entry_buffer_real_get_text;
+ buffer_class->get_length = egg_entry_buffer_real_get_length;
+ buffer_class->insert_text = egg_entry_buffer_real_insert_text;
+ buffer_class->delete_text = egg_entry_buffer_real_delete_text;
+
+ g_type_class_add_private (gobject_class, sizeof (EggEntryBufferPrivate));
+}
+
+/* --------------------------------------------------------------------------------
+ *
+ */
+
+GtkEntryBuffer*
+egg_entry_buffer_new (void)
+{
+ return g_object_new (EGG_TYPE_ENTRY_BUFFER, NULL);
+}
diff --git a/egg/egg-entry-buffer.h b/egg/egg-entry-buffer.h
new file mode 100644
index 0000000..1a7208d
--- /dev/null
+++ b/egg/egg-entry-buffer.h
@@ -0,0 +1,59 @@
+/* -*- Mode: C; indent-tabs-mode: t; c-basic-offset: 8; tab-width: 8 -*- */
+/* egg-secure-buffer.h - secure memory gtkentry buffer
+
+ Copyright (C) 2009 Stefan Walter
+
+ The Gnome Keyring Library is free software; you can redistribute it and/or
+ modify it under the terms of the GNU Library General Public License as
+ published by the Free Software Foundation; either version 2 of the
+ License, or (at your option) any later version.
+
+ The Gnome Keyring 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
+ Library General Public License for more details.
+
+ You should have received a copy of the GNU Library General Public
+ License along with the Gnome Library; see the file COPYING.LIB. If not,
+ write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
+ Boston, MA 02111-1307, USA.
+
+ Author: Stef Walter <stef@memberwebs.com>
+*/
+
+#ifndef __EGG_ENTRY_BUFFER_H__
+#define __EGG_ENTRY_BUFFER_H__
+
+#include <gtk/gtk.h>
+
+G_BEGIN_DECLS
+
+#define EGG_TYPE_ENTRY_BUFFER (egg_entry_buffer_get_type ())
+#define EGG_ENTRY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_ENTRY_BUFFER, EggEntryBuffer))
+#define EGG_ENTRY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_ENTRY_BUFFER, EggEntryBufferClass))
+#define EGG_IS_ENTRY_BUFFER(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_ENTRY_BUFFER))
+#define EGG_IS_ENTRY_BUFFER_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_ENTRY_BUFFER))
+#define EGG_ENTRY_BUFFER_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_ENTRY_BUFFER, EggEntryBufferClass))
+
+typedef struct _EggEntryBuffer EggEntryBuffer;
+typedef struct _EggEntryBufferClass EggEntryBufferClass;
+typedef struct _EggEntryBufferPrivate EggEntryBufferPrivate;
+
+struct _EggEntryBuffer
+{
+ GtkEntryBuffer parent;
+ EggEntryBufferPrivate *priv;
+};
+
+struct _EggEntryBufferClass
+{
+ GtkEntryBufferClass parent_class;
+};
+
+GType egg_entry_buffer_get_type (void) G_GNUC_CONST;
+
+GtkEntryBuffer* egg_entry_buffer_new (void);
+
+G_END_DECLS
+
+#endif /* __EGG_ENTRY_BUFFER_H__ */
diff --git a/egg/egg-secure-entry.c b/egg/egg-secure-entry.c
deleted file mode 100644
index 6e92e1c..0000000
--- a/egg/egg-secure-entry.c
+++ /dev/null
@@ -1,2754 +0,0 @@
-/*
- * 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 gnome-keyring by Stef Walter
- */
-
-#include <stdlib.h>
-#include <string.h>
-#include <gdk/gdkkeysyms.h>
-#include <gtk/gtk.h>
-
-#include "egg-secure-entry.h"
-#include "egg-secure-memory.h"
-
-#define MIN_ASK_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 egg_secure_entry_class_init (EggSecureEntryClass *klass);
-static void egg_secure_entry_editable_init (GtkEditableClass *iface);
-static void egg_secure_entry_cell_editable_init (GtkCellEditableIface *iface);
-static void egg_secure_entry_init (EggSecureEntry *entry);
-static void egg_secure_entry_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec);
-static void egg_secure_entry_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec);
-static void egg_secure_entry_finalize (GObject *object);
-
-/* GtkWidget methods */
-static void egg_secure_entry_realize (GtkWidget *widget);
-static void egg_secure_entry_unrealize (GtkWidget *widget);
-static void egg_secure_entry_size_request (GtkWidget *widget, GtkRequisition *requisition);
-static void egg_secure_entry_size_allocate (GtkWidget *widget, GtkAllocation *allocation);
-static void egg_secure_entry_draw_frame (GtkWidget *widget);
-static gint egg_secure_entry_expose (GtkWidget *widget, GdkEventExpose *event);
-static gint egg_secure_entry_button_press (GtkWidget *widget, GdkEventButton *event);
-static gint egg_secure_entry_button_release (GtkWidget *widget, GdkEventButton *event);
-static gint egg_secure_entry_motion_notify (GtkWidget *widget, GdkEventMotion *event);
-static gint egg_secure_entry_key_press (GtkWidget *widget, GdkEventKey *event);
-static gint egg_secure_entry_key_release (GtkWidget *widget, GdkEventKey *event);
-static gint egg_secure_entry_focus_in (GtkWidget *widget, GdkEventFocus *event);
-static gint egg_secure_entry_focus_out (GtkWidget *widget, GdkEventFocus *event);
-static void egg_secure_entry_grab_focus (GtkWidget *widget);
-static void egg_secure_entry_style_set (GtkWidget *widget, GtkStyle *previous_style);
-static void egg_secure_entry_direction_changed (GtkWidget *widget, GtkTextDirection previous_dir);
-static void egg_secure_entry_state_changed (GtkWidget *widget, GtkStateType previous_state);
-static void egg_secure_entry_screen_changed (GtkWidget *widget, GdkScreen *old_screen);
-
-/* GtkEditable method implementations */
-static void egg_secure_entry_insert_text (GtkEditable *editable, const gchar *new_text,
- gint new_text_length, gint *position);
-static void egg_secure_entry_delete_text (GtkEditable *editable, gint start_pos, gint end_pos);
-static void egg_secure_entry_real_set_position (GtkEditable *editable, gint position);
-static gint egg_secure_entry_get_position (GtkEditable *editable);
-static void egg_secure_entry_set_selection_bounds (GtkEditable *editable, gint start, gint end);
-static gboolean egg_secure_entry_get_selection_bounds (GtkEditable *editable, gint *start, gint *end);
-
-/* GtkCellEditable method implementations */
-static void egg_secure_entry_start_editing (GtkCellEditable *cell_editable, GdkEvent *event);
-
-/* Default signal handlers */
-static void egg_secure_entry_real_insert_text (GtkEditable *editable, const gchar *new_text,
- gint new_text_length, gint *position);
-static void egg_secure_entry_real_delete_text (GtkEditable *editable, gint start_pos, gint end_pos);
-static void egg_secure_entry_move_cursor (EggSecureEntry *entry, GtkMovementStep step,
- gint count, gboolean extend_selection);
-static void egg_secure_entry_insert_at_cursor (EggSecureEntry *entry, const gchar *str);
-static void egg_secure_entry_delete_from_cursor (EggSecureEntry *entry, GtkDeleteType type, gint count);
-static void egg_secure_entry_real_activate (EggSecureEntry *entry);
-static void egg_secure_entry_keymap_direction_changed (GdkKeymap *keymap, EggSecureEntry *entry);
-
-/* IM Context Callbacks */
-static void egg_secure_entry_commit_cb(GtkIMContext *context, const gchar *str, EggSecureEntry *entry);
-static void egg_secure_entry_preedit_changed_cb (GtkIMContext * context, EggSecureEntry *entry);
-static gboolean egg_secure_entry_retrieve_surrounding_cb (GtkIMContext *context, EggSecureEntry *entry);
-static gboolean egg_secure_entry_delete_surrounding_cb (GtkIMContext *context, gint offset,
- gint n_chars, EggSecureEntry *entry);
-
-/* Internal routines */
-static void egg_secure_entry_enter_text (EggSecureEntry *entry, const gchar *str);
-static void egg_secure_entry_set_positions (EggSecureEntry *entry, gint current_pos, gint selection_bound);
-static void egg_secure_entry_draw_text (EggSecureEntry *entry);
-static void egg_secure_entry_draw_cursor (EggSecureEntry *entry);
-static PangoLayout *egg_secure_entry_ensure_layout(EggSecureEntry *entry, gboolean include_preedit);
-static void egg_secure_entry_reset_layout (EggSecureEntry *entry);
-static void egg_secure_entry_queue_draw (EggSecureEntry *entry);
-static void egg_secure_entry_reset_im_context (EggSecureEntry *entry);
-static void egg_secure_entry_recompute (EggSecureEntry *entry);
-static gint egg_secure_entry_find_position (EggSecureEntry *entry, gint x);
-static void egg_secure_entry_get_cursor_locations (EggSecureEntry *entry, gint *strong_x, gint *weak_x);
-static void egg_secure_entry_adjust_scroll (EggSecureEntry *entry);
-static gint egg_secure_entry_move_visually (EggSecureEntry *editable, gint start, gint count);
-static gint egg_secure_entry_move_logically (EggSecureEntry *entry, gint start, gint count);
-static gboolean egg_secure_entry_mnemonic_activate (GtkWidget *widget, gboolean group_cycling);
-static void egg_secure_entry_state_changed (GtkWidget *widget, GtkStateType previous_state);
-static void egg_secure_entry_check_cursor_blink (EggSecureEntry *entry);
-static void egg_secure_entry_pend_cursor_blink (EggSecureEntry *entry);
-static void get_text_area_size (EggSecureEntry *entry, gint *x, gint *y, gint *width, gint *height);
-static void get_widget_window_size (EggSecureEntry *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
-egg_secure_entry_get_type(void)
-{
- static GType entry_type = 0;
-
- if (!entry_type) {
- static const GTypeInfo entry_info = {
- sizeof(EggSecureEntryClass),
- NULL, /* base_init */
- NULL, /* base_finalize */
- (GClassInitFunc) egg_secure_entry_class_init,
- NULL, /* class_finalize */
- NULL, /* class_data */
- sizeof(EggSecureEntry),
- 0, /* n_preallocs */
- (GInstanceInitFunc) egg_secure_entry_init,
- };
-
- static const GInterfaceInfo editable_info = {
- (GInterfaceInitFunc) egg_secure_entry_editable_init, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
- static const GInterfaceInfo cell_editable_info = {
- (GInterfaceInitFunc) egg_secure_entry_cell_editable_init, /* interface_init */
- NULL, /* interface_finalize */
- NULL /* interface_data */
- };
-
- entry_type = g_type_register_static(GTK_TYPE_WIDGET, "EggSecureEntry", &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
-egg_secure_entry_class_init(EggSecureEntryClass *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 = egg_secure_entry_finalize;
- gobject_class->set_property = egg_secure_entry_set_property;
- gobject_class->get_property = egg_secure_entry_get_property;
-
- widget_class->realize = egg_secure_entry_realize;
- widget_class->unrealize = egg_secure_entry_unrealize;
- widget_class->size_request = egg_secure_entry_size_request;
- widget_class->size_allocate = egg_secure_entry_size_allocate;
- widget_class->expose_event = egg_secure_entry_expose;
- widget_class->button_press_event = egg_secure_entry_button_press;
- widget_class->button_release_event = egg_secure_entry_button_release;
- widget_class->motion_notify_event = egg_secure_entry_motion_notify;
- widget_class->key_press_event = egg_secure_entry_key_press;
- widget_class->key_release_event = egg_secure_entry_key_release;
- widget_class->focus_in_event = egg_secure_entry_focus_in;
- widget_class->focus_out_event = egg_secure_entry_focus_out;
- widget_class->grab_focus = egg_secure_entry_grab_focus;
- widget_class->style_set = egg_secure_entry_style_set;
- widget_class->direction_changed = egg_secure_entry_direction_changed;
- widget_class->state_changed = egg_secure_entry_state_changed;
- widget_class->screen_changed = egg_secure_entry_screen_changed;
- widget_class->mnemonic_activate = egg_secure_entry_mnemonic_activate;
-
- class->move_cursor = egg_secure_entry_move_cursor;
- class->insert_at_cursor = egg_secure_entry_insert_at_cursor;
- class->delete_from_cursor = egg_secure_entry_delete_from_cursor;
- class->activate = egg_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 (EggSecureEntryClass, 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 (EggSecureEntryClass, 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 (EggSecureEntryClass, 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 (EggSecureEntryClass, 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,
- G_TYPE_BOOLEAN, FALSE);
- 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,
- G_TYPE_BOOLEAN, TRUE);
-
- /* Activate */
- gtk_binding_entry_add_signal (binding_set, GDK_Return, 0, "activate", 0);
- gtk_binding_entry_add_signal (binding_set, GDK_KP_Enter, 0, "activate", 0);
-
- /* Deleting text */
- gtk_binding_entry_add_signal (binding_set, GDK_Delete, 0, "delete_from_cursor", 2,
- G_TYPE_ENUM, GTK_DELETE_CHARS, G_TYPE_INT, 1);
- gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, 0, "delete_from_cursor", 2,
- G_TYPE_ENUM, GTK_DELETE_CHARS, G_TYPE_INT, 1);
- gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, 0, "delete_from_cursor", 2,
- G_TYPE_ENUM, GTK_DELETE_CHARS, G_TYPE_INT, -1);
- /* Make this do the same as Backspace, to help with mis-typing */
- gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_SHIFT_MASK, "delete_from_cursor", 2,
- G_TYPE_ENUM, GTK_DELETE_CHARS, G_TYPE_INT, -1);
- gtk_binding_entry_add_signal (binding_set, GDK_Delete, GDK_CONTROL_MASK, "delete_from_cursor", 2,
- G_TYPE_ENUM, GTK_DELETE_WORD_ENDS, G_TYPE_INT, 1);
- gtk_binding_entry_add_signal (binding_set, GDK_KP_Delete, GDK_CONTROL_MASK, "delete_from_cursor", 2,
- G_TYPE_ENUM, GTK_DELETE_WORD_ENDS, G_TYPE_INT, 1);
- gtk_binding_entry_add_signal (binding_set, GDK_BackSpace, GDK_CONTROL_MASK, "delete_from_cursor", 2,
- G_TYPE_ENUM, GTK_DELETE_WORD_ENDS, G_TYPE_INT, -1);
-}
-
-static void
-egg_secure_entry_editable_init (GtkEditableClass *iface)
-{
- iface->do_insert_text = egg_secure_entry_insert_text;
- iface->do_delete_text = egg_secure_entry_delete_text;
- iface->insert_text = egg_secure_entry_real_insert_text;
- iface->delete_text = egg_secure_entry_real_delete_text;
- iface->set_selection_bounds = egg_secure_entry_set_selection_bounds;
- iface->get_selection_bounds = egg_secure_entry_get_selection_bounds;
- iface->set_position = egg_secure_entry_real_set_position;
- iface->get_position = egg_secure_entry_get_position;
-}
-
-static void
-egg_secure_entry_cell_editable_init (GtkCellEditableIface * iface)
-{
- iface->start_editing = egg_secure_entry_start_editing;
-}
-
-static void
-egg_secure_entry_set_property (GObject *object, guint prop_id,
- const GValue *value, GParamSpec *pspec)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY(object);
-
- switch (prop_id) {
- case PROP_MAX_LENGTH:
- egg_secure_entry_set_max_length(entry, g_value_get_int(value));
- break;
-
- case PROP_HAS_FRAME:
- egg_secure_entry_set_has_frame(entry, g_value_get_boolean(value));
- break;
-
- case PROP_INVISIBLE_CHAR:
- egg_secure_entry_set_invisible_char(entry, g_value_get_uint(value));
- break;
-
- case PROP_ACTIVATES_DEFAULT:
- egg_secure_entry_set_activates_default(entry, g_value_get_boolean(value));
- break;
-
- case PROP_WIDTH_CHARS:
- egg_secure_entry_set_width_chars(entry, g_value_get_int(value));
- break;
-
- case PROP_TEXT:
- egg_secure_entry_set_text(entry, g_value_get_string(value));
- break;
-
- case PROP_VISIBILITY:
- egg_secure_entry_set_visibility (entry, g_value_get_boolean (value));
- break;
-
- case PROP_SCROLL_OFFSET:
- case PROP_CURSOR_POSITION:
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-egg_secure_entry_get_property (GObject *object, guint prop_id,
- GValue *value, GParamSpec *pspec)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY(object);
-
- switch (prop_id) {
- case PROP_CURSOR_POSITION:
- g_value_set_int(value, entry->current_pos);
- break;
- case PROP_SELECTION_BOUND:
- g_value_set_int(value, entry->selection_bound);
- break;
- case PROP_MAX_LENGTH:
- g_value_set_int(value, entry->text_max_length);
- break;
- case PROP_HAS_FRAME:
- g_value_set_boolean(value, entry->has_frame);
- break;
- case PROP_INVISIBLE_CHAR:
- g_value_set_uint(value, entry->invisible_char);
- break;
- case PROP_ACTIVATES_DEFAULT:
- g_value_set_boolean(value, entry->activates_default);
- break;
- case PROP_WIDTH_CHARS:
- g_value_set_int(value, entry->width_chars);
- break;
- case PROP_SCROLL_OFFSET:
- g_value_set_int(value, entry->scroll_offset);
- break;
- case PROP_TEXT:
- g_value_set_string(value, egg_secure_entry_get_text(entry));
- break;
- case PROP_VISIBILITY:
- g_value_set_boolean (value, egg_secure_entry_get_visibility (entry));
- break;
-
- default:
- G_OBJECT_WARN_INVALID_PROPERTY_ID(object, prop_id, pspec);
- break;
- }
-}
-
-static void
-egg_secure_entry_init (EggSecureEntry *entry)
-{
- GtkStyle *style;
- GtkWidget *tempent;
-
- GTK_WIDGET_SET_FLAGS (entry, GTK_CAN_FOCUS);
-
- /* Get the RC style for a normal GtkEntry */
- style = gtk_rc_get_style_by_paths (gtk_widget_get_settings (GTK_WIDGET (entry)),
- NULL, NULL, GTK_TYPE_ENTRY);
- gtk_widget_set_style (GTK_WIDGET (entry), style);
-
- entry->text_size = MIN_SIZE;
- entry->text = egg_secure_alloc (entry->text_size + 1);
- entry->text[0] = '\0';
-
- entry->visibility = FALSE;
- entry->width_chars = -1;
- entry->is_cell_renderer = FALSE;
- entry->editing_canceled = FALSE;
- entry->has_frame = TRUE;
-
- /* Use the invisible_char from GtkEntry */
- tempent = gtk_entry_new ();
- entry->invisible_char = gtk_entry_get_invisible_char (GTK_ENTRY (tempent));
- g_object_ref_sink (tempent);
- g_object_unref (tempent);
-
- /*
- * This object is completely private. No external entity can gain a reference
- * to it; so we create it here and destroy it in finalize().
- */
- entry->im_context = gtk_im_context_simple_new ();
-
- g_signal_connect (entry->im_context, "commit",
- G_CALLBACK (egg_secure_entry_commit_cb), entry);
- g_signal_connect (entry->im_context, "preedit_changed",
- G_CALLBACK(egg_secure_entry_preedit_changed_cb), entry);
- g_signal_connect (entry->im_context, "retrieve_surrounding",
- G_CALLBACK(egg_secure_entry_retrieve_surrounding_cb), entry);
- g_signal_connect (entry->im_context, "delete_surrounding",
- G_CALLBACK(egg_secure_entry_delete_surrounding_cb), entry);
-}
-
-static void
-egg_secure_entry_finalize (GObject *object)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (object);
-
- if (entry->cached_layout)
- g_object_unref (entry->cached_layout);
-
- g_object_unref (entry->im_context);
-
- if (entry->blink_timeout)
- g_source_remove (entry->blink_timeout);
-
- if (entry->recompute_idle)
- g_source_remove (entry->recompute_idle);
-
- entry->text_size = 0;
-
- if (entry->text)
- egg_secure_free (entry->text);
- entry->text = NULL;
-
- G_OBJECT_CLASS (parent_class)->finalize (object);
-}
-
-static void
-egg_secure_entry_realize (GtkWidget *widget)
-{
- EggSecureEntry *entry;
- GtkEditable *editable;
- GdkWindowAttr attributes;
- gint attributes_mask;
-
- GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
- entry = EGG_SECURE_ENTRY (widget);
- editable = GTK_EDITABLE (widget);
-
- attributes.window_type = GDK_WINDOW_CHILD;
-
- get_widget_window_size (entry, &attributes.x, &attributes.y,
- &attributes.width, &attributes.height);
-
- attributes.wclass = GDK_INPUT_OUTPUT;
- attributes.visual = gtk_widget_get_visual (widget);
- attributes.colormap = gtk_widget_get_colormap (widget);
- attributes.event_mask = gtk_widget_get_events (widget);
- attributes.event_mask |= (GDK_EXPOSURE_MASK | GDK_BUTTON_PRESS_MASK |
- GDK_BUTTON_RELEASE_MASK | GDK_BUTTON1_MOTION_MASK |
- GDK_BUTTON3_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK |
- GDK_POINTER_MOTION_MASK | GDK_ENTER_NOTIFY_MASK |
- GDK_LEAVE_NOTIFY_MASK);
- attributes_mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-
- widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
- &attributes, attributes_mask);
- gdk_window_set_user_data (widget->window, entry);
-
- get_text_area_size (entry, &attributes.x, &attributes.y,
- &attributes.width, &attributes.height);
-
- attributes.cursor = gdk_cursor_new_for_display (gtk_widget_get_display (widget),
- GDK_XTERM);
- attributes_mask |= GDK_WA_CURSOR;
-
- entry->text_area = gdk_window_new (widget->window, &attributes, attributes_mask);
- gdk_window_set_user_data (entry->text_area, entry);
-
- gdk_cursor_unref (attributes.cursor);
-
- widget->style = gtk_style_attach (widget->style, widget->window);
-
- gdk_window_set_background (widget->window,
- &widget->style->base[GTK_WIDGET_STATE (widget)]);
- gdk_window_set_background (entry->text_area,
- &widget->style->base[GTK_WIDGET_STATE (widget)]);
-
- gdk_window_show (entry->text_area);
-
- gtk_im_context_set_client_window (entry->im_context, entry->text_area);
-
- egg_secure_entry_adjust_scroll (entry);
-}
-
-static void
-egg_secure_entry_unrealize (GtkWidget *widget)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
-
- egg_secure_entry_reset_layout (entry);
-
- gtk_im_context_set_client_window (entry->im_context, NULL);
-
- if (entry->text_area) {
- gdk_window_set_user_data (entry->text_area, NULL);
- gdk_window_destroy (entry->text_area);
- entry->text_area = NULL;
- }
-
- if (GTK_WIDGET_CLASS (parent_class)->unrealize)
- (*GTK_WIDGET_CLASS (parent_class)->unrealize) (widget);
-}
-
-static void
-get_borders (EggSecureEntry *entry, gint *xborder, gint *yborder)
-{
- GtkWidget *widget = GTK_WIDGET (entry);
- gint focus_width;
- gboolean interior_focus;
-
- gtk_widget_style_get (widget, "interior-focus", &interior_focus,
- "focus-line-width", &focus_width, NULL);
-
- if (entry->has_frame) {
- *xborder = widget->style->xthickness;
- *yborder = widget->style->ythickness;
- } else {
- *xborder = 0;
- *yborder = 0;
- }
-
- if (!interior_focus) {
- *xborder += focus_width;
- *yborder += focus_width;
- }
-}
-
-static void
-egg_secure_entry_size_request (GtkWidget *widget, GtkRequisition *requisition)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
- PangoFontMetrics *metrics;
- gint xborder, yborder;
- PangoContext *context;
-
- context = gtk_widget_get_pango_context (widget);
- metrics = pango_context_get_metrics (context, widget->style->font_desc,
- pango_context_get_language (context));
-
- entry->ascent = pango_font_metrics_get_ascent (metrics);
- entry->descent = pango_font_metrics_get_descent (metrics);
-
- get_borders (entry, &xborder, &yborder);
-
- xborder += INNER_BORDER;
- yborder += INNER_BORDER;
-
- if (entry->width_chars < 0)
- requisition->width = MIN_ASK_ENTRY_WIDTH + xborder * 2;
- else {
- gint char_width = pango_font_metrics_get_approximate_char_width (metrics);
- gint digit_width = pango_font_metrics_get_approximate_digit_width (metrics);
- gint char_pixels = (MAX (char_width, digit_width) + PANGO_SCALE - 1) / PANGO_SCALE;
- requisition->width = char_pixels * entry->width_chars + xborder * 2;
- }
-
- requisition->height = PANGO_PIXELS (entry->ascent + entry->descent) + yborder * 2;
- pango_font_metrics_unref(metrics);
-}
-
-static void
-get_text_area_size(EggSecureEntry *entry, gint *x, gint *y, gint *width, gint *height)
-{
- gint xborder, yborder;
- GtkRequisition requisition;
- GtkWidget *widget = GTK_WIDGET (entry);
-
- gtk_widget_get_child_requisition (widget, &requisition);
-
- get_borders (entry, &xborder, &yborder);
-
- if (x)
- *x = xborder;
-
- if (y)
- *y = yborder;
-
- if (width)
- *width = GTK_WIDGET (entry)->allocation.width - xborder * 2;
-
- if (height)
- *height = requisition.height - yborder * 2;
-}
-
-static void
-get_widget_window_size (EggSecureEntry *entry, gint *x, gint *y, gint *width, gint *height)
-{
- GtkRequisition requisition;
- GtkWidget *widget = GTK_WIDGET (entry);
-
- gtk_widget_get_child_requisition (widget, &requisition);
-
- if (x)
- *x = widget->allocation.x;
-
- if (y) {
- if (entry->is_cell_renderer)
- *y = widget->allocation.y;
- else
- *y = widget->allocation.y + (widget->allocation.height -
- requisition.height) / 2;
- }
-
- if (width)
- *width = widget->allocation.width;
-
- if (height) {
- if (entry->is_cell_renderer)
- *height = widget->allocation.height;
- else
- *height = requisition.height;
- }
-}
-
-static void
-egg_secure_entry_size_allocate(GtkWidget *widget, GtkAllocation *allocation)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY(widget);
-
- widget->allocation = *allocation;
-
- if (GTK_WIDGET_REALIZED (widget)) {
- /*
- * We call gtk_widget_get_child_requisition, since we want (for
- * backwards compatibility reasons) the realization here to
- * be affected by the usize of the entry, if set
- */
- gint x, y, width, height;
-
- get_widget_window_size (entry, &x, &y, &width, &height);
-
- gdk_window_move_resize (widget->window, x, y, width, height);
-
- get_text_area_size (entry, &x, &y, &width, &height);
-
- gdk_window_move_resize (entry->text_area, x, y, width, height);
-
- egg_secure_entry_recompute (entry);
- }
-}
-
-static void
-egg_secure_entry_draw_frame (GtkWidget *widget)
-{
- gint x = 0, y = 0;
- gint width, height;
- gboolean interior_focus;
- gint focus_width;
-
- gtk_widget_style_get (widget, "interior-focus", &interior_focus,
- "focus-line-width", &focus_width, NULL);
-
- gdk_drawable_get_size (widget->window, &width, &height);
-
- if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) {
- x += focus_width;
- y += focus_width;
- width -= 2 * focus_width;
- height -= 2 * focus_width;
- }
-
- gtk_paint_shadow (widget->style, widget->window, GTK_STATE_NORMAL, GTK_SHADOW_IN,
- NULL, widget, "entry", x, y, width, height);
-
- if (GTK_WIDGET_HAS_FOCUS (widget) && !interior_focus) {
- x -= focus_width;
- y -= focus_width;
- width += 2 * focus_width;
- height += 2 * focus_width;
-
- gtk_paint_focus(widget->style, widget->window, GTK_WIDGET_STATE (widget),
- NULL, widget, "entry", 0, 0, width, height);
- }
-}
-
-static gint
-egg_secure_entry_expose(GtkWidget *widget, GdkEventExpose *event)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY(widget);
-
- if (widget->window == event->window)
- egg_secure_entry_draw_frame(widget);
- else if (entry->text_area == event->window) {
- gint area_width, area_height;
-
- get_text_area_size(entry, NULL, NULL, &area_width, &area_height);
-
- gtk_paint_flat_box(widget->style, entry->text_area, GTK_WIDGET_STATE (widget), GTK_SHADOW_NONE,
- NULL, widget, "entry_bg", 0, 0, area_width, area_height);
-
- if ((entry->invisible_char != 0) && GTK_WIDGET_HAS_FOCUS (widget) &&
- entry->selection_bound == entry->current_pos && entry->cursor_visible)
- egg_secure_entry_draw_cursor (EGG_SECURE_ENTRY (widget));
-
- egg_secure_entry_draw_text (EGG_SECURE_ENTRY (widget));
- }
-
- return FALSE;
-}
-
-static gint
-egg_secure_entry_button_press(GtkWidget *widget, GdkEventButton *event)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
- gint tmp_pos;
-
- if (event->window != entry->text_area ||
- (entry->button && event->button != entry->button))
- return FALSE;
-
- entry->button = event->button;
-
- if (!GTK_WIDGET_HAS_FOCUS (widget)) {
- entry->in_click = TRUE;
- gtk_widget_grab_focus (widget);
- entry->in_click = FALSE;
- }
-
- tmp_pos = egg_secure_entry_find_position (entry, event->x + entry->scroll_offset);
-
- if (event->button == 1) {
- switch (event->type) {
- case GDK_BUTTON_PRESS:
- egg_secure_entry_set_positions(entry, tmp_pos, tmp_pos);
- break;
- default:
- break;
- }
-
- return TRUE;
- }
-
- return FALSE;
-}
-
-static gint
-egg_secure_entry_button_release(GtkWidget *widget, GdkEventButton *event)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY(widget);
-
- if (event->window != entry->text_area || entry->button != event->button)
- return FALSE;
-
- entry->button = 0;
- return TRUE;
-}
-
-static gint
-egg_secure_entry_motion_notify(GtkWidget *widget, GdkEventMotion *event)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY(widget);
- gint tmp_pos;
-
- if (entry->mouse_cursor_obscured) {
- GdkCursor *cursor;
-
- cursor = gdk_cursor_new_for_display (gtk_widget_get_display(widget),
- GDK_XTERM);
- gdk_window_set_cursor (entry->text_area, cursor);
- gdk_cursor_unref (cursor);
- entry->mouse_cursor_obscured = FALSE;
- }
-
- if (event->window != entry->text_area || entry->button != 1)
- return FALSE;
-
- if (event->is_hint || (entry->text_area != event->window))
- gdk_window_get_pointer (entry->text_area, NULL, NULL, NULL);
-
- {
- gint height;
- gdk_drawable_get_size (entry->text_area, NULL, &height);
-
- if (event->y < 0)
- tmp_pos = 0;
- else if (event->y >= height)
- tmp_pos = entry->text_length;
- else
- tmp_pos = egg_secure_entry_find_position (entry,
- event->x + entry->scroll_offset);
-
- egg_secure_entry_set_positions (entry, tmp_pos, -1);
- }
-
- return TRUE;
-}
-
-static void
-set_invisible_cursor (GdkWindow * window)
-{
- GdkBitmap *empty_bitmap;
- GdkCursor *cursor;
- GdkColor useless;
- char invisible_cursor_bits[] = { 0x0 };
-
- useless.red = useless.green = useless.blue = 0;
- useless.pixel = 0;
-
- empty_bitmap = gdk_bitmap_create_from_data (window, invisible_cursor_bits, 1, 1);
-
- cursor = gdk_cursor_new_from_pixmap (empty_bitmap, empty_bitmap, &useless, &useless, 0, 0);
-
- gdk_window_set_cursor (window, cursor);
-
- gdk_cursor_unref (cursor);
-
- g_object_unref (empty_bitmap);
-}
-
-static void
-egg_secure_entry_obscure_mouse_cursor (EggSecureEntry * entry)
-{
- if (entry->mouse_cursor_obscured)
- return;
-
- set_invisible_cursor (entry->text_area);
-
- entry->mouse_cursor_obscured = TRUE;
-}
-
-static gint
-egg_secure_entry_key_press (GtkWidget *widget, GdkEventKey *event)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
-
- egg_secure_entry_pend_cursor_blink (entry);
-
- if (gtk_im_context_filter_keypress (entry->im_context, event)) {
- egg_secure_entry_obscure_mouse_cursor (entry);
- entry->need_im_reset = TRUE;
- return TRUE;
- }
-
- if (GTK_WIDGET_CLASS (parent_class)->key_press_event (widget, event))
- /* Activate key bindings */
- return TRUE;
-
- return FALSE;
-}
-
-static gint
-egg_secure_entry_key_release (GtkWidget *widget, GdkEventKey *event)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
-
- if (gtk_im_context_filter_keypress (entry->im_context, event)) {
- entry->need_im_reset = TRUE;
- return TRUE;
- }
-
- return GTK_WIDGET_CLASS (parent_class)->key_release_event (widget, event);
-}
-
-static gint
-egg_secure_entry_focus_in (GtkWidget *widget, GdkEventFocus *event)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
-
- gtk_widget_queue_draw (widget);
-
- entry->need_im_reset = TRUE;
- gtk_im_context_focus_in (entry->im_context);
-
- g_signal_connect (gdk_keymap_get_for_display (gtk_widget_get_display (widget)), "direction_changed",
- G_CALLBACK (egg_secure_entry_keymap_direction_changed), entry);
-
- egg_secure_entry_check_cursor_blink (entry);
-
- return FALSE;
-}
-
-static gint
-egg_secure_entry_focus_out (GtkWidget *widget, GdkEventFocus *event)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
-
- gtk_widget_queue_draw (widget);
-
- entry->need_im_reset = TRUE;
- gtk_im_context_focus_out (entry->im_context);
-
- egg_secure_entry_check_cursor_blink (entry);
-
- g_signal_handlers_disconnect_by_func (gdk_keymap_get_for_display (gtk_widget_get_display (widget)),
- egg_secure_entry_keymap_direction_changed, entry);
-
- return FALSE;
-}
-
-static void
-egg_secure_entry_grab_focus (GtkWidget *widget)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
- GtkSettings *settings = gtk_widget_get_settings (widget);
- gboolean select_on_focus = FALSE;
-
- GTK_WIDGET_SET_FLAGS (widget, GTK_CAN_DEFAULT);
- GTK_WIDGET_CLASS (parent_class)->grab_focus(widget);
-
- /* Some versions of GTK don't have this property */
- if (g_object_class_find_property (G_OBJECT_CLASS (GTK_SETTINGS_GET_CLASS (settings)),
- "gtk-entry-select-on-focus"))
- g_object_get (settings, "gtk-entry-select-on-focus", &select_on_focus, NULL);
-
- if (select_on_focus && !entry->in_click)
- gtk_editable_select_region (GTK_EDITABLE (widget), 0, -1);
-}
-
-static void
-egg_secure_entry_direction_changed(GtkWidget *widget, GtkTextDirection previous_dir)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
-
- egg_secure_entry_recompute (entry);
-
- GTK_WIDGET_CLASS (parent_class)->direction_changed (widget, previous_dir);
-}
-
-static void
-egg_secure_entry_state_changed (GtkWidget *widget, GtkStateType previous_state)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
-
- if (GTK_WIDGET_REALIZED (widget)) {
- gdk_window_set_background (widget->window,
- &widget->style->base[GTK_WIDGET_STATE(widget)]);
- gdk_window_set_background (entry->text_area,
- &widget->style->base[GTK_WIDGET_STATE(widget)]);
- }
-
- if (!GTK_WIDGET_IS_SENSITIVE (widget)) {
- /* Clear any selection */
- gtk_editable_select_region (GTK_EDITABLE(entry),
- entry->current_pos, entry->current_pos);
- }
-
- gtk_widget_queue_draw (widget);
-}
-
-static void
-egg_secure_entry_screen_changed (GtkWidget *widget, GdkScreen *old_screen)
-{
- egg_secure_entry_recompute (EGG_SECURE_ENTRY (widget));
-}
-
-/* GtkEditable method implementations */
-
-static void
-egg_secure_entry_insert_text (GtkEditable *editable, const gchar *new_text,
- gint new_text_length, gint * position)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY(editable);
- gchar *text;
-
- if (*position < 0 || *position > entry->text_length)
- *position = entry->text_length;
-
- g_object_ref (editable);
-
- text = egg_secure_alloc (new_text_length + 1);
-
- strncpy (text, new_text, new_text_length);
- text[new_text_length] = '\0';
-
- g_signal_emit_by_name (editable, "insert_text", text,
- new_text_length, position);
-
- egg_secure_free (text);
-
- g_object_unref (editable);
-}
-
-static void
-egg_secure_entry_delete_text (GtkEditable* editable, gint start_pos,
- gint end_pos)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (editable);
-
- if (end_pos < 0 || end_pos > entry->text_length)
- end_pos = entry->text_length;
- if (start_pos < 0)
- start_pos = 0;
- if (start_pos > end_pos)
- start_pos = end_pos;
-
- g_object_ref(editable);
-
- g_signal_emit_by_name (editable, "delete_text", start_pos, end_pos);
-
- g_object_unref (editable);
-}
-
-static void
-egg_secure_entry_set_position_internal (EggSecureEntry *entry,
- gint position, gboolean reset_im)
-{
- if (position < 0 || position > entry->text_length)
- position = entry->text_length;
-
- if (position != entry->current_pos || position != entry->selection_bound) {
- if (reset_im)
- egg_secure_entry_reset_im_context (entry);
- egg_secure_entry_set_positions (entry, position, position);
- }
-}
-
-static void
-egg_secure_entry_real_set_position (GtkEditable *editable, gint position)
-{
- egg_secure_entry_set_position_internal (EGG_SECURE_ENTRY (editable),
- position, TRUE);
-}
-
-static gint
-egg_secure_entry_get_position (GtkEditable *editable)
-{
- return EGG_SECURE_ENTRY (editable)->current_pos;
-}
-
-static void
-egg_secure_entry_set_selection_bounds (GtkEditable *editable,
- gint start, gint end)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (editable);
-
- if (start < 0)
- start = entry->text_length;
- if (end < 0)
- end = entry->text_length;
-
- egg_secure_entry_reset_im_context (entry);
-
- egg_secure_entry_set_positions (entry, MIN (end, entry->text_length),
- MIN (start, entry->text_length));
-}
-
-static gboolean
-egg_secure_entry_get_selection_bounds (GtkEditable *editable,
- gint *start, gint *end)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (editable);
-
- *start = entry->selection_bound;
- *end = entry->current_pos;
-
- return (entry->selection_bound != entry->current_pos);
-}
-
-static void
-egg_secure_entry_style_set (GtkWidget *widget, GtkStyle *previous_style)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (widget);
-
- egg_secure_entry_recompute (entry);
-
- if (previous_style && GTK_WIDGET_REALIZED (widget)) {
- gdk_window_set_background (widget->window,
- &widget->style->base[GTK_WIDGET_STATE (widget)]);
- gdk_window_set_background (entry->text_area,
- &widget->style-> base[GTK_WIDGET_STATE (widget)]);
- }
-}
-
-/* GtkCellEditable method implementations
- */
-static void
-gtk_cell_editable_secure_entry_activated (EggSecureEntry *entry, gpointer data)
-{
- gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
- gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
-}
-
-static gboolean
-gtk_cell_editable_key_press_event (EggSecureEntry *entry, GdkEventKey *key_event,
- gpointer data)
-{
- if (key_event->keyval == GDK_Escape) {
- entry->editing_canceled = TRUE;
- gtk_cell_editable_editing_done (GTK_CELL_EDITABLE (entry));
- gtk_cell_editable_remove_widget (GTK_CELL_EDITABLE (entry));
- return TRUE;
- }
-
- /* override focus */
- if (key_event->keyval == GDK_Up || key_event->keyval == GDK_Down) {
- gtk_cell_editable_editing_done(GTK_CELL_EDITABLE(entry));
- gtk_cell_editable_remove_widget(GTK_CELL_EDITABLE(entry));
- return TRUE;
- }
-
- return FALSE;
-}
-
-static void
-egg_secure_entry_start_editing (GtkCellEditable *cell_editable,
- GdkEvent *event)
-{
- EGG_SECURE_ENTRY(cell_editable)->is_cell_renderer = TRUE;
-
- g_signal_connect (cell_editable, "activate",
- G_CALLBACK (gtk_cell_editable_secure_entry_activated), NULL);
- g_signal_connect (cell_editable, "key_press_event",
- G_CALLBACK (gtk_cell_editable_key_press_event), NULL);
-}
-
-/* Default signal handlers */
-
-static void
-egg_secure_entry_real_insert_text (GtkEditable *editable, const gchar *new_text,
- gint new_text_length, gint *position)
-{
- gint _index;
- gint n_chars;
-
- EggSecureEntry *entry = EGG_SECURE_ENTRY (editable);
-
- if (new_text_length < 0)
- new_text_length = strlen (new_text);
-
- n_chars = g_utf8_strlen (new_text, new_text_length);
- if (entry->text_max_length > 0 && n_chars + entry->text_length > entry->text_max_length) {
- gdk_display_beep (gtk_widget_get_display (GTK_WIDGET (entry)));
- n_chars = entry->text_max_length - entry->text_length;
- new_text_length = g_utf8_offset_to_pointer (new_text, n_chars) - new_text;
- }
-
- if (new_text_length + entry->n_bytes + 1 > entry->text_size) {
- while (new_text_length + entry->n_bytes + 1 > entry->text_size) {
- if (entry->text_size == 0)
- entry->text_size = MIN_SIZE;
- else {
- if (2 * (guint) entry->text_size < MAX_SIZE &&
- 2 * (guint) entry->text_size > entry->text_size)
- entry->text_size *= 2;
- else {
- entry->text_size = MAX_SIZE;
- if (new_text_length > (gint) entry->text_size - (gint) entry->n_bytes - 1) {
- new_text_length = (gint) entry->text_size - (gint) entry->n_bytes - 1;
- new_text_length = g_utf8_find_prev_char (new_text, new_text + new_text_length + 1) - new_text;
- n_chars = g_utf8_strlen (new_text, new_text_length);
- }
- break;
- }
- }
- }
-
- entry->text = egg_secure_realloc (entry->text, entry->text_size + 1);
- }
-
- _index = g_utf8_offset_to_pointer (entry->text, *position) - entry->text;
-
- g_memmove (entry->text + _index + new_text_length, entry->text + _index,
- entry->n_bytes - _index);
- memcpy (entry->text + _index, new_text, new_text_length);
-
- entry->n_bytes += new_text_length;
- entry->text_length += n_chars;
-
- /* NUL terminate for safety and convenience */
- entry->text[entry->n_bytes] = '\0';
-
- if (entry->current_pos > *position)
- entry->current_pos += n_chars;
-
- if (entry->selection_bound > *position)
- entry->selection_bound += n_chars;
-
- *position += n_chars;
-
- egg_secure_entry_recompute (entry);
-
- entry->changed = TRUE;
- g_signal_emit_by_name (editable, "changed");
- g_object_notify (G_OBJECT (editable), "text");
-}
-
-static void
-egg_secure_entry_real_delete_text (GtkEditable *editable, gint start_pos,
- gint end_pos)
-{
- EggSecureEntry *entry = EGG_SECURE_ENTRY (editable);
-
- if (start_pos < 0)
- start_pos = 0;
- if (end_pos < 0 || end_pos > entry->text_length)
- end_pos = entry->text_length;
-
- if (start_pos < end_pos) {
- gint start_index = g_utf8_offset_to_pointer (entry->text, start_pos) - entry->text;
- gint end_index = g_utf8_offset_to_pointer(entry->text, end_pos) - entry->text;
- gint current_pos;
- gint selection_bound;
-
- g_memmove (entry->text + start_index, entry->text + end_index,
- entry->n_bytes + 1 - end_index);
- entry->text_length -= (end_pos - start_pos);
- entry->n_bytes -= (end_index - start_index);
-
- current_pos = entry->current_pos;
- if (current_pos > start_pos)
- current_pos -= MIN(current_pos, end_pos) - start_pos;
-
- selection_bound = entry->selection_bound;
- if (selection_bound > start_pos)
- selection_bound -= MIN(selection_bound, end_pos) - start_pos;
-
- egg_secure_entry_set_positions(entry, current_pos, selection_bound);
-
- egg_secure_entry_recompute (entry);
-
- entry->changed = TRUE;
- g_signal_emit_by_name (editable, "changed");
- g_object_notify (G_OBJECT (editable), "text");
- }
-}
-
-/*
- * Compute the X position for an offset that corresponds to the "more important
- * cursor position for that offset. We use this when trying to guess to which
- * end of the selection we should go to when the user hits the left or
- * right arrow key.
- */
-static gint
-get_better_cursor_x (EggSecureEntry *entry, gint offset)
-{
- GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET(entry)));
- PangoDirection keymap_direction = gdk_keymap_get_direction (keymap);
- gboolean split_cursor;
-
- PangoLayout *layout = egg_secure_entry_ensure_layout (entry, TRUE);
- const gchar *text = pango_layout_get_text(layout);
- gint _index = g_utf8_offset_to_pointer (text, offset) - text;
-
- PangoRectangle strong_pos, weak_pos;
-
- g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)),
- "gtk-split-cursor", &split_cursor, NULL);
-
- pango_layout_get_cursor_pos (layout, _index, &strong_pos, &weak_pos);
-
- if (split_cursor)
- return strong_pos.x / PANGO_SCALE;
- else
- return (keymap_direction == entry->resolved_dir) ?
- strong_pos.x / PANGO_SCALE :
- weak_pos.x / PANGO_SCALE;
-}
-
-static void
-egg_secure_entry_move_cursor (EggSecureEntry *entry, GtkMovementStep step,
- gint count, gboolean extend_selection)
-{
- gint new_pos = entry->current_pos;
-
- egg_secure_entry_reset_im_context (entry);
-
- if (entry->current_pos != entry->selection_bound && !extend_selection) {
- /*
- * If we have a current selection and aren't extending it, move to the
- * start/or end of the selection as appropriate
- */
- switch (step) {
- case GTK_MOVEMENT_VISUAL_POSITIONS:
- {
- gint current_x = get_better_cursor_x (entry, entry->current_pos);
- gint bound_x = get_better_cursor_x (entry, entry->selection_bound);
-
- if (count < 0)
- new_pos = current_x < bound_x ?
- entry->current_pos : entry->selection_bound;
- else
- new_pos = current_x > bound_x ?
- entry->current_pos : entry->selection_bound;
- break;
- }
- case GTK_MOVEMENT_LOGICAL_POSITIONS:
- case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
- case GTK_MOVEMENT_PARAGRAPH_ENDS:
- case GTK_MOVEMENT_BUFFER_ENDS:
- new_pos = count < 0 ? 0 : entry->text_length;
- break;
- case GTK_MOVEMENT_WORDS:
- case GTK_MOVEMENT_DISPLAY_LINES:
- case GTK_MOVEMENT_PARAGRAPHS:
- case GTK_MOVEMENT_PAGES:
- case GTK_MOVEMENT_HORIZONTAL_PAGES:
- break;
- }
- } else {
- switch (step) {
- case GTK_MOVEMENT_LOGICAL_POSITIONS:
- new_pos = egg_secure_entry_move_logically (entry, new_pos, count);
- break;
- case GTK_MOVEMENT_VISUAL_POSITIONS:
- new_pos = egg_secure_entry_move_visually (entry, new_pos, count);
- break;
- case GTK_MOVEMENT_DISPLAY_LINE_ENDS:
- case GTK_MOVEMENT_PARAGRAPH_ENDS:
- case GTK_MOVEMENT_BUFFER_ENDS:
- new_pos = count < 0 ? 0 : entry->text_length;
- break;
- case GTK_MOVEMENT_WORDS:
- case GTK_MOVEMENT_DISPLAY_LINES:
- case GTK_MOVEMENT_PARAGRAPHS:
- case GTK_MOVEMENT_PAGES:
- case GTK_MOVEMENT_HORIZONTAL_PAGES:
- break;
- }
- }
-
- if (extend_selection)
- gtk_editable_select_region (GTK_EDITABLE (entry), entry->selection_bound, new_pos);
- else
- gtk_editable_set_position (GTK_EDITABLE (entry), new_pos);
-
- egg_secure_entry_pend_cursor_blink (entry);
-}
-
-static void
-egg_secure_entry_insert_at_cursor(EggSecureEntry *entry, const gchar *str)
-{
- GtkEditable *editable = GTK_EDITABLE (entry);
- gint pos = entry->current_pos;
-
- egg_secure_entry_reset_im_context (entry);
-
- gtk_editable_insert_text (editable, str, -1, &pos);
- gtk_editable_set_position (editable, pos);
-}
-
-static void
-egg_secure_entry_delete_from_cursor (EggSecureEntry *entry, GtkDeleteType type,
- gint count)
-{
- GtkEditable *editable = GTK_EDITABLE (entry);
- gint start_pos = entry->current_pos;
- gint end_pos = entry->current_pos;
-
- egg_secure_entry_reset_im_context (entry);
-
- if (entry->selection_bound != entry->current_pos) {
- gtk_editable_delete_selection (editable);
- return;
- }
-
- switch (type) {
- case GTK_DELETE_CHARS:
- end_pos = egg_secure_entry_move_logically (entry, entry->current_pos, count);
- gtk_editable_delete_text (editable, MIN (start_pos, end_pos), MAX (start_pos, end_pos));
- break;
- case GTK_DELETE_DISPLAY_LINE_ENDS:
- case GTK_DELETE_PARAGRAPH_ENDS:
- if (count < 0)
- gtk_editable_delete_text (editable, 0, entry->current_pos);
- else
- gtk_editable_delete_text (editable, entry->current_pos, -1);
- break;
- case GTK_DELETE_DISPLAY_LINES:
- case GTK_DELETE_PARAGRAPHS:
- gtk_editable_delete_text (editable, 0, -1);
- break;
- default:
- break;
- }
-
- egg_secure_entry_pend_cursor_blink (entry);
-}
-
-static void
-egg_secure_entry_real_activate (EggSecureEntry *entry)
-{
- GtkWindow *window;
- GtkWidget *toplevel;
- GtkWidget *widget;
-
- widget = GTK_WIDGET (entry);
-
- if (entry->activates_default) {
- toplevel = gtk_widget_get_toplevel (widget);
- if (GTK_IS_WINDOW (toplevel)) {
- window = GTK_WINDOW(toplevel);
-
- if (window && widget != window->default_widget &&
- !(widget == window->focus_widget &&
- (!window->default_widget || !GTK_WIDGET_SENSITIVE(window->default_widget))))
- gtk_window_activate_default(window);
- }
- }
-}
-
-static void
-egg_secure_entry_keymap_direction_changed (GdkKeymap *keymap, EggSecureEntry *entry)
-{
- egg_secure_entry_recompute (entry);
-}
-
-/* IM Context Callbacks */
-
-static void
-egg_secure_entry_commit_cb (GtkIMContext *context, const gchar *str,
- EggSecureEntry *entry)
-{
- egg_secure_entry_enter_text (entry, str);
-}
-
-static void
-egg_secure_entry_preedit_changed_cb (GtkIMContext *context, EggSecureEntry *entry)
-{
- gchar *preedit_string;
- gint cursor_pos;
-
- gtk_im_context_get_preedit_string (entry->im_context, &preedit_string, NULL, &cursor_pos);
- entry->preedit_length = strlen (preedit_string);
- cursor_pos = CLAMP (cursor_pos, 0, g_utf8_strlen (preedit_string, -1));
- entry->preedit_cursor = cursor_pos;
- g_free (preedit_string);
-
- egg_secure_entry_recompute (entry);
-}
-
-static gboolean
-egg_secure_entry_retrieve_surrounding_cb (GtkIMContext *context, EggSecureEntry *entry)
-{
- gtk_im_context_set_surrounding (context, entry->text, entry->n_bytes,
- g_utf8_offset_to_pointer (entry->text, entry->current_pos) - entry->text);
- return TRUE;
-}
-
-static gboolean
-egg_secure_entry_delete_surrounding_cb (GtkIMContext *slave, gint offset, gint n_chars,
- EggSecureEntry *entry)
-{
- gtk_editable_delete_text (GTK_EDITABLE (entry), entry->current_pos + offset,
- entry->current_pos + offset + n_chars);
- return TRUE;
-}
-
-/* Internal functions */
-
-/* Used for im_commit_cb and inserting Unicode chars */
-static void
-egg_secure_entry_enter_text (EggSecureEntry *entry, const gchar *str)
-{
- GtkEditable *editable = GTK_EDITABLE (entry);
- gint tmp_pos;
-
- if (gtk_editable_get_selection_bounds (editable, NULL, NULL))
- gtk_editable_delete_selection (editable);
- else {
- if (entry->overwrite_mode)
- egg_secure_entry_delete_from_cursor (entry, GTK_DELETE_CHARS, 1);
- }
-
- tmp_pos = entry->current_pos;
- gtk_editable_insert_text (editable, str, strlen(str), &tmp_pos);
- egg_secure_entry_set_position_internal (entry, tmp_pos, FALSE);
-}
-
-/*
- * All changes to entry->current_pos and entry->selection_bound
- * should go through this function.
- */
-static void
-egg_secure_entry_set_positions (EggSecureEntry *entry, gint current_pos,
- gint selection_bound)
-{
- gboolean changed = FALSE;
-
- g_object_freeze_notify (G_OBJECT (entry));
-
- if (current_pos != -1 && entry->current_pos != current_pos) {
- entry->current_pos = current_pos;
- changed = TRUE;
-
- g_object_notify (G_OBJECT (entry), "cursor_position");
- }
-
- if (selection_bound != -1 && entry->selection_bound != selection_bound) {
- entry->selection_bound = selection_bound;
- changed = TRUE;
-
- g_object_notify (G_OBJECT (entry), "selection_bound");
- }
-
- g_object_thaw_notify (G_OBJECT (entry));
-
- if (changed)
- egg_secure_entry_recompute (entry);
-}
-
-static void
-egg_secure_entry_reset_layout (EggSecureEntry *entry)
-{
- if (entry->cached_layout) {
- g_object_unref (entry->cached_layout);
- entry->cached_layout = NULL;
- }
-}
-
-static void
-update_im_cursor_location (EggSecureEntry *entry)
-{
- GdkRectangle area;
- gint strong_x;
- gint strong_xoffset;
- gint area_width, area_height;
-
- egg_secure_entry_get_cursor_locations (entry, &strong_x, NULL);
- get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
-
- strong_xoffset = strong_x - entry->scroll_offset;
- if (strong_xoffset < 0) {
- strong_xoffset = 0;
- } else if (strong_xoffset > area_width) {
- strong_xoffset = area_width;
- }
- area.x = strong_xoffset;
- area.y = 0;
- area.width = 0;
- area.height = area_height;
-
- gtk_im_context_set_cursor_location (entry->im_context, &area);
-}
-
-static gboolean
-recompute_idle_func (gpointer data)
-{
- EggSecureEntry *entry;
-
- GDK_THREADS_ENTER ();
-
- entry = EGG_SECURE_ENTRY (data);
-
- entry->recompute_idle = 0;
-
- if (gtk_widget_has_screen (GTK_WIDGET (entry))) {
- egg_secure_entry_adjust_scroll (entry);
- egg_secure_entry_queue_draw (entry);
-
- update_im_cursor_location (entry);
- }
-
- GDK_THREADS_LEAVE ();
-
- return FALSE;
-}
-
-static void
-egg_secure_entry_recompute (EggSecureEntry *entry)
-{
- egg_secure_entry_reset_layout (entry);
- egg_secure_entry_check_cursor_blink (entry);
-
- if (!entry->recompute_idle) {
- entry->recompute_idle = g_idle_add_full (G_PRIORITY_HIGH_IDLE + 15, /* between resize and redraw */
- recompute_idle_func, entry, NULL);
- }
-}
-
-static gunichar
-build_string (EggSecureEntry *entry, GString *str, gint extra)
-{
- gint i, count, char_len;
- gunichar invisible_char;
- gchar buf[7];
-
- if (entry->visibility) {
- g_string_append_len (str, entry->text, entry->n_bytes);
- return 0;
-
- } else {
-
- if (entry->invisible_char != 0)
- invisible_char = entry->invisible_char;
- else
- invisible_char = ' '; /* just pick a char */
-
- count = g_utf8_strlen (entry->text, entry->n_bytes) + extra;
-
- char_len = g_unichar_to_utf8 (entry->invisible_char, buf);
- for (i = 0; i < count; i++)
- g_string_append_len(str, buf, char_len);
-
- return invisible_char;
- }
-}
-
-static PangoLayout *
-egg_secure_entry_create_layout (EggSecureEntry * entry, gboolean include_preedit)
-{
- GtkWidget *widget = GTK_WIDGET (entry);
- PangoLayout *layout = gtk_widget_create_pango_layout (widget, NULL);
- PangoAttrList *tmp_attrs = pango_attr_list_new ();
-
- gchar *preedit_string = NULL;
- gint preedit_length = 0;
- PangoAttrList *preedit_attrs = NULL;
-
- pango_layout_set_single_paragraph_mode (layout, TRUE);
-
- if (include_preedit) {
- gtk_im_context_get_preedit_string(entry->im_context, &preedit_string,
- &preedit_attrs, NULL);
- preedit_length = entry->preedit_length;
- }
-
- if (preedit_length) {
- GString *tmp_string = g_string_new(NULL);
-
- gint cursor_index = g_utf8_offset_to_pointer (entry->text, entry->current_pos) -
- entry->text;
-
- gint preedit_len_chars;
- gunichar invisible_char;
-
- preedit_len_chars = g_utf8_strlen (preedit_string, -1);
- invisible_char = build_string (entry, tmp_string, preedit_len_chars);
-
- /*
- * Fix cursor index to point to invisible char corresponding
- * to the preedit, fix preedit_length to be the length of
- * the invisible chars representing the preedit
- */
- cursor_index =
- g_utf8_offset_to_pointer (tmp_string->str, entry->current_pos) - tmp_string->str;
- preedit_length = preedit_len_chars * g_unichar_to_utf8 (invisible_char, NULL);
-
- pango_layout_set_text (layout, tmp_string->str, tmp_string->len);
-
- pango_attr_list_splice (tmp_attrs, preedit_attrs, cursor_index, preedit_length);
-
- g_string_free (tmp_string, TRUE);
- } else {
- PangoDirection pango_dir;
-
- pango_dir = pango_find_base_dir (entry->text, entry->n_bytes);
- if (pango_dir == PANGO_DIRECTION_NEUTRAL) {
- if (GTK_WIDGET_HAS_FOCUS (widget)) {
- GdkDisplay *display = gtk_widget_get_display (widget);
- GdkKeymap *keymap = gdk_keymap_get_for_display (display);
- pango_dir = gdk_keymap_get_direction (keymap);
- } else {
- if (gtk_widget_get_direction (widget) == GTK_TEXT_DIR_LTR)
- pango_dir = PANGO_DIRECTION_LTR;
- else
- pango_dir = PANGO_DIRECTION_RTL;
- }
- }
-
- pango_context_set_base_dir (gtk_widget_get_pango_context(widget), pango_dir);
-
- pango_layout_set_alignment (layout, pango_dir);
-
- entry->resolved_dir = pango_dir;
-
- {
- GString *str = g_string_new (NULL);
- build_string (entry, str, 0);
- pango_layout_set_text (layout, str->str, str->len);
- g_string_free (str, TRUE);
- }
- }
-
- pango_layout_set_attributes (layout, tmp_attrs);
-
- if (preedit_string)
- g_free (preedit_string);
- if (preedit_attrs)
- pango_attr_list_unref (preedit_attrs);
-
- pango_attr_list_unref (tmp_attrs);
-
- return layout;
-}
-
-static PangoLayout *
-egg_secure_entry_ensure_layout (EggSecureEntry *entry, gboolean include_preedit)
-{
- if (entry->preedit_length > 0 && !include_preedit != !entry->cache_includes_preedit)
- egg_secure_entry_reset_layout (entry);
-
- if (!entry->cached_layout) {
- entry->cached_layout = egg_secure_entry_create_layout (entry, include_preedit);
- entry->cache_includes_preedit = include_preedit;
- }
-
- return entry->cached_layout;
-}
-
-static void
-get_layout_position (EggSecureEntry *entry, gint *x, gint *y)
-{
- PangoLayout *layout;
- PangoRectangle logical_rect;
- gint area_width, area_height;
- gint y_pos;
- PangoLayoutLine *line;
-
- layout = egg_secure_entry_ensure_layout (entry, TRUE);
-
- get_text_area_size (entry, NULL, NULL, &area_width, &area_height);
-
- area_height = PANGO_SCALE * (area_height - 2 * INNER_BORDER);
-
- line = pango_layout_get_lines (layout)->data;
- pango_layout_line_get_extents (line, NULL, &logical_rect);
-
- /* Align primarily for locale's ascent/descent */
- y_pos = ((area_height - entry->ascent - entry->descent) / 2 +
- entry->ascent + logical_rect.y);
-
- /* Now see if we need to adjust to fit in actual drawn string */
- if (logical_rect.height > area_height)
- y_pos = (area_height - logical_rect.height) / 2;
- else if (y_pos < 0)
- y_pos = 0;
- else if (y_pos + logical_rect.height > area_height)
- y_pos = area_height - logical_rect.height;
-
- y_pos = INNER_BORDER + y_pos / PANGO_SCALE;
-
- if (x)
- *x = INNER_BORDER - entry->scroll_offset;
-
- if (y)
- *y = y_pos;
-}
-
-static void
-egg_secure_entry_draw_text(EggSecureEntry *entry)
-{
- GtkWidget *widget;
- PangoLayoutLine *line;
-
- if (entry->invisible_char == 0)
- return;
-
- if (GTK_WIDGET_DRAWABLE (entry)) {
- PangoLayout *layout = egg_secure_entry_ensure_layout (entry, TRUE);
- gint x, y;
- gint start_pos, end_pos;
-
- widget = GTK_WIDGET(entry);
-
- get_layout_position(entry, &x, &y);
-
- gdk_draw_layout(entry->text_area, widget->style->text_gc[widget->state], x, y, layout);
-
- if (gtk_editable_get_selection_bounds (GTK_EDITABLE (entry), &start_pos, &end_pos)) {
- gint *ranges;
- gint n_ranges, i;
- PangoRectangle logical_rect;
- const gchar *text = pango_layout_get_text (layout);
- gint start_index = g_utf8_offset_to_pointer (text, start_pos) - text;
- gint end_index = g_utf8_offset_to_pointer (text, end_pos) - text;
- GdkRegion *clip_region = gdk_region_new ();
- GdkGC *text_gc;
- GdkGC *selection_gc;
-
- line = pango_layout_get_lines(layout)->data;
-
- pango_layout_line_get_x_ranges (line, start_index, end_index, &ranges, &n_ranges);
- pango_layout_get_extents(layout, NULL, &logical_rect);
-
- if (GTK_WIDGET_HAS_FOCUS(entry)) {
- selection_gc = widget->style->base_gc[GTK_STATE_SELECTED];
- text_gc = widget->style->text_gc[GTK_STATE_SELECTED];
- } else {
- selection_gc = widget->style->base_gc[GTK_STATE_ACTIVE];
- text_gc = widget->style->text_gc[GTK_STATE_ACTIVE];
- }
-
- for (i = 0; i < n_ranges; i++) {
- GdkRectangle rect;
-
- rect.x = INNER_BORDER - entry->scroll_offset +
- ranges[2 * i] / PANGO_SCALE;
- rect.y = y;
- rect.width = (ranges[2 * i + 1] - ranges[2 * i]) / PANGO_SCALE;
- rect.height = logical_rect.height / PANGO_SCALE;
-
- gdk_draw_rectangle (entry->text_area, selection_gc, TRUE, rect.x,
- rect.y, rect.width, rect.height);
-
- gdk_region_union_with_rect(clip_region, &rect);
- }
-
- gdk_gc_set_clip_region(text_gc, clip_region);
- gdk_draw_layout(entry->text_area, text_gc, x, y, layout);
- gdk_gc_set_clip_region(text_gc, NULL);
-
- gdk_region_destroy(clip_region);
- g_free(ranges);
- }
- }
-}
-
-static void
-draw_insertion_cursor (EggSecureEntry *entry, GdkRectangle *cursor_location,
- gboolean is_primary, PangoDirection direction, gboolean draw_arrow)
-{
- GtkWidget *widget = GTK_WIDGET (entry);
- GtkTextDirection text_dir;
-
- if (direction == PANGO_DIRECTION_LTR)
- text_dir = GTK_TEXT_DIR_LTR;
- else
- text_dir = GTK_TEXT_DIR_RTL;
-
- gtk_draw_insertion_cursor (widget, entry->text_area, NULL, cursor_location,
- is_primary, text_dir, draw_arrow);
-}
-
-static void
-egg_secure_entry_draw_cursor (EggSecureEntry * entry)
-{
- GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET(entry)));
- PangoDirection keymap_direction = gdk_keymap_get_direction (keymap);
-
- if (GTK_WIDGET_DRAWABLE (entry)) {
- GtkWidget *widget = GTK_WIDGET(entry);
- GdkRectangle cursor_location;
- gboolean split_cursor;
-
- gint xoffset = INNER_BORDER - entry->scroll_offset;
- gint strong_x, weak_x;
- gint text_area_height;
- PangoDirection dir1 = PANGO_DIRECTION_NEUTRAL;
- PangoDirection dir2 = PANGO_DIRECTION_NEUTRAL;
- gint x1 = 0;
- gint x2 = 0;
-
- gdk_drawable_get_size (entry->text_area, NULL, &text_area_height);
-
- egg_secure_entry_get_cursor_locations (entry, &strong_x, &weak_x);
-
- g_object_get (gtk_widget_get_settings (widget), "gtk-split-cursor", &split_cursor, NULL);
-
- dir1 = entry->resolved_dir;
-
- if (split_cursor) {
- x1 = strong_x;
-
- if (weak_x != strong_x) {
- dir2 = (entry->resolved_dir == PANGO_DIRECTION_LTR) ?
- PANGO_DIRECTION_RTL : PANGO_DIRECTION_LTR;
- x2 = weak_x;
- }
- } else {
- if (keymap_direction == entry->resolved_dir)
- x1 = strong_x;
- else
- x1 = weak_x;
- }
-
- cursor_location.x = xoffset + x1;
- cursor_location.y = INNER_BORDER;
- cursor_location.width = 0;
- cursor_location.height = text_area_height - 2 * INNER_BORDER;
-
- draw_insertion_cursor (entry, &cursor_location, TRUE, dir1,
- dir2 != PANGO_DIRECTION_NEUTRAL);
-
- if (dir2 != PANGO_DIRECTION_NEUTRAL) {
- cursor_location.x = xoffset + x2;
- draw_insertion_cursor(entry, &cursor_location, FALSE, dir2, TRUE);
- }
- }
-}
-
-static void
-egg_secure_entry_queue_draw (EggSecureEntry *entry)
-{
- if (GTK_WIDGET_REALIZED (entry))
- gdk_window_invalidate_rect (entry->text_area, NULL, FALSE);
-}
-
-static void
-egg_secure_entry_reset_im_context (EggSecureEntry *entry)
-{
- if (entry->need_im_reset) {
- entry->need_im_reset = 0;
- gtk_im_context_reset (entry->im_context);
- }
-}
-
-static gint
-egg_secure_entry_find_position (EggSecureEntry *entry, gint x)
-{
- PangoLayout *layout;
- PangoLayoutLine *line;
- gint _index;
- gint pos;
- gboolean trailing;
- const gchar *text;
- gint cursor_index;
-
- layout = egg_secure_entry_ensure_layout (entry, TRUE);
- text = pango_layout_get_text (layout);
- cursor_index = g_utf8_offset_to_pointer (text, entry->current_pos) - text;
-
- line = pango_layout_get_lines (layout)->data;
- pango_layout_line_x_to_index (line, x * PANGO_SCALE, &_index, &trailing);
-
- if (_index >= cursor_index && entry->preedit_length) {
- if (_index >= cursor_index + entry->preedit_length)
- _index -= entry->preedit_length;
- else {
- _index = cursor_index;
- trailing = 0;
- }
- }
-
- pos = g_utf8_pointer_to_offset (text, text + _index);
- pos += trailing;
-
- return pos;
-}
-
-static void
-egg_secure_entry_get_cursor_locations (EggSecureEntry *entry,
- gint *strong_x, gint *weak_x)
-{
- if (!entry->invisible_char) {
- if (strong_x)
- *strong_x = 0;
- if (weak_x)
- *weak_x = 0;
- } else {
- PangoLayout *layout = egg_secure_entry_ensure_layout (entry, TRUE);
- const gchar *text = pango_layout_get_text (layout);
- PangoRectangle strong_pos, weak_pos;
- gint _index;
-
- _index = g_utf8_offset_to_pointer (text, entry->current_pos +
- entry->preedit_cursor) - text;
-
- pango_layout_get_cursor_pos (layout, _index, &strong_pos, &weak_pos);
-
- if (strong_x)
- *strong_x = strong_pos.x / PANGO_SCALE;
-
- if (weak_x)
- *weak_x = weak_pos.x / PANGO_SCALE;
- }
-}
-
-static void
-egg_secure_entry_adjust_scroll (EggSecureEntry *entry)
-{
- gint min_offset, max_offset;
- gint text_area_width, text_width;
- gint strong_x, weak_x;
- gint strong_xoffset, weak_xoffset;
- PangoLayout *layout;
- PangoLayoutLine *line;
- PangoRectangle logical_rect;
-
- if (!GTK_WIDGET_REALIZED(entry))
- return;
-
- gdk_drawable_get_size (entry->text_area, &text_area_width, NULL);
- text_area_width -= 2 * INNER_BORDER;
-
- layout = egg_secure_entry_ensure_layout (entry, TRUE);
- line = pango_layout_get_lines (layout)->data;
-
- pango_layout_line_get_extents (line, NULL, &logical_rect);
-
- /* Display as much text as we can */
-
- text_width = PANGO_PIXELS (logical_rect.width);
-
- if (text_width > text_area_width) {
- min_offset = 0;
- max_offset = text_width - text_area_width;
- } else {
- min_offset = 0;
- max_offset = min_offset;
- }
-
- entry->scroll_offset = CLAMP (entry->scroll_offset, min_offset, max_offset);
-
- /*
- * And make sure cursors are on screen. Note that the cursor is
- * actually drawn one pixel into the INNER_BORDER space on
- * the right, when the scroll is at the utmost right. This
- * looks better to to me than confining the cursor inside the
- * border entirely, though it means that the cursor gets one
- * pixel closer to the the edge of the widget on the right than
- * on the left. This might need changing if one changed
- * INNER_BORDER from 2 to 1, as one would do on a
- * small-screen-real-estate display.
- *
- * We always make sure that the strong cursor is on screen, and
- * put the weak cursor on screen if possible.
- */
-
- egg_secure_entry_get_cursor_locations (entry, &strong_x, &weak_x);
-
- strong_xoffset = strong_x - entry->scroll_offset;
-
- if (strong_xoffset < 0) {
- entry->scroll_offset += strong_xoffset;
- strong_xoffset = 0;
- } else if (strong_xoffset > text_area_width) {
- entry->scroll_offset += strong_xoffset - text_area_width;
- strong_xoffset = text_area_width;
- }
-
- weak_xoffset = weak_x - entry->scroll_offset;
-
- if (weak_xoffset < 0 && strong_xoffset - weak_xoffset <= text_area_width) {
- entry->scroll_offset += weak_xoffset;
- } else if (weak_xoffset > text_area_width &&
- strong_xoffset - (weak_xoffset - text_area_width) >= 0) {
- entry->scroll_offset += weak_xoffset - text_area_width;
- }
-
- g_object_notify (G_OBJECT (entry), "scroll_offset");
-}
-
-static gint
-egg_secure_entry_move_visually (EggSecureEntry * entry,
- gint start, gint count)
-{
- gint _index;
- PangoLayout *layout = egg_secure_entry_ensure_layout (entry, FALSE);
- const gchar *text;
-
- text = pango_layout_get_text (layout);
-
- _index = g_utf8_offset_to_pointer (text, start) - text;
-
- while (count != 0) {
- int new_index, new_trailing;
- gboolean split_cursor;
- gboolean strong;
-
- g_object_get (gtk_widget_get_settings (GTK_WIDGET (entry)),
- "gtk-split-cursor", &split_cursor, NULL);
-
- if (split_cursor)
- strong = TRUE;
- else {
- GdkKeymap *keymap = gdk_keymap_get_for_display (gtk_widget_get_display (GTK_WIDGET (entry)));
- PangoDirection keymap_direction = gdk_keymap_get_direction (keymap);
-
- strong = keymap_direction == entry->resolved_dir;
- }
-
- if (count > 0) {
- pango_layout_move_cursor_visually (layout, strong, _index, 0, 1,
- &new_index, &new_trailing);
- count--;
- } else {
- pango_layout_move_cursor_visually (layout, strong, _index, 0, -1,
- &new_index, &new_trailing);
- count++;
- }
-
- if (new_index < 0 || new_index == G_MAXINT)
- break;
-
- _index = new_index;
-
- while (new_trailing--)
- _index = g_utf8_next_char (text + new_index) - text;
- }
-
- return g_utf8_pointer_to_offset (text, text + _index);
-}
-
-static gint
-egg_secure_entry_move_logically (EggSecureEntry *entry,
- gint start, gint count)
-{
- gint new_pos = start;
-
- /* Prevent any leak of information */
- new_pos = CLAMP (start + count, 0, entry->text_length);
- return new_pos;
-}
-
-/* Public API */
-
-GtkWidget *
-egg_secure_entry_new (void)
-{
- return g_object_new (EGG_TYPE_SECURE_ENTRY, NULL);
-}
-
-void
-egg_secure_entry_set_text (EggSecureEntry *entry, const gchar *text)
-{
- gint tmp_pos;
-
- g_return_if_fail (EGG_IS_SECURE_ENTRY(entry));
- g_return_if_fail (text != NULL);
-
- /*
- * Actually setting the text will affect the cursor and selection;
- * if the contents don't actually change, this will look odd to the user.
- */
- if (strcmp (entry->text, text) == 0)
- return;
-
- gtk_editable_delete_text (GTK_EDITABLE (entry), 0, -1);
-
- tmp_pos = 0;
- gtk_editable_insert_text (GTK_EDITABLE (entry), text, strlen (text), &tmp_pos);
-}
-
-void
-egg_secure_entry_reset_changed (EggSecureEntry *entry)
-{
- g_return_if_fail (EGG_IS_SECURE_ENTRY (entry));
- entry->changed = FALSE;
-}
-
-gboolean
-egg_secure_entry_get_changed (EggSecureEntry *entry)
-{
- g_return_val_if_fail (EGG_IS_SECURE_ENTRY (entry), FALSE);
- return entry->changed;
-}
-
-void
-egg_secure_entry_set_visibility (EggSecureEntry *entry, gboolean setting)
-{
- g_return_if_fail (EGG_IS_SECURE_ENTRY (entry));
-
- if (setting == entry->visibility)
- return;
-
- if (GTK_WIDGET_HAS_FOCUS (entry) && !setting)
- gtk_im_context_focus_out (entry->im_context);
- g_object_unref (entry->im_context);
-
- if (setting)
- entry->im_context = gtk_im_multicontext_new ();
- else
- entry->im_context = gtk_im_context_simple_new ();
-
- g_signal_connect (entry->im_context, "commit",
- G_CALLBACK (egg_secure_entry_commit_cb), entry);
- g_signal_connect (entry->im_context, "preedit_changed",
- G_CALLBACK(egg_secure_entry_preedit_changed_cb), entry);
- g_signal_connect (entry->im_context, "retrieve_surrounding",
- G_CALLBACK(egg_secure_entry_retrieve_surrounding_cb), entry);
- g_signal_connect (entry->im_context, "delete_surrounding",
- G_CALLBACK(egg_secure_entry_delete_surrounding_cb), entry);
-
- if (GTK_WIDGET_HAS_FOCUS (entry) && setting)
- gtk_im_context_focus_in (entry->im_context);
-
- entry->visibility = setting;
- g_object_notify (G_OBJECT (entry), "visibility");
- egg_secure_entry_recompute (entry);
-}
-
-gboolean
-egg_secure_entry_get_visibility (EggSecureEntry *entry)
-{
- g_return_val_if_fail (EGG_IS_SECURE_ENTRY (entry), FALSE);
- return entry->visibility;
-}
-
-
-/**
- * egg_secure_entry_set_invisible_char:
- * @entry: a #EggSecureEntry
- * @ch: a Unicode character
- *
- * Sets the character to use in place of the actual text when
- * egg_secure_entry_set_visibility() has been called to set text
- * to %FALSE. i.e. this is the character used in "password mode" to
- * show the user how many characters have been typed. The default
- * invisible char is an asterisk ('*'). If you set the invisible char
- * to 0, then the user will get no feedback at all; there will be
- * no text on the screen as they type.
- *
- **/
-void
-egg_secure_entry_set_invisible_char (EggSecureEntry *entry, gunichar ch)
-{
- g_return_if_fail (EGG_IS_SECURE_ENTRY (entry));
-
- if (ch == entry->invisible_char)
- return;
-
- entry->invisible_char = ch;
- g_object_notify (G_OBJECT (entry), "invisible_char");
- egg_secure_entry_recompute (entry);
-}
-
-/**
- * egg_secure_entry_get_invisible_char:
- * @entry: a #EggSecureEntry
- *
- * Retrieves the character displayed in place of the real characters
- * for entries with visisbility set to false. See egg_secure_entry_set_invisible_char().
- *
- * Return value: the current invisible char, or 0, if the entry does not
- * show invisible text at all.
- **/
-gunichar
-egg_secure_entry_get_invisible_char (EggSecureEntry * entry)
-{
- g_return_val_if_fail (EGG_IS_SECURE_ENTRY (entry), 0);
-
- return entry->invisible_char;
-}
-
-/**
- * egg_secure_entry_get_text:
- * @entry: a #EggSecureEntry
- *
- * Retrieves the contents of the entry widget.
- * See also gtk_editable_get_chars().
- *
- * Return value: a pointer to the contents of the widget as a
- * string. This string points to internally allocated
- * storage in the widget and must not be freed, modified or
- * stored.
- **/
-G_CONST_RETURN gchar*
-egg_secure_entry_get_text (EggSecureEntry *entry)
-{
- g_return_val_if_fail (EGG_IS_SECURE_ENTRY (entry), NULL);
-
- return entry->text;
-}
-
-/**
- * egg_secure_entry_set_max_length:
- * @entry: a #EggSecureEntry.
- * @max: the maximum length of the entry, or 0 for no maximum.
- * (other than the maximum length of entries.) The value passed in will
- * be clamped to the range 0-65536.
- *
- * Sets the maximum allowed length of the contents of the widget. If
- * the current contents are longer than the given length, then they
- * will be truncated to fit.
- **/
-void
-egg_secure_entry_set_max_length(EggSecureEntry *entry, gint max)
-{
- g_return_if_fail (EGG_IS_SECURE_ENTRY (entry));
-
- max = CLAMP (max, 0, MAX_SIZE);
-
- if (max > 0 && entry->text_length > max)
- gtk_editable_delete_text (GTK_EDITABLE (entry), max, -1);
-
- entry->text_max_length = max;
- g_object_notify (G_OBJECT (entry), "max_length");
-}
-
-/**
- * egg_secure_entry_get_max_length:
- * @entry: a #EggSecureEntry
- *
- * Retrieves the maximum allowed length of the text in
- * @entry. See egg_secure_entry_set_max_length().
- *
- * Return value: the maximum allowed number of characters
- * in #EggSecureEntry, or 0 if there is no maximum.
- **/
-gint
-egg_secure_entry_get_max_length (EggSecureEntry *entry)
-{
- g_return_val_if_fail (EGG_IS_SECURE_ENTRY (entry), 0);
- return entry->text_max_length;
-}
-
-/**
- * egg_secure_entry_set_activates_default:
- * @entry: a #EggSecureEntry
- * @setting: %TRUE to activate window's default widget on Enter keypress
- *
- * If @setting is %TRUE, pressing Enter in the @entry will activate the default
- * widget for the window containing the entry. This usually means that
- * the dialog box containing the entry will be closed, since the default
- * widget is usually one of the dialog buttons.
- *
- * (For experts: if @setting is %TRUE, the entry calls
- * gtk_window_activate_default() on the window containing the entry, in
- * the default handler for the "activate" signal.)
- *
- **/
-void
-egg_secure_entry_set_activates_default (EggSecureEntry *entry,
- gboolean setting)
-{
- g_return_if_fail (EGG_IS_SECURE_ENTRY (entry));
- setting = setting != FALSE;
-
- if (setting != entry->activates_default) {
- entry->activates_default = setting;
- g_object_notify (G_OBJECT (entry), "activates_default");
- }
-}
-
-/**
- * egg_secure_entry_get_activates_default:
- * @entry: a #EggSecureEntry
- *
- * Retrieves the value set by egg_secure_entry_set_activates_default().
- *
- * Return value: %TRUE if the entry will activate the default widget
- **/
-gboolean
-egg_secure_entry_get_activates_default (EggSecureEntry *entry)
-{
- g_return_val_if_fail (EGG_IS_SECURE_ENTRY (entry), FALSE);
- return entry->activates_default;
-}
-
-/**
- * egg_secure_entry_set_width_chars:
- * @entry: a #EggSecureEntry
- * @n_chars: width in chars
- *
- * Changes the size request of the entry to be about the right size
- * for @n_chars characters. Note that it changes the size
- * <emphasis>request</emphasis>, the size can still be affected by
- * how you pack the widget into containers. If @n_chars is -1, the
- * size reverts to the default entry size.
- *
- **/
-void
-egg_secure_entry_set_width_chars (EggSecureEntry *entry, gint n_chars)
-{
- g_return_if_fail (EGG_IS_SECURE_ENTRY (entry));
-
- if (entry->width_chars != n_chars) {
- entry->width_chars = n_chars;
- g_object_notify (G_OBJECT (entry), "width_chars");
- gtk_widget_queue_resize (GTK_WIDGET (entry));
- }
-}
-
-/**
- * egg_secure_entry_get_width_chars:
- * @entry: a #EggSecureEntry
- *
- * Gets the value set by egg_secure_entry_set_width_chars().
- *
- * Return value: number of chars to request space for, or negative if unset
- **/
-gint
-egg_secure_entry_get_width_chars (EggSecureEntry *entry)
-{
- g_return_val_if_fail (EGG_IS_SECURE_ENTRY (entry), 0);
- return entry->width_chars;
-}
-
-/**
- * egg_secure_entry_set_has_frame:
- * @entry: a #EggSecureEntry
- * @setting: new value
- *
- * Sets whether the entry has a beveled frame around it.
- **/
-void
-egg_secure_entry_set_has_frame (EggSecureEntry *entry, gboolean setting)
-{
- g_return_if_fail (EGG_IS_SECURE_ENTRY (entry));
-
- setting = (setting != FALSE);
-
- if (entry->has_frame == setting)
- return;
-
- gtk_widget_queue_resize (GTK_WIDGET (entry));
- entry->has_frame = setting;
- g_object_notify (G_OBJECT (entry), "has_frame");
-}
-
-/**
- * egg_secure_entry_get_has_frame:
- * @entry: a #EggSecureEntry
- *
- * Gets the value set by egg_secure_entry_set_has_frame().
- *
- * Return value: whether the entry has a beveled frame
- **/
-gboolean
-egg_secure_entry_get_has_frame (EggSecureEntry *entry)
-{
- g_return_val_if_fail (EGG_IS_SECURE_ENTRY (entry), FALSE);
- return entry->has_frame;
-}
-
-static gboolean
-egg_secure_entry_mnemonic_activate (GtkWidget *widget, gboolean group_cycling)
-{
- gtk_widget_grab_focus (widget);
- return TRUE;
-}
-
-/* We display the cursor when
- *
- * - the selection is empty, AND
- * - the widget has focus
- */
-
-#define CURSOR_ON_MULTIPLIER 0.66
-#define CURSOR_OFF_MULTIPLIER 0.34
-#define CURSOR_PEND_MULTIPLIER 1.0
-
-static gboolean
-cursor_blinks (EggSecureEntry *entry)
-{
- GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry));
- gboolean blink;
-
- if (GTK_WIDGET_HAS_FOCUS (entry) &&
- entry->selection_bound == entry->current_pos) {
- g_object_get (settings, "gtk-cursor-blink", &blink, NULL);
- return blink;
- } else
- return FALSE;
-}
-
-static gint
-get_cursor_time (EggSecureEntry *entry)
-{
- GtkSettings *settings = gtk_widget_get_settings (GTK_WIDGET (entry));
- gint time;
-
- g_object_get (settings, "gtk-cursor-blink-time", &time, NULL);
-
- return time;
-}
-
-static void
-show_cursor (EggSecureEntry *entry)
-{
- if (!entry->cursor_visible) {
- entry->cursor_visible = TRUE;
-
- if (GTK_WIDGET_HAS_FOCUS (entry) &&
- entry->selection_bound == entry->current_pos)
- gtk_widget_queue_draw (GTK_WIDGET (entry));
- }
-}
-
-static void
-hide_cursor(EggSecureEntry * entry)
-{
- if (entry->cursor_visible) {
- entry->cursor_visible = FALSE;
-
- if (GTK_WIDGET_HAS_FOCUS (entry) &&
- entry->selection_bound == entry->current_pos)
- gtk_widget_queue_draw (GTK_WIDGET (entry));
- }
-}
-
-/*
- * Blink!
- */
-static gint
-blink_cb (gpointer data)
-{
- EggSecureEntry *entry;
-
- GDK_THREADS_ENTER ();
-
- entry = EGG_SECURE_ENTRY (data);
-
- if (!GTK_WIDGET_HAS_FOCUS (entry)) {
- g_warning ("EggSecureEntry - did not receive focus-out-event. If you\n"
- "connect a handler to this signal, it must return\n"
- "FALSE so the entry gets the event as well");
- }
-
- g_assert (GTK_WIDGET_HAS_FOCUS (entry));
- g_assert (entry->selection_bound == entry->current_pos);
-
- if (entry->cursor_visible) {
- hide_cursor(entry);
- entry->blink_timeout = g_timeout_add (get_cursor_time (entry) * CURSOR_OFF_MULTIPLIER,
- blink_cb, entry);
- } else {
- show_cursor(entry);
- entry->blink_timeout = g_timeout_add (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER,
- blink_cb, entry);
- }
-
- GDK_THREADS_LEAVE ();
-
- /* Remove ourselves */
- return FALSE;
-}
-
-static void
-egg_secure_entry_check_cursor_blink (EggSecureEntry *entry)
-{
- if (cursor_blinks (entry)) {
- if (!entry->blink_timeout) {
- entry->blink_timeout = g_timeout_add (get_cursor_time (entry) * CURSOR_ON_MULTIPLIER,
- blink_cb, entry);
- show_cursor (entry);
- }
- } else {
- if (entry->blink_timeout) {
- g_source_remove (entry->blink_timeout);
- entry->blink_timeout = 0;
- }
-
- entry->cursor_visible = TRUE;
- }
-
-}
-
-static void
-egg_secure_entry_pend_cursor_blink (EggSecureEntry *entry)
-{
- if (cursor_blinks (entry)) {
- if (entry->blink_timeout != 0)
- g_source_remove(entry->blink_timeout);
-
- entry->blink_timeout = g_timeout_add (get_cursor_time (entry) * CURSOR_PEND_MULTIPLIER,
- blink_cb, entry);
- show_cursor (entry);
- }
-}
-
-static inline gboolean
-keyval_is_cursor_move (guint keyval)
-{
- if (keyval == GDK_Up || keyval == GDK_KP_Up)
- return TRUE;
-
- if (keyval == GDK_Down || keyval == GDK_KP_Down)
- return TRUE;
-
- if (keyval == GDK_Page_Up)
- return TRUE;
-
- if (keyval == GDK_Page_Down)
- return TRUE;
-
- return FALSE;
-}
-
-/* stolen from gtkmarshalers.c */
-
-#define g_marshal_value_peek_enum(v) (v)->data[0].v_int
-#define g_marshal_value_peek_int(v) (v)->data[0].v_int
-#define g_marshal_value_peek_boolean(v) (v)->data[0].v_int
-
-/* VOID:ENUM,INT,BOOLEAN (gtkmarshalers.list:64) */
-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)
-{
- typedef void (*GMarshalFunc_VOID__ENUM_INT_BOOLEAN) (gpointer data1,
- gint arg_1,
- gint arg_2,
- gboolean arg_3,
- gpointer data2);
- register GMarshalFunc_VOID__ENUM_INT_BOOLEAN callback;
- register GCClosure *cc = (GCClosure *) closure;
- register gpointer data1, data2;
-
- g_return_if_fail(n_param_values == 4);
-
- if (G_CCLOSURE_SWAP_DATA(closure)) {
- data1 = closure->data;
- data2 = g_value_peek_pointer(param_values + 0);
- } else {
- data1 = g_value_peek_pointer(param_values + 0);
- data2 = closure->data;
- }
- callback =
- (GMarshalFunc_VOID__ENUM_INT_BOOLEAN) (marshal_data ? marshal_data
- : cc->callback);
-
- callback(data1,
- g_marshal_value_peek_enum(param_values + 1),
- g_marshal_value_peek_int(param_values + 2),
- g_marshal_value_peek_boolean(param_values + 3), data2);
-}
-
-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)
-{
- typedef void (*GMarshalFunc_VOID__ENUM_INT) (gpointer data1,
- gint arg_1,
- gint arg_2,
- gpointer data2);
- register GMarshalFunc_VOID__ENUM_INT callback;
- register GCClosure *cc = (GCClosure *) closure;
- register gpointer data1, data2;
-
- g_return_if_fail(n_param_values == 3);
-
- if (G_CCLOSURE_SWAP_DATA(closure)) {
- data1 = closure->data;
- data2 = g_value_peek_pointer(param_values + 0);
- } else {
- data1 = g_value_peek_pointer(param_values + 0);
- data2 = closure->data;
- }
- callback =
- (GMarshalFunc_VOID__ENUM_INT) (marshal_data ? marshal_data : cc->
- callback);
-
- callback(data1,
- g_marshal_value_peek_enum(param_values + 1),
- g_marshal_value_peek_int(param_values + 2), data2);
-}
diff --git a/egg/egg-secure-entry.h b/egg/egg-secure-entry.h
deleted file mode 100644
index 35bf8d4..0000000
--- a/egg/egg-secure-entry.h
+++ /dev/null
@@ -1,187 +0,0 @@
-/*
- * 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 now always invisible, 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 gnome-keyring by Stef Walter
- */
-
-#ifndef __EGG_SECURE_ENTRY_H__
-#define __EGG_SECURE_ENTRY_H__
-
-
-#include <gtk/gtk.h>
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-#define EGG_TYPE_SECURE_ENTRY (egg_secure_entry_get_type ())
-#define EGG_SECURE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_CAST ((obj), EGG_TYPE_SECURE_ENTRY, EggSecureEntry))
-#define EGG_SECURE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_CAST ((klass), EGG_TYPE_SECURE_ENTRY, EggSecureEntryClass))
-#define EGG_IS_SECURE_ENTRY(obj) (G_TYPE_CHECK_INSTANCE_TYPE ((obj), EGG_TYPE_SECURE_ENTRY))
-#define EGG_IS_SECURE_ENTRY_CLASS(klass) (G_TYPE_CHECK_CLASS_TYPE ((klass), EGG_TYPE_SECURE_ENTRY))
-#define EGG_SECURE_ENTRY_GET_CLASS(obj) (G_TYPE_INSTANCE_GET_CLASS ((obj), EGG_TYPE_SECURE_ENTRY, EggSecureEntryClass))
-
-typedef struct _EggSecureEntry EggSecureEntry;
-typedef struct _EggSecureEntryClass EggSecureEntryClass;
-
-struct _EggSecureEntry {
- GtkWidget widget;
-
- gchar *text;
-
- guint overwrite_mode : 1;
-
- /* length in use, in chars */
- guint16 text_length;
- guint16 text_max_length;
-
- /*< private > */
- GdkWindow *text_area;
- GtkIMContext *im_context;
-
- gint current_pos;
- gint selection_bound;
-
- PangoLayout *cached_layout;
- guint cache_includes_preedit : 1;
-
- guint need_im_reset : 1;
-
- guint has_frame : 1;
-
- guint activates_default : 1;
-
- guint cursor_visible : 1;
-
- /* Flag so we don't select all when clicking in entry to focus in */
- guint in_click : 1;
-
- /* Only used by GtkCellRendererText */
- guint is_cell_renderer : 1;
- guint editing_canceled : 1;
-
- guint mouse_cursor_obscured : 1;
-
- /* PangoDirection */
- guint resolved_dir : 4;
-
- guint button;
- guint blink_timeout;
- guint recompute_idle;
- gint scroll_offset;
- gint ascent; /* font ascent, in pango units */
- gint descent; /* font descent, in pango units */
-
- guint16 text_size; /* allocated size, in bytes */
- guint16 n_bytes; /* length in use, in bytes */
-
- guint16 preedit_length; /* length of preedit string, in bytes */
- guint16 preedit_cursor; /* offset of cursor within preedit string, in chars */
-
- gunichar invisible_char;
- gint width_chars;
-
- gboolean visibility;
-
- /* Keeps track of whether changed between resets */
- gboolean changed;
-};
-
-struct _EggSecureEntryClass {
- GtkWidgetClass parent_class;
-
- /* Action signals */
- void (*activate) (EggSecureEntry *entry);
- void (*move_cursor) (EggSecureEntry *entry, GtkMovementStep step,
- gint count, gboolean extend_selection);
- void (*insert_at_cursor) (EggSecureEntry *entry, const gchar *str);
- void (*delete_from_cursor) (EggSecureEntry *entry, GtkDeleteType type, gint count);
-
- /* Padding for future expansion */
- void (*_gtk_reserved1) (void);
- void (*_gtk_reserved2) (void);
- void (*_gtk_reserved3) (void);
- void (*_gtk_reserved4) (void);
-};
-
-GType egg_secure_entry_get_type (void) G_GNUC_CONST;
-
-GtkWidget* egg_secure_entry_new (void);
-
-void egg_secure_entry_reset_changed (EggSecureEntry *entry);
-
-gboolean egg_secure_entry_get_changed (EggSecureEntry *entry);
-
-void egg_secure_entry_set_visibility (EggSecureEntry *entry, gboolean setting);
-
-gboolean egg_secure_entry_get_visibility (EggSecureEntry *entry);
-
-void egg_secure_entry_set_invisible_char (EggSecureEntry *entry, gunichar ch);
-
-gunichar egg_secure_entry_get_invisible_char (EggSecureEntry *entry);
-
-void egg_secure_entry_set_has_frame (EggSecureEntry *entry, gboolean setting);
-
-gboolean egg_secure_entry_get_has_frame (EggSecureEntry *entry);
-
-/* text is truncated if needed */
-void egg_secure_entry_set_max_length (EggSecureEntry *entry, gint max);
-
-gint egg_secure_entry_get_max_length (EggSecureEntry *entry);
-
-void egg_secure_entry_set_activates_default (EggSecureEntry *entry, gboolean setting);
-
-gboolean egg_secure_entry_get_activates_default (EggSecureEntry *entry);
-
-void egg_secure_entry_set_width_chars (EggSecureEntry *entry, gint n_chars);
-
-gint egg_secure_entry_get_width_chars (EggSecureEntry *entry);
-
-/* Somewhat more convenient than the GtkEditable generic functions */
-void egg_secure_entry_set_text (EggSecureEntry *entry, const gchar *text);
-
-/* returns a reference to the text */
-const gchar* egg_secure_entry_get_text (EggSecureEntry *entry);
-
-#ifdef __cplusplus
-}
-#endif
-
-#endif /*__EGG_SECURE_ENTRY_H__ */