[Kazehakase-cvs] CVS update: kazehakase/module/embed/gecko

Back to archive index

Hiroyuki Ikezoe ikezo****@users*****
Tue Mar 20 13:04:11 JST 2007


Index: kazehakase/module/embed/gecko/kz-gecko-embed.cpp
diff -u /dev/null kazehakase/module/embed/gecko/kz-gecko-embed.cpp:1.1
--- /dev/null	Tue Mar 20 13:04:11 2007
+++ kazehakase/module/embed/gecko/kz-gecko-embed.cpp	Tue Mar 20 13:04:11 2007
@@ -0,0 +1,3206 @@
+/* -*- Mode: C++; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
+
+/*
+ *  Copyright (C) 2007 Hiroyuki Ikezoe
+ *
+ *  This program is free software; you can redistribute it and/or modify
+ *  it under the terms of the GNU General Public License as published by
+ *  the Free Software Foundation; either version 2, or (at your option)
+ *  any later version.
+ *
+ *  This program is distributed in the hope that it will be useful,
+ *  but WITHOUT ANY WARRANTY; without even the implied warranty of
+ *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ *  GNU General Public License for more details.
+ *
+ *  You should have received a copy of the GNU General Public License
+ *  along with this program; if not, write to the Free Software
+ *  Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
+ */
+
+#include "kz-embed.h"
+#include "kz-gecko-embed.h"
+
+#include "kz-gecko-single.h"
+
+#define KZ_REGRESSION_BUG4474 1
+
+#include <string.h>
+#include <math.h>
+#include <gtkmozembed.h>
+#include <gtkmozembed_internal.h>
+#include <glib/gi18n.h>
+#include <glib/gstdio.h>
+#include <sys/stat.h>
+
+#include "kazehakase.h"
+#include "kz-window.h"
+#include "kz-mozwrapper.h"
+#include "kz-mozprogresslistener.h"
+#include "kz-mozthumbnailcreator.h"
+#include "kz-mozutils.h"
+#include "mozilla.h"
+#include "mozilla-prefs.h"
+#include "bookmarks/kz-bookmark.h"
+#if USE_MIGEMO
+#include "kz-migemo.h"
+#endif
+#include "utils.h"
+
+#include "kz-search.h"
+
+#include <nsCOMPtr.h>
+#include <nsIDOMDocument.h>
+#include <nsIDocumentViewer.h>
+#include <nsIWebBrowser.h>
+#include <nsIDOMMouseEvent.h>
+#include <dom/nsIDOMKeyEvent.h>
+#include <dom/nsIDOMNSHTMLElement.h>  
+#include <nsIDOMHTMLElement.h>  
+#include <nsIDOMHTMLDocument.h>  
+#include <nsIDOMHTMLTextAreaElement.h>  
+#include <nsIDOMNamedNodeMap.h>
+#include <nsIDOMDocumentRange.h>
+#include <nsIDOMDocumentFragment.h>
+#include <nsIDOMSerializer.h>
+#include <nsIDOMText.h>
+#include <webbrowserpersist/nsIWebBrowserPersist.h>
+#include <nsIWebBrowserFind.h>
+#include <nsIFind.h>
+#include <dom/nsIDOMNSDocument.h>
+#include <dom/nsIDOMNSEvent.h>
+#include <nsIDOMNodeList.h>
+#include <nsIDOMWindow.h>
+#include <nsISelection.h>
+#include <nsIDOMRange.h>
+#include <nsIDOMWindow.h>
+#include <nsISelection.h>
+#include <nsISHistory.h>
+#include <nsIHistoryEntry.h>
+#include <nsISHEntry.h>
+#include <nsISHistoryInternal.h>
+#include <nsIWebNavigation.h>
+#include <nsCWebBrowserPersist.h>
+#include <widget/nsIBaseWindow.h>
+#include <nsIWebPageDescriptor.h>
+#include <nsICommandManager.h>
+#include <nsTime.h>
+#include <nsRect.h>
+#define MOZILLA_STRICT_API
+#include <nsEmbedString.h>
+#undef MOZILLA_STRICT_API
+#include <nsIServiceManager.h>
+#include <nsIInterfaceRequestorUtils.h>
+#include <nsMemory.h>
+#include <nsILocalFile.h>
+#include <nsIDOM3Node.h>
+
+typedef struct _KzGeckoEmbedPrivate	KzGeckoEmbedPrivate;
+struct _KzGeckoEmbedPrivate
+{
+	KzMozWrapper *wrapper;
+	gint size_inited;
+	gint cur_requests;
+	gint total_requests;
+	
+	/* location and title */
+	gchar *location;
+	gchar *title;
+
+	gint load_started; /* count of currently active connections */
+	gint load_percent;
+	gint bytes_loaded;
+	gint max_bytes_loaded;
+	gboolean  is_loading;
+	const gchar *load_status_message;
+
+	gboolean lock;
+
+	/* for navigation link */
+	GList *nav_links[KZ_EMBED_LINK_GUARD];
+
+#ifdef USE_MIGEMO
+	gchar *migemo_keyword;
+#endif
+	gchar *last_highlight;
+	gchar *first_url;
+};
+
+typedef struct _KzGeckoEmbedClass	KzGeckoEmbedClass;
+struct _KzGeckoEmbedClass
+{
+	GtkMozEmbedClass parent_class;
+};
+
+#define KZ_GECKO_EMBED_GET_PRIVATE(obj) (G_TYPE_INSTANCE_GET_PRIVATE ((obj), KZ_TYPE_GECKO_EMBED, KzGeckoEmbedPrivate))
+
+#define KZ_GECKO_EMBED_CLASS(klass)	  (G_TYPE_CHECK_CLASS_CAST ((klass), KZ_TYPE_GECKO_EMBED, KzGeckoEmbedClass))
+#define KZ_IS_GECKO_EMBED_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), KZ_TYPE_GECKO_EMBED))
+#define KZ_GECKO_EMBED_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), KZ_TYPE_GECKO_EMBED, KzGeckoEmbedClass))
+
+/* for module */
+void       kz_embed_module_init		(GTypeModule *module);
+void       kz_embed_module_exit		(void);
+GtkWidget *kz_embed_module_create	(const gchar *url);
+
+/* for interface */
+static void kz_gecko_embed_iface_init   (KzEmbedIFace *iface);
+
+static void  kz_gecko_embed_navigation_link_free(KzGeckoEmbed *kzembed);
+static glong kz_gecko_embed_get_key_event_info  (KzGeckoEmbed *kzembed,
+						 gpointer      event,
+						 KzEmbedEventKey **info_ret);
+static glong kz_gecko_embed_get_mouse_event_info(KzGeckoEmbed *kzembed,
+						 gpointer      event,
+						 KzEmbedEventMouse **info_ret);
+static glong kz_gecko_embed_set_event_context   (KzGeckoEmbed *kzembed,
+						 nsIDOMEventTarget *target,
+						 KzEmbedEvent *info);
+static gchar *kz_gecko_embed_store_history_file (KzGeckoEmbed *kzembed);
+
+static void         kz_gecko_embed_load_url              (KzEmbed      *kzembed,
+							  const gchar  *url);
+static void         kz_gecko_embed_view_source           (KzEmbed      *kzembed,
+							  const gchar  *url);
+
+static gboolean     kz_gecko_embed_is_loading            (KzEmbed      *kzembed);
+
+static const gchar *kz_gecko_embed_get_title             (KzEmbed      *kzembed);
+static const gchar *kz_gecko_embed_get_location          (KzEmbed      *kzembed);
+static gchar       *kz_gecko_embed_ensure_title          (KzEmbed      *kzembed);
+static gchar       *kz_gecko_embed_get_link_message      (KzEmbed      *kzembed);
+
+static gdouble      kz_gecko_embed_get_progress          (KzEmbed      *kzembed);
+
+static gboolean     kz_gecko_embed_can_cut_selection     (KzEmbed      *kzembed);
+static gboolean     kz_gecko_embed_can_copy_selection    (KzEmbed      *kzembed);
+static gboolean     kz_gecko_embed_can_paste             (KzEmbed      *kzembed);
+static void         kz_gecko_embed_cut_selection         (KzEmbed      *kzembed);
+static void         kz_gecko_embed_copy_selection        (KzEmbed      *kzembed);
+static void         kz_gecko_embed_paste                 (KzEmbed      *kzembed);
+static void         kz_gecko_embed_select_all            (KzEmbed      *kzembed);
+
+static gchar       *kz_gecko_embed_get_selection_string  (KzEmbed      *kzembed);
+
+static gboolean     kz_gecko_embed_find                  (KzEmbed      *kzembed,
+							  const char   *keyword,
+							  gboolean      backward);
+static gboolean     kz_gecko_embed_incremental_search    (KzEmbed      *kzembed,
+							  const char   *keyword,
+							  gboolean      backward);
+
+static gboolean     kz_gecko_embed_selection_is_collapsed(KzEmbed      *kzembed);
+
+static gboolean     kz_gecko_embed_get_links             (KzEmbed      *kzembed,
+							  GList       **list,
+							  gboolean      selected_only);
+
+static gboolean     kz_gecko_embed_get_dest_anchors      (KzEmbed      *kzembed,
+							  GList       **list);
+
+static void         kz_gecko_embed_copy_page             (KzEmbed      *kzembed,
+							  KzEmbed      *dkzembed,
+							  KzEmbedCopyType type);
+static gboolean     kz_gecko_embed_shistory_copy         (KzEmbed      *source,
+							  KzEmbed      *dest,
+							  gboolean      back_history,
+							  gboolean      forward_history,
+							  gboolean      set_current);
+static gboolean     kz_gecko_embed_shistory_get_pos      (KzEmbed      *kzembed,
+							  int          *pos,
+							  int          *count);
+static void         kz_gecko_embed_shistory_get_nth      (KzEmbed      *kzembed, 
+							  int           nth,
+							  gboolean      is_relative,
+							  char        **aUrl,
+							  char        **aTitle);
+
+static void         kz_gecko_embed_reload                (KzEmbed      *kzembed,
+							  KzEmbedReloadFlag flags);
+static void         kz_gecko_embed_stop_load             (KzEmbed      *kzembed);
+static void         kz_gecko_embed_go_back               (KzEmbed      *kzembed);
+static void         kz_gecko_embed_go_forward            (KzEmbed      *kzembed);
+
+static gboolean     kz_gecko_embed_can_go_back           (KzEmbed      *kzembed);
+static gboolean     kz_gecko_embed_can_go_forward        (KzEmbed      *kzembed);
+static gboolean     kz_gecko_embed_can_go_nav_link       (KzEmbed      *kzembed,
+							  KzEmbedNavLink link);
+static void         kz_gecko_embed_go_nav_link           (KzEmbed      *kzembed,
+							  KzEmbedNavLink link);
+static void         kz_gecko_embed_append_nav_link       (KzEmbed      *kzembed,
+							  KzEmbedNavLink link,
+							  KzNavi       *navi);
+static void         kz_gecko_embed_set_nth_nav_link      (KzEmbed      *kzembed,
+							  KzEmbedNavLink link,
+							  KzNavi       *navi,
+							  guint         n);
+static KzNavi      *kz_gecko_embed_get_nth_nav_link      (KzEmbed      *kzembed,
+							  KzEmbedNavLink link,
+							  guint         n);
+static GList       *kz_gecko_embed_get_nav_links         (KzEmbed      *kzembed,
+							  KzEmbedNavLink link);
+static void         kz_gecko_embed_go_history_index      (KzEmbed      *kzembed,
+							  gint          index);
+
+static void         kz_gecko_embed_do_command            (KzEmbed      *kzembed,
+							  const char   *command);
+static gboolean     kz_gecko_embed_can_do_command        (KzEmbed      *kzembed,
+							  const char   *command);
+
+static gboolean     kz_gecko_embed_get_lock              (KzEmbed      *kzembed);
+static void         kz_gecko_embed_set_lock              (KzEmbed      *kzembed,
+							  gboolean      lock);
+
+static gchar       *kz_gecko_embed_get_body_text         (KzEmbed      *kzembed);
+#if 0
+static gchar       *kz_gecko_embed_get_selection_source  (KzEmbed      *kzembed);
+#endif
+static void         kz_gecko_embed_set_encoding          (KzEmbed      *kzembed,
+							  const char   *encoding);
+static void         kz_gecko_embed_get_encoding          (KzEmbed      *kzembed,
+							  char        **encoding,
+							  gboolean     *forced);
+static void         kz_gecko_embed_print                 (KzEmbed      *kzembed);
+static void         kz_gecko_embed_print_preview         (KzEmbed      *kzembed);
+static GList       *kz_gecko_embed_get_printer_list      (KzEmbed      *kzembed);
+static void         kz_gecko_embed_create_thumbnail      (KzEmbed      *kzembed);
+
+
+static gboolean     kz_gecko_embed_save_with_content     (KzEmbed      *kzembed,
+							  const char   *rawfilename);
+
+static gboolean     kz_gecko_embed_set_text_into_textarea(KzEmbed      *kzembed,
+							  gpointer      element,
+							  const gchar  *text);
+static gchar       *kz_gecko_embed_get_text_from_textarea(KzEmbed      *kzembed,
+							  gpointer      element);
+
+
+static void         kz_gecko_embed_zoom_set              (KzEmbed      *kzembed, 
+							  int           zoom, 
+							  gboolean      reflow);
+static int          kz_gecko_embed_zoom_get              (KzEmbed      *kzembed);
+static void         kz_gecko_embed_set_text_size         (KzEmbed      *kzembed, 
+							  int           zoom, 
+							  gboolean      reflow);
+static int          kz_gecko_embed_get_text_size         (KzEmbed      *kzembed);
+
+static gchar       *kz_gecko_embed_get_html_with_contents(KzEmbed      *kzembed,
+							  const gchar  *storedir);
+
+static void	     kz_gecko_embed_set_history           (KzEmbed      *kzembed,
+							   KzBookmark   *history);
+static void	     kz_gecko_embed_get_history           (KzEmbed      *kzembed,
+							   KzBookmark   *history);
+static guint	     kz_gecko_embed_get_last_modified     (KzEmbed      *kzembed);
+
+
+#if 0
+static void         kz_gecko_embed_set_edit_mode         (KzEmbed      *kzembed);
+static void         kz_gecko_embed_set_view_mode         (KzEmbed      *kzembed);
+#endif
+static void         kz_gecko_embed_fine_scroll            (KzEmbed      *kzembed,
+							   int           horiz, 
+							   int           vert);
+static void	     kz_gecko_embed_page_up		  (KzEmbed      *kzembed);
+static void	     kz_gecko_embed_page_down		  (KzEmbed      *kzembed);
+
+static gboolean	     kz_gecko_embed_get_allow_javascript  (KzEmbed      *kzembed);
+static void	     kz_gecko_embed_set_allow_javascript  (KzEmbed      *kzembed,
+    							   gboolean      allow);
+static gboolean	     kz_gecko_embed_get_allow_images	  (KzEmbed      *kzembed);
+static void	     kz_gecko_embed_set_allow_images	  (KzEmbed      *kzembed,
+							   gboolean      allow);
+static void          kz_gecko_embed_show_page_certificate (KzEmbed       *kzembed);
+
+/* KzGeckoEmbed Class */
+static void   kz_gecko_embed_class_init (KzGeckoEmbedClass *klass);
+static void   kz_gecko_embed_init       (KzGeckoEmbed *embed);
+
+static GtkMozEmbedClass *kz_gecko_embed_parent_class;
+static GType kz_gecko_embed_type = 0;
+
+static void
+kz_gecko_embed_register_type (GTypeModule *module)
+{
+	static const GTypeInfo kz_gecko_embed_info =
+	{
+		sizeof (KzGeckoEmbedClass),
+		NULL,		/* base_init */
+		NULL,		/* base_finalize */
+		(GClassInitFunc) kz_gecko_embed_class_init,
+		NULL,		/* class_finalize */
+		NULL,		/* class_data */
+		sizeof (KzGeckoEmbed),
+		0,		/* n_preallocs */
+		(GInstanceInitFunc) kz_gecko_embed_init,
+	};
+
+	const GInterfaceInfo kz_embed_info =
+	{
+		(GInterfaceInitFunc) kz_gecko_embed_iface_init,
+		NULL,
+		NULL
+	};	
+
+	kz_gecko_embed_type = g_type_module_register_type(module,
+			GTK_TYPE_MOZ_EMBED,
+			"KzGeckoEmbed",
+			&kz_gecko_embed_info, (GTypeFlags)0);
+
+	g_type_module_add_interface(module,
+				    KZ_TYPE_GECKO_EMBED,
+				    KZ_TYPE_EMBED,
+				    &kz_embed_info);
+}
+
+G_MODULE_EXPORT void 
+kz_embed_module_init (GTypeModule *module)
+{
+	kz_gecko_embed_register_type(module);
+}
+
+G_MODULE_EXPORT void 
+kz_embed_module_exit (void)
+{
+}
+
+G_MODULE_EXPORT GtkWidget * 
+kz_embed_module_create (const gchar *url)
+{
+	return kz_gecko_embed_new(url);
+}
+
+GType
+kz_gecko_embed_get_type (void)
+{
+	return kz_gecko_embed_type;
+}
+
+static void
+kz_gecko_embed_iface_init (KzEmbedIFace *iface)
+{
+	iface->load_url               = kz_gecko_embed_load_url;
+	iface->view_source            = kz_gecko_embed_view_source;
+	iface->is_loading             = kz_gecko_embed_is_loading;
+	iface->get_title              = kz_gecko_embed_get_title;
+	iface->get_location           = kz_gecko_embed_get_location;
+	iface->ensure_title           = kz_gecko_embed_ensure_title;
+	iface->get_link_message       = kz_gecko_embed_get_link_message;
+	iface->get_progress           = kz_gecko_embed_get_progress;
+	iface->can_cut_selection      = kz_gecko_embed_can_cut_selection;
+	iface->can_copy_selection     = kz_gecko_embed_can_copy_selection;
+	iface->can_paste              = kz_gecko_embed_can_paste;
+	iface->cut_selection          = kz_gecko_embed_cut_selection;
+	iface->copy_selection         = kz_gecko_embed_copy_selection;
+	iface->paste                  = kz_gecko_embed_paste;
+	iface->select_all             = kz_gecko_embed_select_all;
+	iface->get_selection_string   = kz_gecko_embed_get_selection_string;
+	iface->find                   = kz_gecko_embed_find;
+	iface->incremental_search     = kz_gecko_embed_incremental_search;
+	iface->selection_is_collapsed = kz_gecko_embed_selection_is_collapsed;
+	iface->get_links              = kz_gecko_embed_get_links;
+	iface->get_dest_anchors       = kz_gecko_embed_get_dest_anchors;
+	iface->copy_page              = kz_gecko_embed_copy_page;
+	iface->shistory_copy          = kz_gecko_embed_shistory_copy;
+	iface->shistory_get_pos       = kz_gecko_embed_shistory_get_pos;
+	iface->shistory_get_nth       = kz_gecko_embed_shistory_get_nth;
+	iface->reload                 = kz_gecko_embed_reload;
+	iface->stop_load              = kz_gecko_embed_stop_load;
+	iface->go_back                = kz_gecko_embed_go_back;
+	iface->go_forward             = kz_gecko_embed_go_forward;
+	iface->can_go_back            = kz_gecko_embed_can_go_back;
+	iface->can_go_forward         = kz_gecko_embed_can_go_forward;
+	iface->can_go_nav_link        = kz_gecko_embed_can_go_nav_link;
+	iface->go_nav_link            = kz_gecko_embed_go_nav_link;
+	iface->append_nav_link        = kz_gecko_embed_append_nav_link;
+	iface->set_nav_link           = NULL;
+	iface->set_nth_nav_link       = kz_gecko_embed_set_nth_nav_link;
+	iface->get_nav_link           = NULL;
+	iface->get_nth_nav_link       = kz_gecko_embed_get_nth_nav_link;
+	iface->get_nav_links          = kz_gecko_embed_get_nav_links;
+	iface->go_history_index       = kz_gecko_embed_go_history_index;
+	iface->do_command             = kz_gecko_embed_do_command;
+	iface->can_do_command         = kz_gecko_embed_can_do_command;
+	iface->get_lock               = kz_gecko_embed_get_lock;
+	iface->set_lock               = kz_gecko_embed_set_lock;
+	iface->get_body_text          = kz_gecko_embed_get_body_text;
+#if 0
+	iface->get_selection_source   = kz_gecko_embed_get_selection_source;
+#endif
+	iface->set_encoding           = kz_gecko_embed_set_encoding;
+	iface->get_encoding           = kz_gecko_embed_get_encoding;
+	iface->print                  = kz_gecko_embed_print;
+	iface->print_preview          = kz_gecko_embed_print_preview;
+	iface->get_printer_list       = kz_gecko_embed_get_printer_list;
+	iface->create_thumbnail       = kz_gecko_embed_create_thumbnail;
+	iface->save_with_content      = kz_gecko_embed_save_with_content;
+	iface->set_text_into_textarea = kz_gecko_embed_set_text_into_textarea;
+	iface->get_text_from_textarea = kz_gecko_embed_get_text_from_textarea;
+	iface->zoom_set               = kz_gecko_embed_zoom_set;
+	iface->zoom_get               = kz_gecko_embed_zoom_get;
+	iface->set_text_size          = kz_gecko_embed_set_text_size;
+	iface->get_text_size          = kz_gecko_embed_get_text_size;
+	iface->get_html_with_contents = kz_gecko_embed_get_html_with_contents;
+	iface->set_history            = kz_gecko_embed_set_history;
+	iface->get_history            = kz_gecko_embed_get_history;
+	iface->get_last_modified      = kz_gecko_embed_get_last_modified;
+	iface->fine_scroll            = kz_gecko_embed_fine_scroll;
+	iface->page_up                = kz_gecko_embed_page_up;
+	iface->page_down              = kz_gecko_embed_page_down;
+	iface->get_allow_javascript   = kz_gecko_embed_get_allow_javascript;
+	iface->set_allow_javascript   = kz_gecko_embed_set_allow_javascript;
+	iface->get_allow_images       = kz_gecko_embed_get_allow_images;
+	iface->set_allow_images       = kz_gecko_embed_set_allow_images;
+	iface->show_page_certificate  = kz_gecko_embed_show_page_certificate;
+
+
+#if 0
+	iface->set_edit_mode          = set_edit_mode;
+	iface->set_view_mode          = set_view_mode;
+#endif
+	iface->link_message        = NULL;
+	iface->js_status           = NULL;
+	iface->location            = NULL;
+	iface->title               = NULL;
+	iface->progress            = NULL;
+	iface->net_start           = NULL;
+	iface->net_stop            = NULL;
+	iface->new_window          = NULL;
+	iface->open_uri            = NULL;
+	iface->size_to             = NULL;
+	iface->dom_key_down        = NULL;
+	iface->dom_key_press       = NULL;
+	iface->dom_key_up          = NULL;
+	iface->dom_mouse_down      = NULL;
+	iface->dom_mouse_up        = NULL;
+	iface->dom_mouse_click     = NULL;
+	iface->dom_mouse_dbl_click = NULL;
+	iface->dom_mouse_over      = NULL;
+	iface->dom_mouse_out       = NULL;
+	iface->security_change     = NULL;
+	iface->status_change       = NULL;
+}
+
+static void
+kz_gecko_embed_class_init (KzGeckoEmbedClass *klass)
+{
+	GObjectClass *object_class;
+
+	kz_gecko_embed_parent_class = (GtkMozEmbedClass *)g_type_class_peek_parent (klass);
+	object_class = (GObjectClass *) klass;
+
+	g_type_class_add_private (object_class, sizeof(KzGeckoEmbedPrivate));
+}
+
+static void
+kz_gecko_embed_init (KzGeckoEmbed *kzembed)
+{
+	gint i;
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	priv->location              = NULL;
+	priv->title                 = NULL;
+	priv->load_started          = 0;
+	priv->load_percent          = 0;
+	priv->bytes_loaded          = 0;
+	priv->max_bytes_loaded      = 0;
+	priv->is_loading            = FALSE;
+	priv->load_status_message   = NULL;
+	priv->wrapper               = NULL;
+	priv->size_inited           = FALSE;
+	priv->total_requests        = 0;
+	priv->cur_requests          = 0;
+	
+	for (i = 0; i < KZ_EMBED_LINK_GUARD; i++)
+	{
+		priv->nav_links[i] = NULL;
+	}
+#ifdef USE_MIGEMO
+	priv->migemo_keyword = NULL;
+#endif
+	priv->last_highlight = NULL;
+	priv->first_url      = NULL;
+
+#ifndef KZ_REGRESSION_BUG4474
+#ifndef HAVE_GECKO_1_8
+	kz_moz_embed_load_url(KZ_EMBED(kzembed), "about:blank");
+#endif
+#endif
+}
+
+static void
+kz_gecko_embed_load_url (KzEmbed *kzembed, const gchar *url)
+{
+	gchar *start_page = NULL;
+
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (url && *url)
+	{
+		start_page = g_strdup(url);
+	}
+	else
+	{
+		start_page = g_strdup("about:blank");
+	}
+
+	if (!priv->first_url &&
+	    kz_gecko_embed_get_lock(kzembed))
+	{
+		GtkMozEmbed *newembed = NULL;
+		g_signal_emit_by_name(kzembed, 
+				      "new-window",
+				      &newembed, 0);
+		gtk_moz_embed_load_url(newembed, start_page);
+		return;
+	}
+	else
+	{
+		gtk_moz_embed_load_url(GTK_MOZ_EMBED(kzembed), start_page);
+	}
+	if (priv->location)
+		g_free(priv->location);
+	priv->location = start_page;
+}
+
+
+static void
+kz_gecko_embed_view_source (KzEmbed *kzembed, const gchar *url)
+{
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	KzMozWrapper *wrapper = priv->wrapper;
+	nsresult rv;
+
+        nsCOMPtr<nsISupports> pageDescriptor;
+        rv = wrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
+        if (!pageDescriptor || NS_FAILED(rv)) return;
+
+        rv = wrapper->LoadDocument(pageDescriptor, 
+				   nsIWebPageDescriptor::DISPLAY_AS_SOURCE);
+	if (NS_FAILED(rv)) return;
+
+	// set history explicitly
+	nsCOMPtr<nsISHistory> sHistory;
+	rv = wrapper->GetSHistory(getter_AddRefs(sHistory));
+	if (NS_FAILED(rv) || !sHistory) return;
+
+	nsCOMPtr<nsISHistoryInternal> sHistoryInternal;
+	sHistoryInternal = do_QueryInterface(sHistory);
+
+	gchar *uri = g_strdup_printf("view-source:%s", url);
+
+	nsCOMPtr<nsISHEntry> entry;
+	entry = do_CreateInstance(NS_SHENTRY_CONTRACTID);
+
+	nsCOMPtr<nsIURI> aURI;
+	NewURI(getter_AddRefs(aURI), uri);
+	/* FIXME! set correct contentType */
+	nsEmbedCString contentType;
+	entry->SetURI(aURI);
+	sHistoryInternal->AddEntry(entry, PR_TRUE);
+	g_free(uri);
+}
+
+
+static gboolean
+kz_gecko_embed_is_loading (KzEmbed *kzembed)
+{
+	return KZ_IS_GECKO_EMBED(kzembed)
+		? KZ_GECKO_EMBED_GET_PRIVATE(kzembed)->is_loading
+		: FALSE;
+}
+
+
+static const gchar *
+kz_gecko_embed_get_title (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+	return KZ_GECKO_EMBED_GET_PRIVATE(kzembed)->title;
+}
+
+static gchar *
+kz_gecko_embed_ensure_title (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (priv->title && *priv->title)
+		return g_strdup(priv->title);
+
+	if (priv->location && *priv->location)
+	{
+		if (kz_gecko_embed_is_loading(kzembed))
+		{
+			return g_strdup_printf(_("Loading %s ..."),
+					       priv->location);
+		}
+		else
+		{
+			return g_strdup(priv->location);
+		}
+	}
+	else
+	{
+		if (kz_gecko_embed_is_loading(kzembed))
+			return g_strdup(_("Loading..."));
+	}
+
+	return g_strdup(_("No title"));
+}
+
+static gchar * 
+kz_gecko_embed_get_link_message (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_GECKO_EMBED(kzembed), NULL);
+
+	gchar *message;
+
+	message = gtk_moz_embed_get_link_message(GTK_MOZ_EMBED(kzembed));
+
+	return message;
+}
+
+
+static gdouble
+kz_gecko_embed_get_progress (KzEmbed *kzembed)
+{
+	gdouble progress;
+
+	g_return_val_if_fail(KZ_GECKO_EMBED(kzembed), 0.0);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (priv->total_requests <= 0 ||
+	    priv->cur_requests <= 0)
+	{
+		return 0.0;
+	}
+
+	progress = (gdouble) priv->cur_requests
+		/ (gdouble) priv->total_requests;
+
+	if (progress > 1.0)
+		return 1.0;
+
+	return progress;
+}
+
+
+static const gchar *
+kz_gecko_embed_get_location (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (priv->location != NULL &&
+	    !strncmp(priv->location, "about:blank", 11))
+	{
+		return "";
+	}
+
+	return priv->location;
+}
+
+static void
+kz_gecko_embed_destroy_brsr (GtkMozEmbed *embed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
+
+	gtk_widget_destroy(GTK_WIDGET(embed));
+}
+
+
+static void
+kz_gecko_embed_link_message (GtkMozEmbed *embed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
+
+	g_signal_emit_by_name(embed, "kz-link-message");
+
+	if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->link_message)
+		((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->link_message(embed);
+}
+
+static void
+kz_gecko_embed_js_status (GtkMozEmbed *embed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
+
+	g_signal_emit_by_name(embed, "kz-js-status");
+
+	if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->js_status)
+		((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->js_status(embed);
+}
+
+static void
+kz_gecko_embed_title (GtkMozEmbed *embed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(embed);
+
+	g_free(priv->title);
+
+	priv->title = gtk_moz_embed_get_title(embed);
+
+	g_signal_emit_by_name(embed, "kz-title");
+
+	if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->title)
+		((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->title(embed);
+}
+
+static void
+kz_gecko_embed_location (GtkMozEmbed *embed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(embed);
+
+#ifndef KZ_REGRESSION_BUG4474
+	if (priv->first_url)
+	{
+		gchar *tmp = g_strdup(priv->first_url);
+		g_free(priv->first_url);
+		priv->first_url = NULL;
+
+		kz_gecko_embed_load_url(KZ_EMBED(embed), tmp);
+		g_free(tmp);
+
+		return;
+	}
+#endif
+	if (priv->location)
+		g_free(priv->location);
+	priv->location = gtk_moz_embed_get_location(embed);
+
+	g_signal_emit_by_name(embed, "kz-location");
+
+	if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->location)
+		((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->location(embed);
+}
+
+
+static void
+kz_gecko_embed_net_start (GtkMozEmbed *embed)
+{
+	KzGeckoEmbed *kzembed = KZ_GECKO_EMBED(embed);
+
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (priv->first_url)
+		return;
+
+	priv->is_loading = TRUE;
+
+	/* First free previous link */
+	kz_gecko_embed_navigation_link_free(kzembed);
+
+	g_signal_emit_by_name(embed, "kz-net-start");
+
+	if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_start)
+		((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_start(embed);
+}
+
+static void
+net_stop_proccess (KzGeckoEmbed *kzembed)
+{
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return;
+	
+	gboolean create_thumbnail = FALSE, store_cache = TRUE;
+	KZ_CONF_GET("Global", "create_thumbnail", create_thumbnail, BOOL);
+	KZ_CONF_GET("History", "store_cache", store_cache, BOOL);
+
+	gchar *cache = g_strconcat("file://", g_get_home_dir(),
+			    	   HISTORY_DIR, NULL);
+	const gchar *location = kz_gecko_embed_get_location(KZ_EMBED(kzembed));
+	if (location && 
+	    (g_str_has_prefix(location, "http:") || 
+	     g_str_has_prefix(location, "https:") || 
+	     g_str_has_prefix(location, "history-search:") || 
+	     g_str_has_prefix(location, "file:")) &&
+	    !g_str_has_prefix(location, cache))
+	{
+		//get the last modification time
+		nsCOMPtr<nsIDOMDocument> domDoc;
+        	priv->wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
+		nsCOMPtr<nsIDOMNSDocument> doc = do_QueryInterface(domDoc);
+		nsEmbedString value;
+		doc->GetLastModified(value);
+
+		nsEmbedCString cValue;
+		NS_UTF16ToCString(value,
+				  NS_CSTRING_ENCODING_UTF8, cValue);
+		nsTime lm (cValue.get(), PR_TRUE);
+		GTime last_modified;
+		LL_DIV(last_modified,
+		       NS_STATIC_CAST(PRTime, lm), PR_USEC_PER_SEC);
+
+		nsCOMPtr<nsIURI> inURI;
+		nsEmbedCString sURI;
+		nsresult rv;
+
+		rv = priv->wrapper->GetDocumentUrl(sURI);
+		const gchar *uri = sURI.get();
+      		rv = NewURI(getter_AddRefs(inURI), uri);
+
+		if (create_thumbnail && 
+		    (!last_modified || (thumbnail_get_last_modified(uri) < last_modified)))
+		{
+			kz_gecko_embed_create_thumbnail(KZ_EMBED(kzembed));
+		}
+		
+		if ((!last_modified || (history_get_last_modified(uri) < last_modified)) &&
+		    !g_str_has_prefix(location, "history-search:"))
+		{
+			if (store_cache)
+			{
+				gchar *filename;
+				filename = kz_gecko_embed_store_history_file(kzembed);
+				if (filename)
+					g_free(filename);
+			}
+
+			if (KZ_GET_SEARCH)
+			{
+				const gchar *title = kz_gecko_embed_get_title(KZ_EMBED(kzembed));
+	
+				nsCOMPtr<nsIDOMNode> node = do_QueryInterface(domDoc);
+				nsCOMPtr<nsIDOMSerializer> serializer;
+				serializer = do_CreateInstance(NS_XMLSERIALIZER_CONTRACTID, &rv);
+				if (serializer)
+				{
+					serializer->SerializeToString(node, value);
+					NS_UTF16ToCString (value, NS_CSTRING_ENCODING_UTF8, cValue);
+				}
+				kz_search_register_document(KZ_GET_SEARCH, uri, title, cValue.get(), last_modified);
+#ifdef WITH_ANTHY_TRAINER
+				KzSearch *search = kz_search_new("anthy-trainer");
+				if (search)
+				{
+					kz_search_register_document(search, uri, title, cValue.get(), last_modified);
+					g_object_unref(search);
+				}
+#endif
+			}
+		}
+	}
+	
+	g_free(cache);
+}
+
+static void
+kz_gecko_embed_net_stop (GtkMozEmbed *embed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(embed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (embed);
+	priv->is_loading = FALSE;
+
+	if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_stop)
+		((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_stop(embed);
+
+	net_stop_proccess(KZ_GECKO_EMBED(embed));
+
+	g_signal_emit_by_name(embed, "kz-net-stop");
+}
+
+static void
+kz_gecko_embed_net_state_all (GtkMozEmbed *embed, const char *aURI,
+			    gint state, guint status)
+{
+	KzGeckoEmbed *kzembed = KZ_GECKO_EMBED(embed);
+
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (state & GTK_MOZ_EMBED_FLAG_IS_NETWORK)
+	{
+		priv->total_requests = 0;
+		priv->cur_requests = 0;
+#if 0
+                if (state & GTK_MOZ_EMBED_FLAG_START)
+                {
+		}
+                else if (state & EMBED_STATE_STOP)
+                {
+                        priv->total_requests = 0;
+                        priv->cur_requests = 0;
+		} 
+#endif
+	}
+        if (state & GTK_MOZ_EMBED_FLAG_IS_REQUEST)
+        {
+                if (state & GTK_MOZ_EMBED_FLAG_START)
+                        priv->total_requests ++;
+                else if (state & GTK_MOZ_EMBED_FLAG_STOP)
+                        priv->cur_requests ++;
+        }
+
+	g_signal_emit_by_name(embed, "kz-progress");
+
+	if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_state_all)
+		((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->net_state_all(embed, aURI, state, status);
+}
+
+static void 
+cb_embed_destroy_browser (GtkMozEmbed *embed, GtkWidget *transient_window)
+{
+	gtk_widget_destroy(GTK_WIDGET(transient_window));
+}
+
+static void
+kz_gecko_embed_new_window (GtkMozEmbed *embed, GtkMozEmbed **newEmbed,
+			 guint chromemask)
+{
+	if ((chromemask & GTK_MOZ_EMBED_FLAG_OPENASCHROME) != 0)
+	{
+		/* FIXME! this is ad hoc. */
+		GtkWidget *newWindow = gtk_window_new(GTK_WINDOW_TOPLEVEL);
+
+		gtk_window_set_transient_for(GTK_WINDOW(newWindow),
+					     GTK_WINDOW(gtk_widget_get_toplevel(GTK_WIDGET(embed))));
+		*newEmbed = GTK_MOZ_EMBED(kz_gecko_embed_new(NULL));
+		g_signal_connect(*newEmbed,"destroy",
+				 G_CALLBACK(cb_embed_destroy_browser),
+				 newWindow);
+		gtk_container_add(GTK_CONTAINER(newWindow),
+				  GTK_WIDGET(*newEmbed));
+	}
+	else
+	{
+		g_signal_emit_by_name(embed, "kz-new-window", newEmbed);
+	}
+}
+
+static gint
+kz_gecko_embed_open_uri (GtkMozEmbed *embed, const char *uri)
+{
+	gint ret = FALSE;
+
+	g_signal_emit_by_name(embed, "kz-open-uri", uri, &ret);
+
+	if (((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->open_uri)
+		ret = ((GtkMozEmbedClass*)kz_gecko_embed_parent_class)->open_uri(embed, uri);
+
+#if 0
+	if (!strncmp(uri, "mailto:", 7))
+	{
+		return TRUE;
+	}
+#endif
+
+	return ret;
+}
+
+static void
+kz_gecko_embed_size_to (GtkMozEmbed *embed, gint width, gint height)
+{
+	gtk_widget_set_size_request(GTK_WIDGET(embed), width, height);
+	gtk_widget_queue_resize(GTK_WIDGET(embed));
+
+	g_signal_emit_by_name(embed, "kz-size-to", width, height);
+}
+
+static gint
+kz_gecko_embed_dom_key_down (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventKey *kzevent;
+	gint ret = FALSE;
+
+	kz_gecko_embed_get_key_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
+	g_signal_emit_by_name(embed, "kz-dom-key-down",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
+static gint
+kz_gecko_embed_dom_key_up (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventKey *kzevent;
+	gint ret = FALSE;
+
+	kz_gecko_embed_get_key_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
+	g_signal_emit_by_name(embed, "kz-dom-key-up",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
+static gint
+kz_gecko_embed_dom_key_press (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventKey *kzevent;
+	gint ret = FALSE;
+
+	kz_gecko_embed_get_key_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
+	g_signal_emit_by_name(embed, "kz-dom-key-press",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
+static gint
+kz_gecko_embed_dom_mouse_down (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventMouse *kzevent;
+	gint ret = FALSE;
+
+	kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
+
+	g_signal_emit_by_name(embed, "kz-dom-mouse-down",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
+static gint
+kz_gecko_embed_dom_mouse_up (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventMouse *kzevent;
+	gint ret = FALSE;
+
+	kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
+	g_signal_emit_by_name(embed, "kz-dom-mouse-up",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
+static gint
+kz_gecko_embed_dom_mouse_click (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventMouse *kzevent;
+	gint ret = FALSE;
+
+	kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
+	g_signal_emit_by_name(embed, "kz-dom-mouse-click",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
+static gint
+kz_gecko_embed_dom_mouse_dbl_click (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventMouse *kzevent;
+	gint ret = FALSE;
+
+	kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
+	g_signal_emit_by_name(embed, "kz-dom-mouse-dbl-click",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
+static
+gint kz_gecko_embed_dom_mouse_over (GtkMozEmbed *embed, gpointer event)
+{
+	KzEmbedEventMouse *kzevent;
+	gint ret = FALSE;
+
+	kz_gecko_embed_get_mouse_event_info(KZ_GECKO_EMBED(embed), event, &kzevent);
+	g_signal_emit_by_name(embed, "kz-dom-mouse-over",
+			      kzevent, &ret);
+	kz_embed_event_free((KzEmbedEvent *) kzevent);
+
+	return ret;
+}
+
+static void
+kz_gecko_embed_visibility (GtkMozEmbed *embed, gboolean visibility)
+{
+	GtkWidget *parent = NULL;
+
+	parent = gtk_widget_get_parent(GTK_WIDGET(embed));
+	g_return_if_fail(parent != NULL);
+	
+	g_object_set(embed, "visible", visibility, NULL);
+	g_object_set(parent, "visible", visibility, NULL);
+}
+
+#if 0
+static void
+kz_gecko_embed_security_change (GtkMozEmbed *embed,
+			      gpointer request,
+			      guint state)
+{
+	if (kz_gecko_embed_parent_class->security_change)
+		kz_gecko_embed_parent_class->security_change(embed, request, state);
+}
+#endif
+
+static gboolean
+kz_gecko_embed_can_cut_selection (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return TRUE;
+
+	PRBool retval;
+	nsresult rv = priv->wrapper->CanCutSelection(&retval);
+
+	if (NS_FAILED(rv)) return FALSE;
+
+	return retval;
+}
+
+static gboolean
+kz_gecko_embed_can_copy_selection (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return TRUE;
+
+	PRBool retval;
+	nsresult rv = priv->wrapper->CanCopySelection(&retval);
+
+	if (NS_FAILED(rv)) return FALSE;
+
+	return retval;
+}
+
+static gboolean
+kz_gecko_embed_can_paste (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return TRUE;
+
+	PRBool retval;
+	nsresult rv = priv->wrapper->CanPaste(&retval);
+
+	if (NS_FAILED(rv)) return FALSE;
+
+	return retval;
+}
+
+static void
+kz_gecko_embed_cut_selection (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail(priv->wrapper);
+
+	priv->wrapper->CutSelection();
+}
+
+static void
+kz_gecko_embed_copy_selection (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail(priv->wrapper);
+
+	priv->wrapper->CopySelection();
+}
+
+static void
+kz_gecko_embed_paste (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail(priv->wrapper);
+
+	priv->wrapper->Paste();
+}
+
+static void
+kz_gecko_embed_select_all (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail(priv->wrapper);
+
+	priv->wrapper->SelectAll();
+}
+
+static gchar *
+kz_gecko_embed_get_selection_string(KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return NULL;
+
+	nsresult rv;
+
+	nsCOMPtr<nsISelection> selection;
+	rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
+	if (!selection) return NULL;
+
+	PRUnichar *string;
+	rv = selection->ToString(&string);
+	
+	nsEmbedCString str;
+	NS_UTF16ToCString(nsEmbedString(string),
+			  NS_CSTRING_ENCODING_UTF8, str);
+
+	return g_strdup (str.get());
+}
+
+static gchar *
+kz_gecko_embed_get_html_with_contents (KzEmbed *kzembed, const gchar *storedir)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return NULL;
+
+	nsresult rv;
+
+	nsCOMPtr<nsISelection> selection;
+	rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
+	if (!selection) return NULL;
+
+	nsEmbedString string;
+	rv = priv->wrapper->GetHtmlWithContents(selection, 
+						storedir,
+						string);
+	if (NS_FAILED(rv)) return NULL;
+
+	nsEmbedCString str;
+	NS_UTF16ToCString(nsEmbedString(string),
+			  NS_CSTRING_ENCODING_UTF8, str);
+	return g_strdup(str.get());
+}
+#if 0
+static gchar *
+kz_gecko_embed_get_selection_source(KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	if (!priv->wrapper) return NULL;
+
+	nsresult rv;
+
+	nsCOMPtr<nsISelection> selection;
+	rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
+	if (!selection) return NULL;
+
+	nsAutoString string;
+	rv = priv->wrapper->GetSelectionSource(selection, PR_TRUE, string);
+	if (NS_FAILED(rv)) return NULL;
+
+	return g_strdup(NS_ConvertUCS2toUTF8(string).get());
+}
+#endif
+
+#if USE_MIGEMO
+static gboolean
+kz_gecko_embed_get_body_string(KzGeckoEmbed *mozembed, gchar **body_string,
+			     gboolean backward, gboolean whole)
+{
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (mozembed);
+	nsEmbedString text;
+	nsresult rv;
+
+	if (whole)
+		rv = priv->wrapper->GetBodyString(text);
+	else
+		rv = priv->wrapper->GetStringSelection(text, backward);
+	if (NS_FAILED(rv))
+		return FALSE;
+	
+	nsEmbedCString str;
+	NS_UTF16ToCString(text,
+			  NS_CSTRING_ENCODING_UTF8, str);
+	*body_string = g_strdup(str.get());
+	return TRUE;
+}
+
+static void
+set_migemo_keyword(KzGeckoEmbed *mozembed, const char *keyword,
+		   gchar *body_string, gboolean backward)
+{
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (mozembed);
+	g_free(priv->migemo_keyword);
+	priv->migemo_keyword =
+		kz_migemo_get_matched_text(KZ_GET_MIGEMO, body_string,
+					   keyword, backward);
+}
+#endif
+
+static gboolean
+kz_gecko_embed_unhighlight_word (KzEmbed *kzembed, const char *word)
+{
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return FALSE;
+
+	KzMozWrapper *wrapper = priv->wrapper;
+
+	nsresult rv;
+	nsCOMPtr<nsIFind> finder;
+	finder = do_CreateInstance("@mozilla.org/embedcomp/rangefind;1", &rv);
+
+	if (NS_FAILED(rv)) return FALSE;
+
+	nsEmbedString string;
+	NS_CStringToUTF16(nsEmbedCString(word),
+			  NS_CSTRING_ENCODING_UTF8, string);
+	const PRUnichar *u_word;
+	NS_StringGetData(string, &u_word);
+	
+	nsCOMPtr<nsIDOMDocument> domDoc;
+       	rv = wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
+        if (NS_FAILED(rv) || !domDoc) return FALSE;
+	
+	nsCOMPtr<nsIDOMDocumentRange> docRange = do_QueryInterface(domDoc);
+	if (!docRange) return FALSE;
+
+	nsCOMPtr<nsIDOMRange> searchRange;
+	nsCOMPtr<nsIDOMRange> startRange;
+	nsCOMPtr<nsIDOMRange> endRange;
+	rv = wrapper->SetHighlightRange(getter_AddRefs(searchRange),
+	    				getter_AddRefs(startRange),
+					getter_AddRefs(endRange));
+	nsCOMPtr<nsIDOMRange> retRange;
+
+	while (finder->Find(u_word, searchRange, startRange, endRange, getter_AddRefs(retRange)) == NS_OK)
+	{
+		if (!retRange) break;
+
+		nsCOMPtr<nsIDOMNode> startContainer;
+		retRange->GetStartContainer(getter_AddRefs(startContainer));
+
+		nsCOMPtr<nsIDOMNode> elm;
+		startContainer->GetParentNode(getter_AddRefs(elm));
+
+		char *attr = NULL;
+		wrapper->GetAttributeFromNode(elm, "id", &attr);
+		if (elm && attr && !g_ascii_strcasecmp(attr, "kazehakase-search"))
+		{
+			nsCOMPtr<nsIDOMDocumentFragment> flag;
+			nsCOMPtr<nsIDOMNode> next;
+			nsCOMPtr<nsIDOMNode> parent;
+
+			domDoc->CreateDocumentFragment(getter_AddRefs(flag));
+			nsCOMPtr<nsIDOMNode> flagNode;
+			flagNode = do_QueryInterface(flag);
+
+			elm->GetNextSibling(getter_AddRefs(next));
+			elm->GetParentNode(getter_AddRefs(parent));
+
+			nsCOMPtr<nsIDOMNode> child;
+			while (elm->GetFirstChild(getter_AddRefs(child)) == NS_OK)
+			{
+				if (!child) break;
+				nsCOMPtr<nsIDOMNode> newNode;
+				flagNode->AppendChild(child, getter_AddRefs(newNode));
+			}
+
+			docRange->CreateRange(getter_AddRefs(startRange));
+			startRange->SetStartAfter(elm);
+
+			nsCOMPtr<nsIDOMNode> tmp;
+			parent->RemoveChild(elm, getter_AddRefs(tmp));
+			parent->InsertBefore(flagNode, next, getter_AddRefs(tmp));
+		}
+		else
+		{
+			nsCOMPtr<nsIDOMNode> endContainer;
+			retRange->GetEndContainer(getter_AddRefs(endContainer));
+			PRInt32 endOffset;
+			retRange->GetEndOffset(&endOffset);
+			docRange->CreateRange(getter_AddRefs(startRange));
+			startRange->SetStart(endContainer, endOffset);
+		}
+		startRange->Collapse(PR_TRUE);
+	}
+
+	return TRUE;
+}
+
+
+// this function is drawn upon 
+//   toolkit/components/typeaheadfind/content/findBar.js in firefox-1.0+.
+static gboolean
+kz_gecko_embed_highlight_word (KzEmbed *kzembed, const char *word)
+{
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (priv->last_highlight)
+	{
+		if (!strcmp(priv->last_highlight, word))
+			return TRUE;
+		kz_gecko_embed_unhighlight_word (kzembed, priv->last_highlight);
+		g_free(priv->last_highlight);
+	}
+	
+	priv->last_highlight = g_strdup(word);
+
+	nsresult rv;
+	nsCOMPtr<nsIFind> finder;
+	finder = do_CreateInstance("@mozilla.org/embedcomp/rangefind;1", &rv);
+
+	if (NS_FAILED(rv)) return FALSE;
+
+	nsEmbedString string;
+	NS_CStringToUTF16(nsEmbedCString(word),
+			  NS_CSTRING_ENCODING_UTF8, string);
+	const PRUnichar *u_word;
+	NS_StringGetData(string, &u_word);
+	
+	nsCOMPtr<nsIDOMDocument> domDoc;
+       	rv = priv->wrapper->GetMainDomDocument(getter_AddRefs(domDoc));
+        if (NS_FAILED(rv) || !domDoc) return FALSE;
+
+
+	nsCOMPtr<nsIDOMRange> searchRange;
+	nsCOMPtr<nsIDOMRange> startRange;
+	nsCOMPtr<nsIDOMRange> endRange;
+	rv = priv->wrapper->SetHighlightRange(getter_AddRefs(searchRange),
+	    						     getter_AddRefs(startRange),
+							     getter_AddRefs(endRange));
+
+	const PRUnichar span[]          = { 's', 'p', 'a', 'n' ,'\0' };
+	const PRUnichar style[]         = { 's', 't', 'y', 'l' ,'e', '\0' };
+	const PRUnichar u_color[]       = { 's', 'p', 'a', 'n' ,'\0' };
+	const PRUnichar id[]            = { 'i', 'd', '\0' };
+	const PRUnichar sc[]            = { ';', '\0' };
+	const PRUnichar bg_color[]      = { 'b', 'a', 'c', 'k' ,'g', 'r', 
+			 		    'o', 'u', 'n', 'd', '-', 'c',
+			 		    'o', 'l', 'o', 'r', ':', '\0' };
+	const PRUnichar kazehakase_id[] = { 'k', 'a', 'z', 'e' ,'h', 'a', 
+					    'k', 'a', 's', 'e', '-', 's',
+					    'e', 'a', 'r', 'c', 'h', '\0' };
+
+	nsEmbedCString cColor("#ffff00");
+	nsEmbedString uColor;
+	NS_CStringToUTF16(cColor, NS_CSTRING_ENCODING_UTF8, uColor);
+	nsEmbedString color(bg_color);
+	color += uColor;
+	color += sc;
+	nsCOMPtr<nsIDOMElement> baseElm;
+	domDoc->CreateElement(nsEmbedString(span), getter_AddRefs(baseElm));
+	baseElm->SetAttribute(nsEmbedString(style), color);
+	baseElm->SetAttribute(nsEmbedString(id), nsEmbedString(kazehakase_id));
+	nsCOMPtr<nsIDOMNode> baseNode = do_QueryInterface(baseElm);
+
+	nsCOMPtr<nsIDOMRange> retRange;
+
+	while (finder->Find(u_word, searchRange, startRange, endRange, getter_AddRefs(retRange)) == NS_OK)
+	{
+		if (!retRange) break;
+
+		nsCOMPtr<nsIDOMNode> node;
+		baseNode->CloneNode(PR_TRUE, getter_AddRefs(node));
+
+		nsCOMPtr<nsIDOMNode> startContainer;
+		retRange->GetStartContainer(getter_AddRefs(startContainer));
+
+		PRInt32 startOffset, endOffset;
+		retRange->GetStartOffset(&startOffset);
+		retRange->GetEndOffset(&endOffset);
+
+		nsCOMPtr<nsIDOMDocumentFragment> flag;
+		retRange->ExtractContents(getter_AddRefs(flag));
+		if (!flag) continue;
+
+		nsCOMPtr<nsIDOMNode> flagNode;
+		flagNode = do_QueryInterface(flag);
+
+		nsCOMPtr<nsIDOMText> text;
+		text = do_QueryInterface(startContainer);
+
+		nsCOMPtr<nsIDOMText> before;
+		text->SplitText(startOffset, getter_AddRefs(before));
+		nsCOMPtr<nsIDOMNode> beforeNode;
+		beforeNode = do_QueryInterface(before);
+		
+		nsCOMPtr<nsIDOMNode> parent;
+		beforeNode->GetParentNode(getter_AddRefs(parent));
+
+		nsCOMPtr<nsIDOMNode> newNode;
+		node->AppendChild(flagNode, getter_AddRefs(newNode));
+		nsCOMPtr<nsIDOMNode> newParent;
+		parent->InsertBefore(node, beforeNode, getter_AddRefs(newParent));
+
+		nsCOMPtr<nsIDOMDocument> doc;
+		node->GetOwnerDocument(getter_AddRefs(doc));
+		nsCOMPtr<nsIDOMDocumentRange> range;
+		range = do_QueryInterface(doc);
+
+		range->CreateRange(getter_AddRefs(startRange));
+
+		nsCOMPtr<nsIDOMNodeList> list;
+		node->GetChildNodes(getter_AddRefs(list));
+
+		PRUint32 length;
+		list->GetLength(&length);
+		startRange->SetStart(node, length);
+		startRange->SetEnd(node, length);
+	}
+
+	return TRUE;
+}
+
+  
+static gboolean
+kz_gecko_embed_find (KzEmbed *kzembed, const char *keyword,
+		   gboolean backward)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+	g_return_val_if_fail(keyword, FALSE);
+
+	nsCOMPtr<nsIWebBrowser> web;
+	gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(kzembed),
+					getter_AddRefs(web));
+	if (!web) return FALSE;
+
+
+	nsresult rv;
+	nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(web));
+#if USE_MIGEMO
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	gboolean use_migemo;
+	KZ_CONF_GET("Global", "use_migemo", use_migemo, BOOL);
+
+	nsEmbedString str;
+	if (use_migemo)
+	{
+		gchar *body_string;
+		KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+		if (!kz_gecko_embed_get_body_string(mozembed, &body_string,
+						  backward, FALSE))
+			goto START_SEARCH;
+		set_migemo_keyword(mozembed, keyword, body_string, backward);
+
+		if (!priv->migemo_keyword)
+		{
+			g_free(body_string);
+			if (!kz_gecko_embed_get_body_string(mozembed,
+							  &body_string,
+							  backward,
+							  TRUE))
+				goto START_SEARCH;
+			set_migemo_keyword(mozembed, keyword,
+					   body_string, backward);
+		}
+		
+		if (priv->migemo_keyword)
+		{
+			NS_CStringToUTF16(nsEmbedCString(priv->migemo_keyword),
+					  NS_CSTRING_ENCODING_UTF8, str);
+		}
+		else
+		{
+			NS_CStringToUTF16(nsEmbedCString(keyword),
+					  NS_CSTRING_ENCODING_UTF8, str);
+		}
+		g_free(body_string);
+	}
+	else
+	{
+		NS_CStringToUTF16(nsEmbedCString(keyword),
+				  NS_CSTRING_ENCODING_UTF8, str);
+	}
+	finder->SetSearchString(str.get());
+START_SEARCH:
+#else	
+	nsEmbedString str;
+	NS_CStringToUTF16(nsEmbedCString(keyword),
+			  NS_CSTRING_ENCODING_UTF8, str);
+	finder->SetSearchString(str.get());
+#endif
+	finder->SetFindBackwards(backward);
+	finder->SetWrapFind(TRUE);
+	finder->SetEntireWord(TRUE);
+	finder->SetSearchFrames(TRUE);
+	finder->SetMatchCase(FALSE);
+	PRBool did_find;
+	rv = finder->FindNext(&did_find);
+
+	return NS_SUCCEEDED(rv) && did_find ? TRUE : FALSE;
+}
+
+static gboolean
+kz_gecko_embed_incremental_search (KzEmbed *kzembed, const char *keyword,
+				 gboolean backward)
+{
+	nsresult rv;
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+	g_return_val_if_fail(keyword, FALSE);
+
+	if (strlen(keyword) == 0)
+		return FALSE;
+
+	nsCOMPtr<nsIWebBrowser> web;
+	gtk_moz_embed_get_nsIWebBrowser(GTK_MOZ_EMBED(kzembed),
+					getter_AddRefs(web));
+	if (!web) return FALSE;
+
+	nsCOMPtr<nsIWebBrowserFind> finder(do_GetInterface(web));
+#if USE_MIGEMO
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	gboolean use_migemo;
+	KZ_CONF_GET("Global", "use_migemo", use_migemo, BOOL);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	nsCOMPtr<nsISelection> selection;
+	rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
+	if (!selection) return FALSE;
+
+	selection->RemoveAllRanges();
+
+	nsEmbedString str;
+	if (use_migemo)
+	{
+		gchar *body_string;
+
+		if (!kz_gecko_embed_get_body_string(mozembed, &body_string,
+						  backward, TRUE))
+			goto START_SEARCH;
+		set_migemo_keyword(mozembed, keyword, body_string, backward);
+
+		if (priv->migemo_keyword) 
+		{
+			NS_CStringToUTF16(nsEmbedCString(priv->migemo_keyword),
+					  NS_CSTRING_ENCODING_UTF8, str);
+		}
+		else 
+		{
+			NS_CStringToUTF16(nsEmbedCString(keyword),
+					  NS_CSTRING_ENCODING_UTF8, str);
+		}
+		g_free(body_string);
+	}
+	else
+	{
+		NS_CStringToUTF16(nsEmbedCString(keyword),
+				  NS_CSTRING_ENCODING_UTF8, str);
+	}
+	finder->SetSearchString(str.get());
+START_SEARCH:
+#else
+	nsEmbedString str;
+	NS_CStringToUTF16(nsEmbedCString(keyword),
+			  NS_CSTRING_ENCODING_UTF8, str);
+	finder->SetSearchString(str.get());
+#endif
+	finder->SetFindBackwards(backward);
+	finder->SetWrapFind(TRUE);
+	finder->SetEntireWord(TRUE);
+	finder->SetSearchFrames(TRUE);
+	finder->SetMatchCase(FALSE);
+	PRBool did_find;
+	rv = finder->FindNext(&did_find);
+
+	// highlight search word
+	
+	gboolean use_highlight = FALSE;
+	KZ_CONF_GET("Global", "use_highlight", use_highlight, BOOL);
+	if (use_highlight)
+	{
+		if (NS_SUCCEEDED(rv))
+		{
+			nsEmbedCString c_str;
+			NS_UTF16ToCString(str, NS_CSTRING_ENCODING_UTF8, c_str);
+			kz_gecko_embed_highlight_word(kzembed, c_str.get());
+		}
+	}
+
+	return NS_SUCCEEDED(rv) && did_find ? TRUE : FALSE;
+}
+
+static gboolean
+kz_gecko_embed_selection_is_collapsed (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), TRUE);
+
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return TRUE;
+
+	nsresult rv;
+
+	nsCOMPtr<nsISelection> selection;
+	rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
+	if (!selection) return TRUE;
+
+	PRBool collapsed;
+	rv = selection->GetIsCollapsed(&collapsed);
+	if (NS_FAILED(rv)) return TRUE;
+
+	return collapsed;
+}
+
+
+static gboolean
+kz_gecko_embed_get_links (KzEmbed *kzembed, GList **list,
+			gboolean selected_only)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_val_if_fail(priv->wrapper, FALSE);
+	g_return_val_if_fail(list, FALSE);
+
+	// get selection
+	nsresult rv;
+	nsCOMPtr<nsISelection> selection;
+	rv = priv->wrapper->GetSelection(getter_AddRefs(selection));
+	if (NS_FAILED(rv)) return FALSE;
+
+	// get all anchor nodes in the document.
+	nsCOMPtr<nsIDOMDocument> mainDoc;
+        rv = priv->wrapper->GetMainDomDocument(getter_AddRefs(mainDoc));
+        if (NS_FAILED(rv) || !mainDoc) return FALSE;
+
+        // get main DOMWindow
+	nsCOMPtr<nsIDOMWindow> mainDOMWindow;
+	rv = priv->wrapper->GetDOMWindow(getter_AddRefs(mainDOMWindow));
+	if (NS_FAILED(rv)) return FALSE;
+
+	rv = priv->wrapper->GetLinksFromWindow(mainDOMWindow,
+							 list,
+							 selection,
+							 selected_only);
+
+	return NS_FAILED(rv) ? FALSE : TRUE;
+}
+
+
+static gboolean
+kz_gecko_embed_get_dest_anchors (KzEmbed *kzembed, GList **list)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_val_if_fail(priv->wrapper, FALSE);
+	g_return_val_if_fail(list, FALSE);
+
+	// get all anchor nodes in the document.
+	nsCOMPtr<nsIDOMDocument> mainDoc;
+        nsresult rv = priv->wrapper->GetMainDomDocument(getter_AddRefs(mainDoc));
+        if (NS_FAILED(rv) || !mainDoc) return FALSE;
+
+        // get main DOMWindow
+	nsCOMPtr<nsIDOMWindow> mainDOMWindow;
+	rv = priv->wrapper->GetDOMWindow(getter_AddRefs(mainDOMWindow));
+	if (NS_FAILED(rv)) return FALSE;
+
+	rv = priv->wrapper->GetDestAnchorsFromWindow(mainDOMWindow,
+						     list);
+
+	return NS_FAILED(rv) ? FALSE : TRUE;
+}
+
+
+glong
+kz_gecko_embed_get_key_event_info(KzGeckoEmbed *kzembed, gpointer event,
+				KzEmbedEventKey **info_ret)
+{
+	KzEmbedEventKey *info;
+	info = (KzEmbedEventKey *) kz_embed_event_new(KZ_EMBED_EVENT_KEY);
+	*info_ret = info;
+
+	nsresult result;
+
+	nsIDOMKeyEvent *aKeyEvent = (nsIDOMKeyEvent*) event;
+
+     	nsCOMPtr<nsIDOMEventTarget> OriginalTarget;
+
+     	nsCOMPtr<nsIDOMNSEvent> aEvent = do_QueryInterface(aKeyEvent);
+     	if (!aEvent) return KZ_CONTEXT_NONE;
+
+	PRUint32 code;
+	aKeyEvent->GetKeyCode(&code);
+	info->key = code;
+
+	aKeyEvent->GetCharCode(&code);
+	info->char_code = code;
+
+	PRBool mod_key;
+	info->modifier = 0;
+	aKeyEvent->GetAltKey(&mod_key);
+        if (mod_key) info->modifier |= KZ_ALT_KEY;
+
+	aKeyEvent->GetShiftKey(&mod_key);
+        if (mod_key) info->modifier |= KZ_SHIFT_KEY;
+
+	aKeyEvent->GetMetaKey(&mod_key);
+        if (mod_key) info->modifier |= KZ_META_KEY;
+
+	aKeyEvent->GetCtrlKey(&mod_key);
+        if (mod_key) info->modifier |= KZ_CTRL_KEY;
+
+     	result = aEvent->GetOriginalTarget(getter_AddRefs(OriginalTarget));
+
+     	if (NS_FAILED(result) || !OriginalTarget) return KZ_CONTEXT_NONE;
+
+     	nsCOMPtr<nsIDOMNode> OriginalNode = do_QueryInterface(OriginalTarget);
+     	if (!OriginalNode) return KZ_CONTEXT_NONE;
+
+     	nsEmbedString nodename;
+     	OriginalNode->GetNodeName(nodename);
+
+	nsEmbedCString cNodename;
+	NS_UTF16ToCString(nodename, NS_CSTRING_ENCODING_UTF8, cNodename);
+
+     	if (!g_ascii_strcasecmp(cNodename.get(), "xul:thumb") ||
+	    !g_ascii_strcasecmp(cNodename.get(), "xul:slider"))
+	{
+       		return KZ_CONTEXT_NONE;
+	}
+
+     	nsCOMPtr<nsIDOMEventTarget> target;
+     	result = aKeyEvent->GetTarget(getter_AddRefs(target));
+     	if (NS_FAILED(result) || !target) return KZ_CONTEXT_NONE;
+
+	return kz_gecko_embed_set_event_context(kzembed, target, (KzEmbedEvent *) info);
+}
+
+
+glong
+kz_gecko_embed_get_mouse_event_info(KzGeckoEmbed *kzembed, gpointer event,
+				  KzEmbedEventMouse **info_ret)
+{
+	KzEmbedEventMouse *info;
+	info = (KzEmbedEventMouse *) kz_embed_event_new(KZ_EMBED_EVENT_MOUSE);
+	*info_ret = info;
+
+	nsresult result;
+
+	nsIDOMMouseEvent *aMouseEvent = (nsIDOMMouseEvent*)event;
+
+     	nsCOMPtr<nsIDOMEventTarget> OriginalTarget;
+
+     	nsCOMPtr<nsIDOMNSEvent> aEvent = do_QueryInterface(aMouseEvent);
+     	if (!aEvent) return KZ_CONTEXT_NONE;
+
+	PRUint16 button;
+	aMouseEvent->GetButton(&button);
+	info->button = button;
+
+	PRBool mod_key;
+	info->modifier = 0;
+	aMouseEvent->GetAltKey(&mod_key);
+        if (mod_key) info->modifier |= KZ_ALT_KEY;
+
+	aMouseEvent->GetShiftKey(&mod_key);
+        if (mod_key) info->modifier |= KZ_SHIFT_KEY;
+
+	aMouseEvent->GetMetaKey(&mod_key);
+        if (mod_key) info->modifier |= KZ_META_KEY;
+
+	aMouseEvent->GetCtrlKey(&mod_key);
+        if (mod_key) info->modifier |= KZ_CTRL_KEY;
+
+	PRInt32 pos;
+	aMouseEvent->GetClientX(&pos);
+	info->x = pos;
+	aMouseEvent->GetClientY(&pos);
+	info->y = pos;
+
+     	result = aEvent->GetOriginalTarget(getter_AddRefs(OriginalTarget));
+
+     	if (NS_FAILED(result) || !OriginalTarget) return KZ_CONTEXT_NONE;
+
+     	nsCOMPtr<nsIDOMNode> OriginalNode = do_QueryInterface(OriginalTarget);
+     	if (!OriginalNode) return KZ_CONTEXT_NONE;
+
+     	nsEmbedString nodename;
+     	OriginalNode->GetNodeName(nodename);
+
+	nsEmbedCString cNodename;
+	NS_UTF16ToCString(nodename, NS_CSTRING_ENCODING_UTF8, cNodename);
+
+     	if (!g_ascii_strcasecmp(cNodename.get(), "xul:thumb") ||
+	    !g_ascii_strcasecmp(cNodename.get(), "xul:slider"))
+	{
+       		return KZ_CONTEXT_NONE;
+	}
+
+     	nsCOMPtr<nsIDOMEventTarget> target;
+     	result = aMouseEvent->GetTarget(getter_AddRefs(target));
+     	if (NS_FAILED(result) || !target) return KZ_CONTEXT_NONE;
+
+	return kz_gecko_embed_set_event_context(kzembed, target, (KzEmbedEvent *) info);
+}
+
+
+static glong
+mozilla_set_event_context (KzGeckoEmbed *kzembed,
+			   nsIDOMEventTarget *target,
+			   KzEmbedEvent *info)
+{
+	nsresult result;
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	KzMozWrapper *wrapper = priv->wrapper;
+
+	g_return_val_if_fail(priv->wrapper, KZ_CONTEXT_NONE);
+
+	nsCOMPtr<nsIDOMNode> node = do_QueryInterface(target);
+	if (!node) return KZ_CONTEXT_NONE;
+
+     	nsCOMPtr<nsIDOMDocument> domDoc;
+     	result = node->GetOwnerDocument(getter_AddRefs(domDoc));
+     	if (!NS_SUCCEEDED (result) || !domDoc) return KZ_CONTEXT_NONE;
+
+	nsCOMPtr<nsIDOM3Node> domnode = do_QueryInterface(domDoc);
+     	if(!domnode) return KZ_CONTEXT_NONE;
+
+     	nsCOMPtr<nsIDOMNSDocument> nsDoc = do_QueryInterface(domDoc);
+     	if (!nsDoc) return KZ_CONTEXT_NONE;
+
+	nsEmbedString spec;
+	domnode->GetBaseURI(spec);
+
+	nsEmbedCString cSpec;
+	NS_UTF16ToCString(spec,
+			  NS_CSTRING_ENCODING_UTF8, cSpec);
+
+	nsCOMPtr<nsIURI> baseURI;
+	NewURI(getter_AddRefs(baseURI), cSpec.get());
+	if (!baseURI) return KZ_CONTEXT_NONE;
+
+     	nsEmbedString mime;
+     	nsDoc->GetContentType(mime);
+
+	nsEmbedCString cMime;
+	NS_UTF16ToCString(mime, NS_CSTRING_ENCODING_UTF8, cMime);
+     	if (!g_ascii_strcasecmp(cMime.get(), "text/xul"))  return KZ_CONTEXT_NONE;
+
+	PRUint32 flags = KZ_CONTEXT_NONE;
+
+	// check framed page
+	nsCOMPtr<nsIDOMDocument> mainDocument;
+	result = priv->wrapper->GetMainDomDocument (getter_AddRefs(mainDocument));
+	if (domDoc != mainDocument)
+	{
+		flags |= KZ_CONTEXT_FRAME;
+		nsEmbedCString url;
+		baseURI->GetSpec(url);		
+		info->frame_src = g_strdup(url.get());
+	}
+	
+	// check whether the node is in the selection or not
+	nsCOMPtr<nsISelection> selection;
+	result = priv->wrapper->GetSelection(getter_AddRefs(selection));
+	if (selection)
+	{
+		PRBool contains;
+		selection->ContainsNode(node, PR_TRUE, &contains);
+		if (contains)
+			flags |= KZ_CONTEXT_SELECTION;
+	}
+
+	// Get other context
+	nsCOMPtr<nsIDOMHTMLElement> element;
+
+     	do {
+		PRUint16 type;
+		node->GetNodeType(&type);
+
+		element = do_QueryInterface(node);
+		if (element)
+		{
+			nsEmbedString uTag;
+			element->GetLocalName(uTag);
+
+			nsEmbedCString utf8_tag;
+			NS_UTF16ToCString(uTag, NS_CSTRING_ENCODING_UTF8, utf8_tag);
+
+			if (!g_ascii_strcasecmp(utf8_tag.get(), "input"))
+			{
+				flags |= KZ_CONTEXT_INPUT;
+			}
+			else if (!g_ascii_strcasecmp(utf8_tag.get(), "textarea"))
+			{
+				flags |= KZ_CONTEXT_INPUT | KZ_CONTEXT_TEXTAREA;
+				info->element = (void*)element;
+			}
+			else if (!g_ascii_strcasecmp(utf8_tag.get(), "img"))
+			{
+				flags |= KZ_CONTEXT_IMAGE;
+
+				char *src = NULL;
+				wrapper->GetAttributeFromNode(node, "src", &src);
+				if (!src)  return KZ_CONTEXT_NONE;
+
+			     	nsEmbedCString srca;
+			     	srca = nsEmbedCString(src);
+
+			     	nsEmbedCString srcc,imgc;
+				
+			     	srcc = nsEmbedCString(src);
+
+			     	result = baseURI->Resolve(srcc, imgc);
+			     	g_free(src);
+
+			     	info->img = g_strdup(imgc.get());
+
+			     	if (!info->img) return KZ_CONTEXT_NONE;
+			}
+			else
+			{
+				flags |= KZ_CONTEXT_OTHER;
+			}
+
+			nsCOMPtr<nsIDOMNamedNodeMap> attributes;
+			node->GetAttributes(getter_AddRefs(attributes));
+			if (attributes)
+			{
+				nsCOMPtr<nsIDOMNode> hrefNode;
+				nsEmbedString href;
+
+				NS_CStringToUTF16(nsEmbedCString("href"),
+						  NS_CSTRING_ENCODING_UTF8,
+						  href);
+				attributes->GetNamedItem(href, getter_AddRefs(hrefNode));
+				if (hrefNode)
+				{
+					gchar *link;
+					flags |= KZ_CONTEXT_LINK;
+
+					wrapper->GetLinkAndTitleFromNode(domDoc,
+								 node,
+								 &link,
+								 &info->linktext);
+					if (!link)
+					{
+						g_free(info->linktext);
+						return KZ_CONTEXT_NONE;
+					}
+					if (!strncasecmp(link, "mailto:", 7))
+						info->link = g_strdup(link+7); 
+					else 
+						info->link = g_strdup(link);
+					g_free(link);
+					break;
+				}
+			}
+		}
+
+		nsCOMPtr<nsIDOMNode> parentNode;
+		node->GetParentNode(getter_AddRefs(parentNode));
+
+		if (!parentNode)
+		{
+			node = nsnull;
+			flags |= KZ_CONTEXT_DOCUMENT;
+			break;
+		}
+		node = parentNode;
+	} while (node);
+
+	info->context = flags;
+
+	return flags;
+}
+
+static gchar *
+kz_gecko_embed_get_up_location(KzGeckoEmbed *kzembed)
+{
+	const gchar *location;
+	gchar *up_location = NULL;
+	gchar *pos, *dummy;
+	int len; 
+
+	location = kz_gecko_embed_get_location(KZ_EMBED(kzembed));
+	if (!location)
+		return NULL;
+
+	len = strlen(location);
+	if (location[len - 1] == '/')
+		dummy = g_strndup(location, len - 1);
+	else 
+		dummy = g_strndup(location, len);
+	pos =  strrchr(dummy, '/');
+	if (pos)
+		up_location = g_strndup(dummy, pos - dummy + 1);
+	g_free(dummy);
+	return up_location;
+}
+
+static void
+kz_gecko_embed_reload (KzEmbed *kzembed, KzEmbedReloadFlag flags)
+{
+	gint32 moz_flags;
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	switch (flags) {
+	  case KZ_EMBED_RELOAD_NORMAL:
+	    moz_flags = GTK_MOZ_EMBED_FLAG_RELOADNORMAL;
+	    break;
+	  case KZ_EMBED_RELOAD_BYPASS_CACHE:
+	    moz_flags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSCACHE;
+	    break;
+	  case KZ_EMBED_RELOAD_BYPASS_PROXY:
+	    moz_flags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXY;
+	    break;
+	  case KZ_EMBED_RELOAD_BYPASS_PROXY_AND_CACHE:
+	    moz_flags = GTK_MOZ_EMBED_FLAG_RELOADBYPASSPROXYANDCACHE;
+	    break;
+	  case KZ_EMBED_RELOAD_CHARSET_CHANGE:
+	    moz_flags = GTK_MOZ_EMBED_FLAG_RELOADCHARSETCHANGE;
+	    break;
+	}
+
+	gtk_moz_embed_reload(GTK_MOZ_EMBED(kzembed), moz_flags);
+}
+
+
+static void
+kz_gecko_embed_stop_load (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	gtk_moz_embed_stop_load(GTK_MOZ_EMBED(kzembed));
+}
+
+
+static void
+kz_gecko_embed_go_back (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	gtk_moz_embed_go_back(GTK_MOZ_EMBED(kzembed));
+}
+
+
+static void
+kz_gecko_embed_go_up (KzEmbed *kzembed)
+{
+	gchar *location;
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	location = kz_gecko_embed_get_up_location(KZ_GECKO_EMBED(kzembed));
+	kz_gecko_embed_load_url(kzembed, location);
+	g_free(location);
+}
+
+static void
+kz_gecko_embed_go_forward (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	gtk_moz_embed_go_forward(GTK_MOZ_EMBED(kzembed));
+}
+
+
+static gboolean
+kz_gecko_embed_can_go_back (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+	return gtk_moz_embed_can_go_back(GTK_MOZ_EMBED(kzembed));
+}
+
+static gboolean
+kz_gecko_embed_can_go_forward (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+	return gtk_moz_embed_can_go_forward(GTK_MOZ_EMBED(kzembed));
+}
+
+static gboolean
+kz_gecko_embed_can_go_nav_link (KzEmbed *kzembed,
+			      KzEmbedNavLink link)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	KzNavi *navi = KZ_NAVI(g_list_nth_data(priv->nav_links[link], 0));
+	return (navi && navi->uri) ? TRUE : FALSE;
+}
+
+static void
+kz_gecko_embed_go_nav_link (KzEmbed *kzembed,
+			  KzEmbedNavLink link)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	KzNavi *navi = KZ_NAVI(g_list_nth_data(priv->nav_links[link], 0));
+	g_return_if_fail(navi);
+
+	kz_gecko_embed_load_url(kzembed, navi->uri);
+}
+
+
+static void
+kz_gecko_embed_append_nav_link (KzEmbed *kzembed,
+			      KzEmbedNavLink link,
+			      KzNavi *navi)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	g_return_if_fail(link < KZ_EMBED_LINK_GUARD);
+	g_return_if_fail(navi);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	priv->nav_links[link] = g_list_append(priv->nav_links[link],
+					      g_object_ref(navi));
+}
+
+static void
+kz_gecko_embed_set_nth_nav_link (KzEmbed *kzembed,
+			       KzEmbedNavLink link,
+			       KzNavi *navi,
+			       guint n)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	g_return_if_fail(link < KZ_EMBED_LINK_GUARD);
+	g_return_if_fail(navi);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	guint len = g_list_length(priv->nav_links[link]);
+	GList *nth_nav_link;
+
+	if (n >= len)
+	{
+		int i;
+		for (i = len; i < n; i++)
+		{
+			priv->nav_links[link] =
+				g_list_append(priv->nav_links[link], NULL);
+		}
+	}
+	
+	nth_nav_link = g_list_nth(priv->nav_links[link], n);
+	if (nth_nav_link->data)
+		g_object_unref(nth_nav_link->data);
+	nth_nav_link->data = g_object_ref(navi);
+}
+
+
+static KzNavi *
+kz_gecko_embed_get_nth_nav_link (KzEmbed *kzembed,
+			       KzEmbedNavLink link,
+			       guint n)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(kzembed);
+
+	return KZ_NAVI(g_list_nth_data(priv->nav_links[link], n));
+}
+
+
+static GList *
+kz_gecko_embed_get_nav_links (KzEmbed *kzembed,
+			    KzEmbedNavLink link)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(kzembed);
+
+	return priv->nav_links[link];
+}
+
+
+static void
+kz_gecko_embed_go_history_index (KzEmbed *kzembed, gint index)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail(priv->wrapper);
+	
+	priv->wrapper->GoHistoryIndex(index);
+}
+
+static void
+kz_gecko_embed_copy_page (KzEmbed *kzembed, KzEmbed *dkzembed,
+			KzEmbedCopyType type)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	g_return_if_fail(KZ_IS_GECKO_EMBED(dkzembed));
+
+	KzMozWrapper *dWrapper = KZ_GECKO_EMBED_GET_PRIVATE(dkzembed)->wrapper;;
+	KzMozWrapper *sWrapper = KZ_GECKO_EMBED_GET_PRIVATE(kzembed)->wrapper;;
+
+        nsresult rv;
+
+        nsCOMPtr<nsISupports> pageDescriptor;
+        rv = sWrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
+        if (!pageDescriptor || NS_FAILED(rv)) return;
+
+	PRUint32 aDisplayType = nsIWebPageDescriptor::DISPLAY_NORMAL;
+	switch (type) {
+	  case KZ_EMBED_COPY_NORMAL:
+	    aDisplayType = nsIWebPageDescriptor::DISPLAY_NORMAL;
+	    break;
+	  case KZ_EMBED_COPY_SOURCE:
+	    aDisplayType = nsIWebPageDescriptor::DISPLAY_AS_SOURCE;
+	    break;
+	}
+        rv = dWrapper->LoadDocument(pageDescriptor, aDisplayType);
+}
+
+
+static gboolean
+kz_gecko_embed_shistory_copy (KzEmbed *source,
+			    KzEmbed *dest,
+			    gboolean back_history,
+			    gboolean forward_history,
+			    gboolean set_current)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(source), FALSE);
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(dest), FALSE);
+
+	nsresult rv;
+	KzMozWrapper *d_wrapper = KZ_GECKO_EMBED_GET_PRIVATE(dest)->wrapper;;
+	KzMozWrapper *s_wrapper = KZ_GECKO_EMBED_GET_PRIVATE(source)->wrapper;;
+	rv = s_wrapper->CopyHistoryTo (d_wrapper, back_history, forward_history, set_current);
+
+	return NS_SUCCEEDED(rv) ? TRUE : FALSE;
+}
+
+
+/* picked from galeon-1.3.11a */
+static gboolean
+kz_gecko_embed_shistory_get_pos (KzEmbed *kzembed,
+			       int *pos, int *count)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	nsresult rv;
+	int total, index;
+
+	rv = priv->wrapper->GetSHInfo (&total, &index);
+
+	*pos = index;
+	*count = total;
+
+	return NS_SUCCEEDED(rv) ? TRUE : FALSE;
+}
+
+/* picked from galeon-1.3.11a */
+static void
+kz_gecko_embed_shistory_get_nth (KzEmbed *kzembed, 
+			       int nth,
+			       gboolean is_relative,
+			       char **aUrl,
+			       char **aTitle)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	KzMozWrapper *wrapper = priv->wrapper;
+	nsresult rv;
+
+	if (is_relative)
+	{
+		int pos, count;
+		if (kz_gecko_embed_shistory_get_pos(kzembed, &pos, &count))
+			pos += nth;
+		else
+			return;
+		nth = pos;
+	}
+	
+        nsEmbedCString url;
+        rv = wrapper->GetSHUrlAtIndex(nth, url);
+
+        *aUrl = (NS_SUCCEEDED (rv) && url.Length()) ? g_strdup(url.get()) : NULL;
+
+	PRUnichar *title;
+	rv = wrapper->GetSHTitleAtIndex(nth, &title);
+
+	nsEmbedCString str;
+	NS_UTF16ToCString(nsEmbedString(title),
+			  NS_CSTRING_ENCODING_UTF8, str);
+	*aTitle = g_strdup (str.get());
+	nsMemory::Free(title);
+}
+
+
+static gboolean
+kz_gecko_embed_get_lock (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	return priv->lock;
+}
+
+
+static void
+kz_gecko_embed_set_lock (KzEmbed *kzembed, gboolean lock)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	priv->lock = lock;
+}
+
+
+static gchar *
+kz_gecko_embed_get_body_text(KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	nsEmbedString text;
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_val_if_fail(priv->wrapper, FALSE);
+	priv->wrapper->GetBodyString(text);
+
+	nsEmbedCString cText;
+	NS_UTF16ToCString(text,
+			  NS_CSTRING_ENCODING_UTF8, cText);
+	return g_strdup(cText.get());
+}
+
+
+static void
+kz_gecko_embed_set_encoding (KzEmbed *kzembed, const char *encoding)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail(priv->wrapper);
+	priv->wrapper->ForceEncoding(encoding);
+}
+
+static void
+kz_gecko_embed_get_encoding (KzEmbed *kzembed, char **encoding, gboolean *forced)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail(priv->wrapper);
+	priv->wrapper->GetEncoding(encoding, *forced);
+}
+
+static gboolean 
+kz_gecko_embed_save_with_content (KzEmbed *kzembed, const char *rawfilename)
+{
+	nsresult rv;
+	KzMozWrapper *wrapper = NULL;
+	PRUint32 persistFlags = 0;
+
+	nsCOMPtr<nsIWebBrowserPersist> bpersist = 
+		do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID);
+	if (!bpersist) return FALSE;
+
+	nsCOMPtr<nsIURI> linkURI;
+	linkURI = nsnull;
+
+	nsEmbedCString filename(rawfilename);
+        nsCOMPtr<nsILocalFile> file;
+       	NS_NewNativeLocalFile(filename, PR_TRUE, getter_AddRefs(file)); 
+        if (!file) return FALSE;
+
+	nsCOMPtr<nsILocalFile> path;
+	char *datapath;
+	datapath = g_strconcat (rawfilename, ".content", NULL);
+
+	nsEmbedString DataPath;
+	NS_CStringToUTF16(nsEmbedCString(datapath),
+			  NS_CSTRING_ENCODING_UTF8, DataPath);
+	NS_NewLocalFile(DataPath, PR_TRUE, getter_AddRefs(path));
+	g_free (datapath);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	wrapper = priv->wrapper;
+	g_return_val_if_fail (wrapper != NULL, FALSE);	
+
+	persistFlags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+
+	size_t len = strlen(rawfilename);
+	if((rawfilename[len-1] == 'z' && rawfilename[len-2] == 'g') ||
+	   (rawfilename[len-1] == 'Z' && rawfilename[len-2] == 'G'))
+	{
+                persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_NO_CONVERSION;
+	}
+
+	persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_BYPASS_CACHE;
+	bpersist->SetPersistFlags (persistFlags);
+
+	nsCOMPtr<nsIDOMDocument> DOMDocument;
+
+	rv = wrapper->GetMainDomDocument (getter_AddRefs(DOMDocument));
+	if (NS_FAILED(rv) || !DOMDocument) return FALSE;
+
+	nsCOMPtr<nsIURI> inURI;
+	nsEmbedCString sURI;
+
+	rv = wrapper->GetDocumentUrl(sURI);
+      	rv = NewURI(getter_AddRefs(inURI), sURI.get());
+
+	// FIXME! Use ProgressListener. 
+	// KzMozProgressListener *aProgress = new KzMozProgressListener ();
+	// aProgress->Init(inURI, path, 
+	//		nsnull, nsnull, 0, bpersist);
+
+	rv = bpersist->SaveDocument (DOMDocument, file, path, nsnull, 0, 0);
+	if (NS_FAILED(rv)) return FALSE;
+
+	return TRUE;
+}
+
+
+static void
+kz_gecko_embed_print (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail (priv->wrapper != NULL);
+
+	priv->wrapper->Print();
+}
+
+
+static void
+kz_gecko_embed_print_preview (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_if_fail (priv->wrapper != NULL);
+	
+	priv->wrapper->PrintPreview();
+}
+
+
+static GList *
+kz_gecko_embed_get_printer_list (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	g_return_val_if_fail (priv->wrapper != NULL, NULL);
+	
+	GList *list = NULL;
+	priv->wrapper->GetPrinterList(&list);
+
+	return list;
+}
+
+
+static gchar *
+kz_gecko_embed_get_text_from_textarea (KzEmbed *kzembed,
+				     gpointer element)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+
+	nsIDOMHTMLElement *htmlElement = (nsIDOMHTMLElement*)element;
+
+	nsCOMPtr<nsIDOMHTMLTextAreaElement> tElement = do_QueryInterface(htmlElement);
+
+	g_return_val_if_fail(tElement, NULL);
+
+	nsEmbedString string;
+	tElement->GetValue(string);
+
+	nsEmbedCString cString;
+	NS_UTF16ToCString(string,
+			  NS_CSTRING_ENCODING_UTF8, cString);
+
+	return g_strdup(cString.get());
+}
+
+
+static gboolean
+kz_gecko_embed_set_text_into_textarea (KzEmbed *kzembed,
+				     gpointer element,
+				     const gchar *text)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	nsIDOMHTMLElement *htmlElement = (nsIDOMHTMLElement*)element;
+
+	nsCOMPtr<nsIDOMHTMLTextAreaElement> tElement = do_QueryInterface(htmlElement);
+
+	if (!tElement) return FALSE;
+
+	nsEmbedString string;
+	NS_CStringToUTF16(nsEmbedCString(text),
+			  NS_CSTRING_ENCODING_UTF8, string);
+	tElement->SetValue(string);
+
+	return TRUE;
+}
+
+
+static gchar *
+kz_gecko_embed_store_history_file(KzGeckoEmbed *kzembed)
+{
+	nsresult rv;
+
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), NULL);
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	KzMozWrapper *wrapper = priv->wrapper;
+	g_return_val_if_fail (wrapper != NULL, NULL);
+
+	PRUint32 persistFlags = 0;
+	
+	nsCOMPtr<nsIWebBrowserPersist> bpersist = 
+		do_CreateInstance(NS_WEBBROWSERPERSIST_CONTRACTID);
+	if (!bpersist) return NULL;
+
+	persistFlags = nsIWebBrowserPersist::PERSIST_FLAGS_REPLACE_EXISTING_FILES;
+
+	persistFlags |= nsIWebBrowserPersist::PERSIST_FLAGS_FROM_CACHE;
+	bpersist->SetPersistFlags (persistFlags);
+
+	nsCOMPtr<nsIURI> inURI;
+	nsEmbedCString sURI;
+
+	rv = wrapper->GetDocumentUrl(sURI);
+      	rv = NewURI(getter_AddRefs(inURI), sURI.get());
+
+	gchar *dir, *filename;
+
+	filename = create_filename_with_path_from_uri(sURI.get());
+		
+	dir = g_build_filename(g_get_home_dir(),
+			       HISTORY_DIR,
+			       filename,
+			       NULL);
+	g_free(filename);
+
+	nsCOMPtr<nsILocalFile> localFile = do_CreateInstance(NS_LOCAL_FILE_CONTRACTID);
+	rv = localFile->InitWithNativePath(nsEmbedCString(dir));
+
+	if (NS_FAILED(rv))
+		return NULL;
+
+	PRBool exists;
+	localFile->Exists(&exists);
+	if (!exists)
+	{
+		rv = localFile->Create(nsIFile::NORMAL_FILE_TYPE, 0600);
+		if (NS_FAILED(rv))
+			return NULL;
+	}
+
+	nsCOMPtr<nsISupports> pageDescriptor;
+
+	wrapper->GetPageDescriptor(getter_AddRefs(pageDescriptor));
+	
+	rv = bpersist->SaveURI (inURI, pageDescriptor, nsnull,
+				nsnull, nsnull, localFile);
+
+	// update timestamp file
+	gchar *timestamp_file = g_build_filename(g_get_home_dir(),
+			HISTORY_DIR,
+			"timestamp",
+			NULL);
+
+	struct stat st;
+	g_stat(dir, &st);
+	// Hmm, rounding st_mtime causes some problem I think. Is it OK?
+	gchar *time = g_strdup_printf("%d", (int)st.st_mtime);
+
+	GIOChannel *io = g_io_channel_new_file(timestamp_file, "a+", NULL);
+	g_io_channel_set_encoding(io, NULL, NULL);
+	g_io_channel_write_chars(io, time, strlen(time),
+			NULL, NULL);
+	g_io_channel_write_chars(io, ",", 1, NULL, NULL);
+	g_io_channel_write_chars(io, dir, strlen(dir),
+			NULL, NULL);
+	g_io_channel_write_chars(io, "\n", 1, NULL, NULL);
+	g_io_channel_shutdown(io, TRUE, NULL);
+	g_io_channel_unref(io);
+
+	g_free(time);
+	g_free(timestamp_file);
+
+	return dir;
+}
+
+
+#ifndef MOZ_NSICANVASRENDERINGCONTEXTINTERNAL_HAVE_GETINPUTSTREAM_
+static KzMozThumbnailCreator *
+kz_window_create_thumbnail_creator (KzWindow *kz)
+{
+	KzMozThumbnailCreator *creator;
+
+	creator	= KZ_MOZ_THUMBNAIL_CREATOR(g_object_get_data(G_OBJECT(kz),
+							     "KzGeckoEmbed::ThumbnailCreator"));
+	if (!creator)
+	{
+		creator = kz_moz_thumbnail_creator_new();
+		gtk_widget_set_size_request(GTK_WIDGET(creator), 0, 0);
+		gtk_widget_show(GTK_WIDGET(creator));
+
+		gtk_box_pack_start(GTK_BOX(kz->statusbar),
+				   GTK_WIDGET(creator),
+				   FALSE, FALSE, 0);
+		g_object_set_data(G_OBJECT(kz), 
+				  "KzGeckoEmbed::ThumbnailCreator", 
+				  creator);
+	}
+
+	return creator;
+}
+#endif
+
+static void
+kz_gecko_embed_create_thumbnail (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	gboolean create_thumbnail = FALSE;
+	KZ_CONF_GET("Global", "create_thumbnail", create_thumbnail, BOOL);
+	if (!create_thumbnail) return;
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	KzMozWrapper *wrapper = priv->wrapper;
+	g_return_if_fail (wrapper != NULL);
+
+#ifdef MOZ_NSICANVASRENDERINGCONTEXTINTERNAL_HAVE_GETINPUTSTREAM_
+	wrapper->CreateThumbnail();
+#else
+	nsresult rv;
+	int total, index;
+	rv = wrapper->GetSHInfo (&total, &index);
+
+	nsCOMPtr<nsIHistoryEntry> he;
+	rv = wrapper->GetHistoryEntry(index, getter_AddRefs(he));
+	if (NS_FAILED(rv)) return;
+
+	GtkWidget *window = gtk_widget_get_toplevel(GTK_WIDGET(kzembed));
+
+	if (!KZ_IS_WINDOW(window)) return;
+
+	KzWindow *kz = KZ_WINDOW(window);
+
+	KzMozThumbnailCreator *creator;
+	creator = kz_window_create_thumbnail_creator(kz);
+	kz_moz_thumbnail_creator_append_queue(creator, he);
+#endif
+}
+
+
+void
+kz_gecko_embed_do_command (KzEmbed *kzembed, const char *command)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	nsCOMPtr<nsICommandManager> commandManager;
+	commandManager = do_GetInterface(priv->wrapper->mWebBrowser);
+	if (!commandManager) return;
+	
+	commandManager->DoCommand(command, nsnull, nsnull);
+
+}
+
+static gboolean
+kz_gecko_embed_can_do_command (KzEmbed *kzembed, const char *command)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+	
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	nsCOMPtr<nsICommandManager> commandManager;
+	commandManager = do_GetInterface(priv->wrapper->mWebBrowser);
+	if (!commandManager) return FALSE;
+	
+	PRBool enabled;
+	commandManager->IsCommandEnabled(command, nsnull, &enabled);
+
+	return (enabled == PR_TRUE);
+}
+
+static void
+kz_gecko_embed_zoom_set (KzEmbed *kzembed, int zoom, gboolean reflow)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	priv->wrapper->SetImageZoom ((float)(zoom) / 100);
+		
+	kz_gecko_embed_set_text_size(kzembed, zoom, reflow);
+}
+
+static int
+kz_gecko_embed_zoom_get (KzEmbed *kzembed)
+{
+	return kz_gecko_embed_get_text_size(kzembed);
+}
+
+
+static void
+kz_gecko_embed_set_text_size (KzEmbed *kzembed,  int zoom, gboolean reflow)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	priv->wrapper->SetZoom ((float)(zoom) / 100, reflow);
+}
+
+static int 
+kz_gecko_embed_get_text_size (KzEmbed *kzembed)
+{
+	float f;
+	int zoom;
+
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), 100);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return 100;
+
+	nsresult result = priv->wrapper->GetZoom (&f);
+	if (NS_FAILED (result)) return 100;
+
+	zoom = (int) rint (f * 100);
+
+	return zoom;
+}
+
+static void
+kz_gecko_embed_set_history (KzEmbed *kzembed, KzBookmark *history)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	g_return_if_fail(KZ_IS_BOOKMARK(history));
+
+	if (!kz_bookmark_is_folder(history)) return;
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return;
+
+	nsCOMPtr<nsISHistory> sHistory;
+	nsresult rv = priv->wrapper->GetSHistory(getter_AddRefs(sHistory));
+	if (NS_FAILED(rv) || !sHistory) return;
+
+	nsCOMPtr<nsISHistoryInternal> sHistoryInternal;
+	sHistoryInternal = do_QueryInterface(sHistory);
+
+	PRInt32 n;
+	sHistory->GetCount(&n);
+	sHistory->PurgeHistory(n);
+
+	GList *children, *node;
+	children = kz_bookmark_get_children(history);
+	for (node = children; node; node = g_list_next (node))
+	{
+		KzBookmark *child = KZ_BOOKMARK(node->data);
+		const gchar *title, *uri;
+
+		title = kz_bookmark_get_title(child);
+		uri   = kz_bookmark_get_link(child);
+
+		nsCOMPtr<nsISHEntry> entry;
+		entry = do_CreateInstance(NS_SHENTRY_CONTRACTID);
+
+		nsCOMPtr<nsIURI> aURI;
+		NewURI(getter_AddRefs(aURI), uri);		
+		/* FIXME! set correct contentType */
+		nsEmbedCString contentType;
+		entry->SetURI(aURI);
+		sHistoryInternal->AddEntry(entry, PR_TRUE);
+	}
+	g_list_free(children);
+
+	/* set current */
+	gint cur = kz_bookmark_get_current(history);
+	kz_gecko_embed_go_history_index(kzembed, cur);
+}
+
+static void
+kz_gecko_embed_get_history (KzEmbed *kzembed, KzBookmark *history)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+	g_return_if_fail(KZ_IS_BOOKMARK(history));
+
+	if (!kz_bookmark_is_folder(history)) return;
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+	if (!priv->wrapper) return;
+
+	nsCOMPtr<nsISHistory> sHistory;
+	nsresult rv = priv->wrapper->GetSHistory(getter_AddRefs(sHistory));
+
+	if (NS_FAILED(rv) || !sHistory) return;
+
+	GList *children, *tab;
+	children = kz_bookmark_get_children(history);
+	tab = children;
+
+	PRInt32 count;
+	sHistory->GetCount(&count);
+
+	PRInt32 index;
+	sHistory->GetIndex(&index);
+	for (PRInt32 i = 0; i < count; i++)
+	{
+		gchar *title = NULL, *uri = NULL;
+		KzBookmark *bookmark = NULL;
+		
+		kz_gecko_embed_shistory_get_nth (kzembed,
+					       i, FALSE,
+					       &uri,
+					       &title);
+		if (tab)
+		{
+			bookmark = KZ_BOOKMARK(tab->data);
+			tab = g_list_next(tab);
+		}
+
+		/* if there's no children of bookmarks, create a new bookmark */
+		if (!bookmark)
+		{
+			bookmark = kz_bookmark_new_with_attrs(title, uri, NULL);
+			kz_bookmark_append(history, bookmark);
+			g_object_unref(bookmark);
+		}
+		else if (uri && !strcmp(uri, kz_bookmark_get_link(bookmark)))
+		{
+			g_free(uri);
+			continue;
+		}
+		else
+		{
+			kz_bookmark_set_link(bookmark, uri);
+			kz_bookmark_set_title(bookmark, title);
+			kz_bookmark_set_last_visited(bookmark, 0);
+		}
+
+		if (title)
+			g_free(title);
+		if (uri)
+			g_free(uri);
+	}
+
+	if (tab)
+		tab = g_list_last(tab);
+	GList *prev;
+
+	while (tab)
+	{
+		KzBookmark *child = KZ_BOOKMARK(tab->data);
+		prev = g_list_previous(tab);
+		kz_bookmark_remove (history, child);
+		tab = prev;
+	}
+
+	if (children)
+		g_list_free(children);
+
+	kz_bookmark_set_current(history, (gint)index);
+}
+
+
+static guint
+kz_gecko_embed_get_last_modified (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), 0);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return 0;
+
+	nsresult result;
+
+	nsCOMPtr<nsIDOMDocument> DOMDocument;
+
+	result = priv->wrapper->GetDocument (getter_AddRefs(DOMDocument));
+	if (NS_FAILED(result) || !DOMDocument) return 0;
+
+	nsCOMPtr<nsIDOMNSDocument> doc = do_QueryInterface(DOMDocument);
+	if(!doc) return 0;
+	
+	nsEmbedString value;
+
+	doc->GetLastModified(value);
+
+	guint mod_time = 0;
+	nsEmbedCString cValue;
+	NS_UTF16ToCString(value,
+			  NS_CSTRING_ENCODING_UTF8, cValue);
+	nsTime last_modified (cValue.get(), PR_TRUE);
+	LL_DIV (mod_time,
+		NS_STATIC_CAST(PRTime, last_modified), PR_USEC_PER_SEC);
+	return mod_time;
+}
+
+
+#if 0
+static void
+kz_gecko_embed_set_edit_mode (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+
+	nsCOMPtr<nsIDOMWindow> domWindow;
+	priv->wrapper->GetDOMWindow(getter_AddRefs(domWindow));
+	
+	nsCOMPtr<nsIEditingSession> edit;
+	edit = do_GetInterface(priv->wrapper->mWebBrowser);
+	if (edit)
+	{
+		edit->MakeWindowEditable(domWindow, "html", PR_FALSE);
+	}
+}
+
+static void
+kz_gecko_embed_set_view_mode (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbed *mozembed = KZ_GECKO_EMBED(kzembed);
+	
+	nsCOMPtr<nsIDOMWindow> domWindow;
+	priv->wrapper->GetDOMWindow(getter_AddRefs(domWindow));
+	
+	nsCOMPtr<nsIEditingSession> edit;
+	edit = do_GetInterface(priv->wrapper->mWebBrowser);
+	if (edit)
+	{
+		edit->TearDownEditorOnWindow(domWindow);
+	}
+}
+#endif
+
+static void
+kz_gecko_embed_fine_scroll (KzEmbed *kzembed,
+			  int horiz, int vert)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return;
+
+	priv->wrapper->FineScroll (horiz, vert);
+}
+
+static void
+kz_gecko_embed_page_up (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return;
+	
+	priv->wrapper->PageUp();
+}
+
+static void
+kz_gecko_embed_page_down (KzEmbed *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return;
+	
+	priv->wrapper->PageDown();
+}
+
+static gboolean
+kz_gecko_embed_get_allow_javascript (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return FALSE;
+
+	PRBool allow;
+	priv->wrapper->GetAllowJavascript(&allow);
+
+	return allow ? TRUE : FALSE;
+}
+
+static void
+kz_gecko_embed_set_allow_javascript (KzEmbed *kzembed, gboolean allow)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return;
+	
+	priv->wrapper->SetAllowJavascript(allow);
+}
+
+static gboolean
+kz_gecko_embed_get_allow_images (KzEmbed *kzembed)
+{
+	g_return_val_if_fail(KZ_IS_GECKO_EMBED(kzembed), FALSE);
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return FALSE;
+
+	PRBool allow;
+	priv->wrapper->GetAllowImages(&allow);
+
+	return allow ? TRUE : FALSE;
+}
+
+static void
+kz_gecko_embed_set_allow_images (KzEmbed *kzembed, gboolean allow)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return;
+	
+	priv->wrapper->SetAllowImages(allow);
+}
+
+static void
+kz_gecko_embed_show_page_certificate (KzEmbed       *kzembed)
+{
+	g_return_if_fail(KZ_IS_GECKO_EMBED(kzembed));
+
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE (kzembed);
+
+	if (!priv->wrapper) return;
+
+	priv->wrapper->ShowPageCertificate();
+
+}
+
+static void
+nav_link_elem_free(gpointer object, gpointer unused)
+{
+	if (object)
+		g_object_unref(G_OBJECT(object));
+}
+
+static void
+kz_gecko_embed_navigation_link_free(KzGeckoEmbed *kzembed)
+{	
+	gint i;
+	KzGeckoEmbedPrivate *priv = KZ_GECKO_EMBED_GET_PRIVATE(kzembed);
+	
+	for (i = 0; i < KZ_EMBED_LINK_GUARD; i++)
+	{
+		if (priv->nav_links[i])
+		{
+			g_list_foreach(priv->nav_links[i], nav_link_elem_free, NULL);
+			g_list_free(priv->nav_links[i]);
+			priv->nav_links[i] = NULL;
+		}
+	}
+#ifdef USE_MIGEMO
+	if (priv->migemo_keyword)
+		g_free(priv->migemo_keyword);
+	priv->migemo_keyword =NULL;
+#endif
+	if (priv->last_highlight)
+		g_free(priv->last_highlight);
+	priv->last_highlight = NULL;
+}
+


More information about the Kazehakase-cvs mailing list
Back to archive index