+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#include "browser_widget.hpp"
+
+#include <cassert>
+
+#include <gtkmozembed_internal.h>
+
+browser_widget::browser_widget()
+ : Gtk::Bin(GTK_BIN(gtk_moz_embed_new()))
+{
+}
+browser_widget::~browser_widget()
+{
+}
+
+GtkMozEmbed * browser_widget::gobj()
+{
+ return GTK_MOZ_EMBED(gobject_);
+}
+const GtkMozEmbed * browser_widget::gobj() const
+{
+ return GTK_MOZ_EMBED(gobject_);
+}
+
+void browser_widget::load_uri(const char * uri)
+{
+ gtk_moz_embed_load_url(gobj(), uri);
+}
+void browser_widget::load_uri(const std::string & uri)
+{
+ return load_uri(uri.c_str());
+}
+void browser_widget::stop_load()
+{
+ gtk_moz_embed_stop_load(gobj());
+}
+void browser_widget::go_back()
+{
+ gtk_moz_embed_go_back(gobj());
+}
+void browser_widget::go_forward()
+{
+ gtk_moz_embed_go_forward(gobj());
+}
+void browser_widget::reload(gint32 flags)
+{
+ gtk_moz_embed_reload(gobj(), flags);
+}
+
+bool browser_widget::can_go_back() const
+{
+ return gtk_moz_embed_can_go_back(const_cast<GtkMozEmbed *>(gobj()));
+}
+bool browser_widget::can_go_forward() const
+{
+ return gtk_moz_embed_can_go_forward(const_cast<GtkMozEmbed *>(gobj()));
+}
+
+namespace
+{
+ template<typename T>
+ class c_scoped_ptr
+ {
+ public:
+ explicit c_scoped_ptr(T * p = 0) : p_(p) {}
+ ~c_scoped_ptr() { free(p_); }
+ T * get() const { return p_; }
+ T * release()
+ {
+ T * p = p_;
+ p_ = NULL;
+ return p;
+ }
+ void reset(T * p = 0)
+ {
+ free(p_);
+ p_ = p;
+ }
+ private:
+ T * p_;
+ };
+}
+
+std::string browser_widget::get_link_message() const
+{
+ c_scoped_ptr<char> str(
+ gtk_moz_embed_get_link_message(const_cast<GtkMozEmbed *>(gobj())));
+ return std::string(str.get());
+}
+std::string browser_widget::get_js_status() const
+{
+ c_scoped_ptr<char> str(
+ gtk_moz_embed_get_js_status(const_cast<GtkMozEmbed *>(gobj())));
+ return std::string(str.get());
+}
+std::string browser_widget::get_title() const
+{
+ c_scoped_ptr<char> str(
+ gtk_moz_embed_get_title(const_cast<GtkMozEmbed *>(gobj())));
+ return std::string(str.get());
+}
+std::string browser_widget::get_location() const
+{
+ c_scoped_ptr<char> str(
+ gtk_moz_embed_get_location(const_cast<GtkMozEmbed *>(gobj())));
+ return std::string(str.get());
+}
+already_AddRefed<nsIWebBrowser> browser_widget::get_browser()
+{
+ nsIWebBrowser * result = 0;
+ gtk_moz_embed_get_nsIWebBrowser(gobj(), &result);
+ assert(result);
+ return dont_AddRef(result);
+}
+
+namespace
+{
+ void browser_widget_signal_link_message_callback(GtkMozEmbed * self, void * data)
+ {
+ typedef SigC::Slot0<void> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_link_message_info =
+ {
+ "link_message",
+ (GCallback) &browser_widget_signal_link_message_callback,
+ (GCallback) &browser_widget_signal_link_message_callback
+ };
+
+ void browser_widget_signal_js_status_callback(GtkMozEmbed * self, void * data)
+ {
+ typedef SigC::Slot0<void> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_js_status_info =
+ {
+ "js_status",
+ (GCallback) &browser_widget_signal_js_status_callback,
+ (GCallback) &browser_widget_signal_js_status_callback
+ };
+
+ void browser_widget_signal_location_callback(GtkMozEmbed * self, void * data)
+ {
+ typedef SigC::Slot0<void> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_location_info =
+ {
+ "location",
+ (GCallback) &browser_widget_signal_location_callback,
+ (GCallback) &browser_widget_signal_location_callback
+ };
+
+ void browser_widget_signal_title_callback(GtkMozEmbed * self, void * data)
+ {
+ typedef SigC::Slot0<void> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_title_info =
+ {
+ "title",
+ (GCallback) &browser_widget_signal_title_callback,
+ (GCallback) &browser_widget_signal_title_callback
+ };
+
+ void browser_widget_signal_progress_callback(
+ GtkMozEmbed * self, gint p0, gint p1, void * data)
+ {
+ typedef SigC::Slot2<void, gint, gint> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(p0, p1, slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_progress_info =
+ {
+ "progress",
+ (GCallback) &browser_widget_signal_progress_callback,
+ (GCallback) &browser_widget_signal_progress_callback
+ };
+
+ void browser_widget_signal_net_state_callback(
+ GtkMozEmbed * self, const char * p0, gint p1, guint p2, void * data)
+ {
+ typedef SigC::Slot3<void, const char *, gint, guint> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(p0, p1, p2, slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_net_state_info =
+ {
+ "net_state_all",
+ (GCallback) &browser_widget_signal_net_state_callback,
+ (GCallback) &browser_widget_signal_net_state_callback
+ };
+
+ void browser_widget_signal_net_start_callback(GtkMozEmbed * self, void * data)
+ {
+ typedef SigC::Slot0<void> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_net_start_info =
+ {
+ "net_start",
+ (GCallback) &browser_widget_signal_net_start_callback,
+ (GCallback) &browser_widget_signal_net_start_callback
+ };
+
+ void browser_widget_signal_net_stop_callback(GtkMozEmbed * self, void * data)
+ {
+ typedef SigC::Slot0<void> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_net_stop_info =
+ {
+ "net_stop",
+ (GCallback) &browser_widget_signal_net_stop_callback,
+ (GCallback) &browser_widget_signal_net_stop_callback
+ };
+
+ void browser_widget_signal_new_window_callback(
+ GtkMozEmbed * self, GtkMozEmbed ** p0, guint p1, void * data)
+ {
+ typedef SigC::Slot1<browser_widget *, guint> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ {
+ if (browser_widget * result =
+ (*(SlotType::Proxy)(slot->proxy_))(p1, slot))
+ {
+ *p0 = result->gobj();
+ return;
+ }
+ }
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+
+ *p0 = NULL;
+ return;
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_new_window_info =
+ {
+ "new_window",
+ (GCallback) &browser_widget_signal_new_window_callback,
+ (GCallback) &browser_widget_signal_new_window_callback
+ };
+
+ void browser_widget_signal_visibility_callback(
+ GtkMozEmbed * self, gboolean p0, void * data)
+ {
+ typedef SigC::Slot1<void, bool> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(p0, slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_visibility_info =
+ {
+ "visibility",
+ (GCallback) &browser_widget_signal_visibility_callback,
+ (GCallback) &browser_widget_signal_visibility_callback
+ };
+
+ void browser_widget_signal_destroy_browser_callback(
+ GtkMozEmbed * self, void * data)
+ {
+ typedef SigC::Slot0<void> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ (*(SlotType::Proxy)(slot->proxy_))(slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_destroy_info =
+ {
+ "destroy_browser",
+ (GCallback) &browser_widget_signal_destroy_browser_callback,
+ (GCallback) &browser_widget_signal_destroy_browser_callback
+ };
+
+ gint browser_widget_signal_open_uri_callback(
+ GtkMozEmbed * self, const char * p0, void * data)
+ {
+ typedef SigC::Slot1<bool, const char *> SlotType;
+
+ if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
+ {
+ try
+ {
+ if (SigC::SlotNode * const slot =
+ Glib::SignalProxyNormal::data_to_slot(data))
+ return (*(SlotType::Proxy)(slot->proxy_))(p0, slot);
+ }
+ catch(...)
+ {
+ Glib::exception_handlers_invoke();
+ }
+ }
+
+ return 0;
+ }
+
+ const Glib::SignalProxyInfo browser_widget_signal_open_uri_info =
+ {
+ "open_uri",
+ (GCallback) &browser_widget_signal_open_uri_callback,
+ (GCallback) &browser_widget_signal_open_uri_callback
+ };
+
+} // namespace
+
+Glib::SignalProxy0<void> browser_widget::signal_link_message()
+{
+ return Glib::SignalProxy0<void>(this, &browser_widget_signal_link_message_info);
+}
+Glib::SignalProxy0<void> browser_widget::signal_js_status()
+{
+ return Glib::SignalProxy0<void>(this, &browser_widget_signal_js_status_info);
+}
+Glib::SignalProxy0<void> browser_widget::signal_location()
+{
+ return Glib::SignalProxy0<void>(this, &browser_widget_signal_location_info);
+}
+Glib::SignalProxy0<void> browser_widget::signal_title()
+{
+ return Glib::SignalProxy0<void>(this, &browser_widget_signal_title_info);
+}
+Glib::SignalProxy2<void, gint /*cur*/, gint /*max*/> browser_widget::signal_progress()
+{
+ return Glib::SignalProxy2<void, gint, gint>(
+ this, &browser_widget_signal_progress_info);
+}
+Glib::SignalProxy3<void, const char *, gint /*flags*/, guint /*status*/>
+browser_widget::signal_net_state()
+{
+ return Glib::SignalProxy3<void, const char *, gint, guint>(
+ this, &browser_widget_signal_net_state_info);
+}
+Glib::SignalProxy0<void> browser_widget::signal_net_start()
+{
+ return Glib::SignalProxy0<void>(this, &browser_widget_signal_net_start_info);
+}
+Glib::SignalProxy0<void> browser_widget::signal_net_stop()
+{
+ return Glib::SignalProxy0<void>(this, &browser_widget_signal_net_stop_info);
+}
+Glib::SignalProxy1<browser_widget *, guint /*chromemask*/> browser_widget::signal_new_window()
+{
+ return Glib::SignalProxy1<browser_widget *, guint>(
+ this, &browser_widget_signal_new_window_info);
+}
+Glib::SignalProxy1<void, bool /*visibility*/> browser_widget::signal_visibility()
+{
+ return Glib::SignalProxy1<void, bool>(
+ this, &browser_widget_signal_visibility_info);
+}
+Glib::SignalProxy0<void> browser_widget::signal_destroy()
+{
+ return Glib::SignalProxy0<void>(this, &browser_widget_signal_destroy_info);
+}
+Glib::SignalProxy1<bool, const char * /*uri*/> browser_widget::signal_open_uri()
+{
+ return Glib::SignalProxy1<bool, const char *>(
+ this, &browser_widget_signal_open_uri_info);
+}
+
+browser_widget::browser_widget(GObject * gobject, bool take_copy)
+{
+ assert(GTK_MOZ_EMBED(gobject));
+ gobject_ = gobject;
+ if (take_copy)
+ reference();
+}
+Glib::ObjectBase * browser_widget::wrap_new(GObject * gobject)
+{
+ return new browser_widget(gobject, false);
+}
+
+browser_widget::initialiser::initialiser()
+{
+ gtk_moz_embed_set_comp_path(MOZ_LIB_DIR);
+ gtk_moz_embed_push_startup();
+
+ wrap_register(gtk_moz_embed_get_type(), wrap_new);
+}
+
+browser_widget::initialiser::~initialiser()
+{
+ gtk_moz_embed_pop_startup();
+}
+
+namespace Glib
+{
+ browser_widget * wrap(GtkMozEmbed * object, bool take_copy)
+ {
+ return dynamic_cast<browser_widget *>(
+ Glib::wrap_auto((GObject*)(object), take_copy));
+ }
+}