Renamed various types to fit lower_case_with_underscores convention.
authorBen Hutchings <ben@decadent.org.uk>
Tue, 20 Dec 2005 00:29:40 +0000 (00:29 +0000)
committerBen Hutchings <ben@decadent.org.uk>
Sun, 2 Nov 2008 23:39:54 +0000 (23:39 +0000)
Renamed FrameBuffer to the more specific x_frame_buffer and removed "x_" from its accessor function names.
Renamed files to match function/class names.

22 files changed:
Makefile
browser_widget.cpp [new file with mode: 0644]
browser_widget.hpp [new file with mode: 0644]
browserwidget.cpp [deleted file]
browserwidget.hpp [deleted file]
child_iterator.cpp [new file with mode: 0644]
child_iterator.hpp [new file with mode: 0644]
childiterator.cpp [deleted file]
childiterator.hpp [deleted file]
framebuffer.cpp [deleted file]
framebuffer.hpp [deleted file]
link_iterator.cpp [new file with mode: 0644]
link_iterator.hpp [new file with mode: 0644]
linkiterator.cpp [deleted file]
linkiterator.hpp [deleted file]
style_sheets.cpp [new file with mode: 0644]
style_sheets.hpp [new file with mode: 0644]
stylesheets.cpp [deleted file]
stylesheets.hpp [deleted file]
webdvd.cpp
x_frame_buffer.cpp [new file with mode: 0644]
x_frame_buffer.hpp [new file with mode: 0644]

index 989ef7d..caffd0f 100644 (file)
--- a/Makefile
+++ b/Makefile
@@ -31,9 +31,9 @@ else
 endif
 
 cxxsources := \
-    auto_proc.cpp browserwidget.cpp childiterator.cpp framebuffer.cpp \
-    linkiterator.cpp pixbufs.cpp stylesheets.cpp temp_file.cpp video.cpp \
-    webdvd.cpp xpcom_support.cpp
+    auto_proc.cpp browser_widget.cpp child_iterator.cpp                    \
+    link_iterator.cpp pixbufs.cpp style_sheets.cpp temp_file.cpp video.cpp \
+    webdvd.cpp x_frame_buffer.cpp xpcom_support.cpp
 csources := jquant2.c
 
 webdvd : $(cxxsources:.cpp=.o) $(csources:.c=.o)
@@ -52,7 +52,7 @@ install :
 
 .PHONY : clean distclean install
 
-browserwidget.% : CPPFLAGS += -DMOZ_LIB_DIR='"$(moz_lib_dir)"'
+browser_widget.% : CPPFLAGS += -DMOZ_LIB_DIR='"$(moz_lib_dir)"'
 
 webdvd.% \
     : CPPFLAGS += -DWEBDVD_LIB_DIR='"$(webdvd_lib_dir)"'             \
@@ -60,16 +60,16 @@ webdvd.% \
                   -DMOZ_VERSION_MINOR=$(moz_version_minor)           \
                   -DMOZ_VERSION_PATCHLEVEL=$(moz_version_patchlevel)
 
-browserwidget.% pixbufs.% temp_file.% webdvd.% \
+browser_widget.% pixbufs.% temp_file.% webdvd.% \
     : CPPFLAGS += $(shell pkg-config --cflags gtkmm-2.0)
 
-browserwidget.% childiterator.o linkiterator.% stylesheets.% webdvd.% \
-xpcom_support.%                                                       \
+browser_widget.% child_iterator.o link_iterator.% style_sheets.% webdvd.% \
+xpcom_support.%                                                           \
     : CPPFLAGS += $(shell pkg-config --cflags mozilla-gtkmozembed)
 
 # These dig a bit deeper into Mozilla
-linkiterator.% stylesheets.% webdvd.%                                        \
-    : CPPFLAGS += $(addprefix -I$(moz_include_dir)/,                         \
+link_iterator.% style_sheets.% webdvd.%                                    \
+    : CPPFLAGS += $(addprefix -I$(moz_include_dir)/,                       \
                     content docshell dom gfx layout necko webshell widget)
 
 %.d : %.cpp
diff --git a/browser_widget.cpp b/browser_widget.cpp
new file mode 100644 (file)
index 0000000..0f6b53d
--- /dev/null
@@ -0,0 +1,539 @@
+// 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));
+    }
+}
diff --git a/browser_widget.hpp b/browser_widget.hpp
new file mode 100644 (file)
index 0000000..16d3023
--- /dev/null
@@ -0,0 +1,73 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#ifndef INC_BROWSER_WIDGET_HPP
+#define INC_BROWSER_WIDGET_HPP
+
+#include <glibmm/signalproxy.h>
+#include <gtkmm/bin.h>
+
+#include <gtkmozembed.h>
+#include <nsCOMPtr.h>
+
+class browser_widget;
+class nsIWebBrowser;
+
+namespace Glib
+{
+    browser_widget * wrap(GtkMozEmbed * object, bool take_copy = false);
+}
+
+class browser_widget : public Gtk::Bin
+{
+public:
+    browser_widget();
+    virtual ~browser_widget();
+    GtkMozEmbed * gobj();
+    const GtkMozEmbed * gobj() const;
+
+    void load_uri(const char * uri);
+    void load_uri(const std::string & uri);
+    void stop_load();
+    void go_back();
+    void go_forward();
+    void reload(gint32 flags = GTK_MOZ_EMBED_FLAG_RELOADNORMAL);
+
+    bool can_go_back() const;
+    bool can_go_forward() const;
+
+    std::string get_link_message() const;
+    std::string get_js_status() const;
+    std::string get_title() const;
+    std::string get_location() const;
+    already_AddRefed<nsIWebBrowser> get_browser();
+
+    Glib::SignalProxy0<void> signal_link_message();
+    Glib::SignalProxy0<void> signal_js_status();
+    Glib::SignalProxy0<void> signal_location();
+    Glib::SignalProxy0<void> signal_title();
+    Glib::SignalProxy2<void, gint /*cur*/, gint /*max*/> signal_progress();
+    Glib::SignalProxy3<void, const char *, gint /*flags*/, guint /*status*/>
+       signal_net_state();
+    Glib::SignalProxy0<void> signal_net_start();
+    Glib::SignalProxy0<void> signal_net_stop();
+    Glib::SignalProxy1<browser_widget *, guint /*chromemask*/> signal_new_window();
+    Glib::SignalProxy1<void, bool /*visibility*/> signal_visibility();
+    Glib::SignalProxy0<void> signal_destroy();
+    Glib::SignalProxy1<bool, const char * /*uri*/> signal_open_uri();
+
+    // This must be instantiated after Gtk initialisation and before
+    // instantiation of browser_widget.
+    struct initialiser
+    {
+       initialiser();
+       ~initialiser();
+    };
+
+private:
+    browser_widget(GObject * gobject, bool take_copy);
+    static Glib::ObjectBase * wrap_new(GObject * gobject);
+    friend browser_widget * Glib::wrap(GtkMozEmbed * object, bool take_copy);
+};
+
+#endif // !INC_BROWSER_WIDGET_HPP
diff --git a/browserwidget.cpp b/browserwidget.cpp
deleted file mode 100644 (file)
index a2bed64..0000000
+++ /dev/null
@@ -1,539 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#include "browserwidget.hpp"
-
-#include <cassert>
-
-#include <gtkmozembed_internal.h>
-
-BrowserWidget::BrowserWidget()
-       : Gtk::Bin(GTK_BIN(gtk_moz_embed_new()))
-{
-}
-BrowserWidget::~BrowserWidget()
-{
-}
-
-GtkMozEmbed * BrowserWidget::gobj()
-{
-    return GTK_MOZ_EMBED(gobject_);
-}
-const GtkMozEmbed * BrowserWidget::gobj() const
-{
-    return GTK_MOZ_EMBED(gobject_);
-}
-
-void BrowserWidget::load_uri(const char * uri)
-{
-    gtk_moz_embed_load_url(gobj(), uri);
-}
-void BrowserWidget::load_uri(const std::string & uri)
-{
-    return load_uri(uri.c_str());
-}
-void BrowserWidget::stop_load()
-{
-    gtk_moz_embed_stop_load(gobj());
-}
-void BrowserWidget::go_back()
-{
-    gtk_moz_embed_go_back(gobj());
-}
-void BrowserWidget::go_forward()
-{
-    gtk_moz_embed_go_forward(gobj());
-}
-void BrowserWidget::reload(gint32 flags)
-{
-    gtk_moz_embed_reload(gobj(), flags);
-}
-
-bool BrowserWidget::can_go_back() const
-{
-    return gtk_moz_embed_can_go_back(const_cast<GtkMozEmbed *>(gobj()));
-}
-bool BrowserWidget::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 BrowserWidget::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 BrowserWidget::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 BrowserWidget::get_title() const
-{
-    c_scoped_ptr<char> str(
-       gtk_moz_embed_get_title(const_cast<GtkMozEmbed *>(gobj())));
-    return std::string(str.get());
-}
-std::string BrowserWidget::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> BrowserWidget::get_browser()
-{
-    nsIWebBrowser * result = 0;
-    gtk_moz_embed_get_nsIWebBrowser(gobj(), &result);
-    assert(result);
-    return dont_AddRef(result);
-}
-
-namespace
-{
-    void BrowserWidget_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 BrowserWidget_signal_link_message_info =
-    {
-       "link_message",
-       (GCallback) &BrowserWidget_signal_link_message_callback,
-       (GCallback) &BrowserWidget_signal_link_message_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_js_status_info =
-    {
-       "js_status",
-       (GCallback) &BrowserWidget_signal_js_status_callback,
-       (GCallback) &BrowserWidget_signal_js_status_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_location_info =
-    {
-       "location",
-       (GCallback) &BrowserWidget_signal_location_callback,
-       (GCallback) &BrowserWidget_signal_location_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_title_info =
-    {
-       "title",
-       (GCallback) &BrowserWidget_signal_title_callback,
-       (GCallback) &BrowserWidget_signal_title_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_progress_info =
-    {
-       "progress",
-       (GCallback) &BrowserWidget_signal_progress_callback,
-       (GCallback) &BrowserWidget_signal_progress_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_net_state_info =
-    {
-       "net_state_all",
-       (GCallback) &BrowserWidget_signal_net_state_callback,
-       (GCallback) &BrowserWidget_signal_net_state_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_net_start_info =
-    {
-       "net_start",
-       (GCallback) &BrowserWidget_signal_net_start_callback,
-       (GCallback) &BrowserWidget_signal_net_start_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_net_stop_info =
-    {
-       "net_stop",
-       (GCallback) &BrowserWidget_signal_net_stop_callback,
-       (GCallback) &BrowserWidget_signal_net_stop_callback
-    };
-
-    void BrowserWidget_signal_new_window_callback(
-       GtkMozEmbed * self, GtkMozEmbed ** p0, guint p1, void * data)
-    {
-       typedef SigC::Slot1<BrowserWidget *, guint> SlotType;
-
-       if (Glib::ObjectBase::_get_current_wrapper((GObject *)self))
-       {
-           try
-           {
-               if (SigC::SlotNode * const slot =
-                   Glib::SignalProxyNormal::data_to_slot(data))
-               {
-                   if (BrowserWidget * result =
-                       (*(SlotType::Proxy)(slot->proxy_))(p1, slot))
-                   {
-                       *p0 = result->gobj();
-                       return;
-                   }
-               }
-           }
-           catch(...)
-           {
-               Glib::exception_handlers_invoke();
-           }
-       }
-
-       *p0 = NULL;
-       return;
-    }
-
-    const Glib::SignalProxyInfo BrowserWidget_signal_new_window_info =
-    {
-       "new_window",
-       (GCallback) &BrowserWidget_signal_new_window_callback,
-       (GCallback) &BrowserWidget_signal_new_window_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_visibility_info =
-    {
-       "visibility",
-       (GCallback) &BrowserWidget_signal_visibility_callback,
-       (GCallback) &BrowserWidget_signal_visibility_callback
-    };
-
-    void BrowserWidget_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 BrowserWidget_signal_destroy_info =
-    {
-       "destroy_browser",
-       (GCallback) &BrowserWidget_signal_destroy_browser_callback,
-       (GCallback) &BrowserWidget_signal_destroy_browser_callback
-    };
-
-    gint BrowserWidget_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 BrowserWidget_signal_open_uri_info =
-    {
-       "open_uri",
-       (GCallback) &BrowserWidget_signal_open_uri_callback,
-       (GCallback) &BrowserWidget_signal_open_uri_callback
-    };
-
-} // namespace
-
-Glib::SignalProxy0<void> BrowserWidget::signal_link_message()
-{
-    return Glib::SignalProxy0<void>(this, &BrowserWidget_signal_link_message_info);
-}
-Glib::SignalProxy0<void> BrowserWidget::signal_js_status()
-{
-    return Glib::SignalProxy0<void>(this, &BrowserWidget_signal_js_status_info);
-}
-Glib::SignalProxy0<void> BrowserWidget::signal_location()
-{
-    return Glib::SignalProxy0<void>(this, &BrowserWidget_signal_location_info);
-}
-Glib::SignalProxy0<void> BrowserWidget::signal_title()
-{
-    return Glib::SignalProxy0<void>(this, &BrowserWidget_signal_title_info);
-}
-Glib::SignalProxy2<void, gint /*cur*/, gint /*max*/> BrowserWidget::signal_progress()
-{
-    return Glib::SignalProxy2<void, gint, gint>(
-       this, &BrowserWidget_signal_progress_info);
-}
-Glib::SignalProxy3<void, const char *, gint /*flags*/, guint /*status*/>
-BrowserWidget::signal_net_state()
-{
-    return Glib::SignalProxy3<void, const char *, gint, guint>(
-       this, &BrowserWidget_signal_net_state_info);
-}
-Glib::SignalProxy0<void> BrowserWidget::signal_net_start()
-{
-    return Glib::SignalProxy0<void>(this, &BrowserWidget_signal_net_start_info);
-}
-Glib::SignalProxy0<void> BrowserWidget::signal_net_stop()
-{
-    return Glib::SignalProxy0<void>(this, &BrowserWidget_signal_net_stop_info);
-}
-Glib::SignalProxy1<BrowserWidget *, guint /*chromemask*/> BrowserWidget::signal_new_window()
-{
-    return Glib::SignalProxy1<BrowserWidget *, guint>(
-       this, &BrowserWidget_signal_new_window_info);
-}
-Glib::SignalProxy1<void, bool /*visibility*/> BrowserWidget::signal_visibility()
-{
-    return Glib::SignalProxy1<void, bool>(
-       this, &BrowserWidget_signal_visibility_info);
-}
-Glib::SignalProxy0<void> BrowserWidget::signal_destroy()
-{
-    return Glib::SignalProxy0<void>(this, &BrowserWidget_signal_destroy_info);
-}
-Glib::SignalProxy1<bool, const char * /*uri*/> BrowserWidget::signal_open_uri()
-{
-    return Glib::SignalProxy1<bool, const char *>(
-       this, &BrowserWidget_signal_open_uri_info);
-}
-
-BrowserWidget::BrowserWidget(GObject * gobject, bool take_copy)
-{
-    assert(GTK_MOZ_EMBED(gobject));
-    gobject_ = gobject;
-    if (take_copy)
-       reference();
-}
-Glib::ObjectBase * BrowserWidget::wrap_new(GObject * gobject)
-{
-    return new BrowserWidget(gobject, false);
-}
-
-BrowserWidget::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);
-}
-
-BrowserWidget::Initialiser::~Initialiser()
-{
-    gtk_moz_embed_pop_startup();
-}
-
-namespace Glib
-{
-    BrowserWidget * wrap(GtkMozEmbed * object, bool take_copy)
-    {
-       return dynamic_cast<BrowserWidget *>(
-           Glib::wrap_auto((GObject*)(object), take_copy));
-    }
-}
diff --git a/browserwidget.hpp b/browserwidget.hpp
deleted file mode 100644 (file)
index 2cfc1d7..0000000
+++ /dev/null
@@ -1,73 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#ifndef INC_BROWSERWIDGET_HPP
-#define INC_BROWSERWIDGET_HPP
-
-#include <glibmm/signalproxy.h>
-#include <gtkmm/bin.h>
-
-#include <gtkmozembed.h>
-#include <nsCOMPtr.h>
-
-class BrowserWidget;
-class nsIWebBrowser;
-
-namespace Glib
-{
-    BrowserWidget * wrap(GtkMozEmbed * object, bool take_copy = false);
-}
-
-class BrowserWidget : public Gtk::Bin
-{
-public:
-    BrowserWidget();
-    virtual ~BrowserWidget();
-    GtkMozEmbed * gobj();
-    const GtkMozEmbed * gobj() const;
-
-    void load_uri(const char * uri);
-    void load_uri(const std::string & uri);
-    void stop_load();
-    void go_back();
-    void go_forward();
-    void reload(gint32 flags = GTK_MOZ_EMBED_FLAG_RELOADNORMAL);
-
-    bool can_go_back() const;
-    bool can_go_forward() const;
-
-    std::string get_link_message() const;
-    std::string get_js_status() const;
-    std::string get_title() const;
-    std::string get_location() const;
-    already_AddRefed<nsIWebBrowser> get_browser();
-
-    Glib::SignalProxy0<void> signal_link_message();
-    Glib::SignalProxy0<void> signal_js_status();
-    Glib::SignalProxy0<void> signal_location();
-    Glib::SignalProxy0<void> signal_title();
-    Glib::SignalProxy2<void, gint /*cur*/, gint /*max*/> signal_progress();
-    Glib::SignalProxy3<void, const char *, gint /*flags*/, guint /*status*/>
-       signal_net_state();
-    Glib::SignalProxy0<void> signal_net_start();
-    Glib::SignalProxy0<void> signal_net_stop();
-    Glib::SignalProxy1<BrowserWidget *, guint /*chromemask*/> signal_new_window();
-    Glib::SignalProxy1<void, bool /*visibility*/> signal_visibility();
-    Glib::SignalProxy0<void> signal_destroy();
-    Glib::SignalProxy1<bool, const char * /*uri*/> signal_open_uri();
-
-    // This must be instantiated after Gtk initialisation and before
-    // instantiation of BrowserWidget.
-    struct Initialiser
-    {
-       Initialiser();
-       ~Initialiser();
-    };
-
-private:
-    BrowserWidget(GObject * gobject, bool take_copy);
-    static Glib::ObjectBase * wrap_new(GObject * gobject);
-    friend BrowserWidget * Glib::wrap(GtkMozEmbed * object, bool take_copy);
-};
-
-#endif // !INC_BROWSERWIDGET_HPP
diff --git a/child_iterator.cpp b/child_iterator.cpp
new file mode 100644 (file)
index 0000000..d6e708e
--- /dev/null
@@ -0,0 +1,46 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#include "child_iterator.hpp"
+
+#include <cassert>
+
+#include "xpcom_support.hpp"
+
+using xpcom_support::check;
+
+child_iterator::child_iterator()
+       : node_(0)
+{}
+
+child_iterator::child_iterator(nsIDOMNode * node)
+{
+    check(node->GetFirstChild(&node_));
+}
+
+child_iterator::~child_iterator()
+{
+    if (node_)
+       node_->Release();
+}
+
+already_AddRefed<nsIDOMNode> child_iterator::operator*() const
+{
+    assert(node_);
+    node_->AddRef();
+    return node_;
+}
+
+child_iterator & child_iterator::operator++()
+{
+    nsIDOMNode * next;
+    check(node_->GetNextSibling(&next));
+    node_->Release();
+    node_ = next;
+    return *this;
+}
+
+bool child_iterator::operator==(const child_iterator & other) const
+{
+    return node_ == other.node_;
+}
diff --git a/child_iterator.hpp b/child_iterator.hpp
new file mode 100644 (file)
index 0000000..e099676
--- /dev/null
@@ -0,0 +1,33 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#ifndef INC_CHILD_ITERATOR_HPP
+#define INC_CHILD_ITERATOR_HPP
+
+#include <iterator>
+
+#include <nsCOMPtr.h>
+#include <nsIDOMNode.h>
+
+class child_iterator
+    : public std::iterator<std::input_iterator_tag, nsCOMPtr<nsIDOMNode>,
+                          void, void, void>
+{
+public:
+    child_iterator();
+    explicit child_iterator(nsIDOMNode * node);
+    ~child_iterator();
+
+    already_AddRefed<nsIDOMNode> operator*() const;
+    child_iterator & operator++();
+    bool operator==(const child_iterator &) const;
+    bool operator!=(const child_iterator & other) const
+       {
+           return !(*this == other);
+       }
+
+private:
+    nsIDOMNode * node_;
+};
+
+#endif // !INC_CHILD_ITERATOR_HPP
diff --git a/childiterator.cpp b/childiterator.cpp
deleted file mode 100644 (file)
index 285b4a8..0000000
+++ /dev/null
@@ -1,46 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#include "childiterator.hpp"
-
-#include <cassert>
-
-#include "xpcom_support.hpp"
-
-using xpcom_support::check;
-
-ChildIterator::ChildIterator()
-       : node_(0)
-{}
-
-ChildIterator::ChildIterator(nsIDOMNode * node)
-{
-    check(node->GetFirstChild(&node_));
-}
-
-ChildIterator::~ChildIterator()
-{
-    if (node_)
-       node_->Release();
-}
-
-already_AddRefed<nsIDOMNode> ChildIterator::operator*() const
-{
-    assert(node_);
-    node_->AddRef();
-    return node_;
-}
-
-ChildIterator & ChildIterator::operator++()
-{
-    nsIDOMNode * next;
-    check(node_->GetNextSibling(&next));
-    node_->Release();
-    node_ = next;
-    return *this;
-}
-
-bool ChildIterator::operator==(const ChildIterator & other) const
-{
-    return node_ == other.node_;
-}
diff --git a/childiterator.hpp b/childiterator.hpp
deleted file mode 100644 (file)
index edc937c..0000000
+++ /dev/null
@@ -1,33 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#ifndef INC_CHILDITERATOR_HPP
-#define INC_CHILDITERATOR_HPP
-
-#include <iterator>
-
-#include <nsCOMPtr.h>
-#include <nsIDOMNode.h>
-
-class ChildIterator
-    : public std::iterator<std::input_iterator_tag, nsCOMPtr<nsIDOMNode>,
-                          void, void, void>
-{
-public:
-    ChildIterator();
-    explicit ChildIterator(nsIDOMNode * node);
-    ~ChildIterator();
-
-    already_AddRefed<nsIDOMNode> operator*() const;
-    ChildIterator & operator++();
-    bool operator==(const ChildIterator &) const;
-    bool operator!=(const ChildIterator & other) const
-       {
-           return !(*this == other);
-       }
-
-private:
-    nsIDOMNode * node_;
-};
-
-#endif // !INC_CHILDITERATOR_HPP
diff --git a/framebuffer.cpp b/framebuffer.cpp
deleted file mode 100644 (file)
index 2ae42cd..0000000
+++ /dev/null
@@ -1,265 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#include "framebuffer.hpp"
-
-#include <cassert>
-#include <cstdio>
-#include <cstring>
-#include <stdexcept>
-
-#include <sys/types.h>
-#include <errno.h>
-#include <fcntl.h>
-#include <netdb.h>
-#include <sys/socket.h>
-#include <sys/stat.h>
-#include <sys/utsname.h>
-#include <unistd.h>
-#include <wait.h>
-
-#include "auto_fd.hpp"
-#include "auto_handle.hpp"
-#include "temp_file.hpp"
-
-namespace
-{
-    struct addrinfo_factory
-    {
-       addrinfo * operator()() const { return NULL; }
-    };
-    struct addrinfo_closer
-    {
-       void operator()(addrinfo * addr_list) const
-           {
-               if (addr_list)
-                   freeaddrinfo(addr_list);
-           }
-    };
-    typedef auto_handle<addrinfo *, addrinfo_closer, addrinfo_factory>
-        auto_addrinfo;
-
-    int select_display_num(auto_fd & tcp4_socket, auto_fd & tcp6_socket)
-    {
-       // Minimum and maximum display numbers to use.  Xvnc and ssh's
-       // proxies start at 10, so we'll follow that convention.  We
-       // have to put a limit on iteration somewhere, and 100
-       // displays seems rather excessive so we'll stop there.
-       const int min_display_num = 10;
-       const int max_display_num = 99;
-
-       for (int display_num = min_display_num;
-            display_num <= max_display_num;
-            ++display_num)
-       {
-           // Check that there's no lock file for the local socket
-           // for this display.  We could also check for stale locks,
-           // but this will probably do.
-           char lock_file_name[20];
-           std::sprintf(lock_file_name, "/tmp/.X%d-lock", display_num);
-           if (!(access(lock_file_name, 0) == -1 && errno == ENOENT))
-               continue;
-
-           // Attempt to create TCP socket(s) and bind them to the
-           // appropriate port number.  We won't set the X server to
-           // listen on a TCP socket but this does ensure that ssh
-           // isn't using and won't use this display number.  This is
-           // roughly based on the x11_create_display_inet function
-           // in OpenSSH.
-
-           auto_addrinfo addr_list;
-
-           {
-               addrinfo hints = {};
-               hints.ai_family = AF_UNSPEC;
-               hints.ai_socktype = SOCK_STREAM;
-               char port_str[5 + 1];
-               std::sprintf(port_str, "%d", 6000 + display_num);
-               addrinfo * addr_list_temp;
-               int error = getaddrinfo(NULL, port_str, &hints,
-                                            &addr_list_temp);
-               if (error != 0)
-                   throw std::runtime_error(
-                       std::string("getaddrinfo: ")
-                       .append(gai_strerror(error)));
-               addr_list.reset(addr_list_temp);
-           }
-
-           const addrinfo * addr;
-
-           for (addr = addr_list.get(); addr != NULL; addr = addr->ai_next)
-           {
-               // We're only interested in TCPv4 and TCPv6.
-               if (addr->ai_family != AF_INET && addr->ai_family != AF_INET6)
-                   continue;
-               auto_fd & tcp_socket =
-                   (addr->ai_family == AF_INET) ? tcp4_socket : tcp6_socket;
-
-               tcp_socket.reset(socket(addr->ai_family,
-                                       SOCK_STREAM,
-                                       addr->ai_protocol));
-               if (tcp_socket.get() < 0)
-               {
-                   // If the family is unsupported, no-one can bind
-                   // to this address, so this is not a problem.
-                   if (errno == EAFNOSUPPORT
-#                      ifdef EPFNOSUPPORT
-                       || errno == EPFNOSUPPORT
-#                      endif
-                       )
-                       continue;
-                   throw std::runtime_error(
-                       std::string("socket: ").append(strerror(errno)));
-               }
-
-               // Don't let TCPv6 sockets interfere with TCPv4 sockets.
-#              ifdef IPV6_V6ONLY
-               if (addr->ai_family == AF_INET6)
-               {
-                   int on = 1;
-                   if (setsockopt(tcp_socket.get(), IPPROTO_IPV6, IPV6_V6ONLY,
-                                  &on, sizeof(on)) != 0)
-                   {
-                       throw std::runtime_error(
-                           std::string("setsockopt IPV6_V6ONLY: ")
-                           .append(strerror(errno)));
-                   }
-               }
-#              endif
-
-               if (bind(tcp_socket.get(), addr->ai_addr, addr->ai_addrlen)
-                   != 0)
-                   break;
-           }
-
-           // If we reached the end of the address list, we've
-           // successfully bound to all appropriate addresses for
-           // this display number, so we can use it.
-           if (addr == NULL)
-               return display_num;
-       }
-
-       throw std::runtime_error("did not find a free X display");
-    }
-
-    void get_random_bytes(unsigned char * buf, int len)
-    {
-       assert(len > 0);
-       auto_fd random_fd(open("/dev/urandom", O_RDONLY));
-       if (random_fd.get() == -1 || read(random_fd.get(), buf, len) != len)
-           throw std::runtime_error(std::strerror(errno));
-    }
-
-    std::auto_ptr<temp_file> create_temp_auth_file(int display_num)
-    {
-       std::auto_ptr<temp_file> auth_file(new temp_file("Xvfb-auth-"));
-
-       // An xauth entry consists of the following fields.  All u16 fields
-       // are big-endian and unaligned.  Character arrays are not null-
-       // terminated.
-       // u16     address family (= 256 for local socket)
-       // u16     length of address
-       // char[]  address (= hostname)
-       // u16     length of display number
-       // char[]  display number
-       // u16     auth type name length
-       // char[]  auth type name (= "MIT-MAGIC-COOKIE-1")
-       // u16     length of auth data (= 16)
-       // char[]  auth data (= random bytes)
-       uint16_t family = htons(0x100);
-       write(auth_file->get_fd(), &family, sizeof(family));
-       utsname my_uname;
-       uname(&my_uname);
-       uint16_t len = htons(strlen(my_uname.nodename));
-       write(auth_file->get_fd(), &len, sizeof(len));
-       write(auth_file->get_fd(),
-             my_uname.nodename, strlen(my_uname.nodename));
-       char display[15];
-       std::sprintf(display, "%d", display_num);
-       len = htons(strlen(display));
-       write(auth_file->get_fd(), &len, sizeof(len));
-       write(auth_file->get_fd(), display, strlen(display));
-       static const char auth_type[] = "MIT-MAGIC-COOKIE-1";
-       len = htons(sizeof(auth_type) - 1);
-       write(auth_file->get_fd(), &len, sizeof(len));
-       write(auth_file->get_fd(), auth_type, sizeof(auth_type) - 1);
-       unsigned char auth_key[16];
-       get_random_bytes(auth_key, sizeof(auth_key));
-       len = htons(sizeof(auth_key));
-       write(auth_file->get_fd(), &len, sizeof(len));
-       write(auth_file->get_fd(), auth_key, sizeof(auth_key));
-
-       return auth_file;
-    }
-
-    // Run the X server with the specified auth file, dimensions and
-    // assigned display number.
-    auto_kill_proc spawn_x_server(int display_num,
-                                 const std::string & auth_file_name,
-                                 int width, int height, int depth)
-    {
-       char display[15];
-       std::sprintf(display, ":%d", display_num);
-       const char * auth_file_c_str = auth_file_name.c_str();
-       std::fflush(NULL);
-       auto_kill_proc server_proc(fork());
-       if (server_proc.get() == -1)
-           throw std::runtime_error(std::strerror(errno));
-
-       if (server_proc.get() == 0)
-       {
-           char dimensions[40];
-           std::sprintf(dimensions, "%dx%dx%d", width, height, depth);
-           execlp("Xvfb",
-                  "Xvfb",
-                  "-auth", auth_file_c_str,
-                  "-nolisten", "tcp",
-                  "-screen", "0", dimensions,
-                  "-terminate",
-                  display,
-                  NULL);
-           _exit(128 + errno);
-       }
-
-       // Wait for the lock file to appear or the server to exit.  We can't
-       // really wait on both of these, so poll at 1-second intervals.
-       char lock_file_name[20];
-       std::sprintf(lock_file_name, "/tmp/.X%d-lock", display_num);
-       for (;;)
-       {
-           if (access(lock_file_name, 0) == 0)
-               break;
-           if (errno != ENOENT) // huh?
-               throw std::runtime_error(std::strerror(errno));
-           if (waitpid(server_proc.get(), NULL, WNOHANG) == server_proc.get())
-           {
-               server_proc.release(); // pid is now invalid
-               // TODO: Get the exit status and decode it properly.
-               throw std::runtime_error("X server failed to create display");
-           }
-           sleep(1);
-       }
-
-       return server_proc;
-    }
-}
-
-FrameBuffer::FrameBuffer(int width, int height, int depth)
-       : display_num_(select_display_num(tcp4_socket_, tcp6_socket_)),
-         auth_file_(create_temp_auth_file(display_num_)),
-         server_proc_(spawn_x_server(display_num_,
-                                     get_x_authority(),
-                                     width, height, depth))
-{}
-
-std::string FrameBuffer::get_x_authority() const
-{
-    return auth_file_->get_name();
-}
-
-std::string FrameBuffer::get_x_display() const
-{
-    char display[15];
-    std::sprintf(display, ":%d", display_num_);
-    return display;
-}
diff --git a/framebuffer.hpp b/framebuffer.hpp
deleted file mode 100644 (file)
index 3e49875..0000000
+++ /dev/null
@@ -1,29 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#ifndef INC_FRAMEBUFFER_HPP
-#define INC_FRAMEBUFFER_HPP
-
-#include <memory>
-#include <string>
-
-#include "auto_fd.hpp"
-#include "auto_proc.hpp"
-#include "temp_file.hpp"
-
-// Run Xvfb with a frame buffer of the given dimensions.
-class FrameBuffer
-{
-public:
-    FrameBuffer(int width, int height, int depth);
-    std::string get_x_authority() const;
-    std::string get_x_display() const;
-
-private:
-    auto_fd tcp4_socket_, tcp6_socket_;
-    int display_num_;
-    std::auto_ptr<temp_file> auth_file_;
-    auto_kill_proc server_proc_;
-};
-
-#endif // !INC_FRAMEBUFFER_HPP
diff --git a/link_iterator.cpp b/link_iterator.cpp
new file mode 100644 (file)
index 0000000..20d4b4c
--- /dev/null
@@ -0,0 +1,52 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#include "link_iterator.hpp"
+
+#include <cassert>
+
+#include <nsIDOMHTMLCollection.h>
+#include <nsIDOMHTMLDocument.h>
+
+link_iterator::link_iterator()
+{}
+
+link_iterator::link_iterator(nsIDOMDocument * document)
+{
+    nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(document));
+    if (!htmlDoc)
+       return;
+
+    htmlDoc->GetLinks(getter_AddRefs(collection_));
+    assert(collection_);
+
+    index_ = 0;
+    length_ = 0;
+    collection_->GetLength(&length_);
+    if (length_ == 0)
+       collection_ = 0;
+}
+
+already_AddRefed<nsIDOMNode> link_iterator::operator*() const
+{
+    assert(collection_);
+    nsIDOMNode * result = 0;
+    collection_->Item(index_, &result);
+    assert(result);
+    return dont_AddRef(result);
+}
+
+link_iterator & link_iterator::operator++()
+{
+    assert(collection_);
+    ++index_;
+    if (index_ == length_)
+       collection_ = 0;
+    return *this;
+}
+
+bool link_iterator::operator==(const link_iterator & other) const
+{
+    return (collection_ == other.collection_
+           && (!collection_ || index_ == other.index_));
+}
diff --git a/link_iterator.hpp b/link_iterator.hpp
new file mode 100644 (file)
index 0000000..d2b7a1a
--- /dev/null
@@ -0,0 +1,36 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#ifndef INC_LINK_ITERATOR_HPP
+#define INC_LINK_ITERATOR_HPP
+
+#include <iterator>
+
+#include <nsCOMPtr.h>
+#include <nsIDOMHTMLCollection.h>
+#include <nsIDOMNode.h>
+
+class nsIDOMDocument;
+
+class link_iterator
+    : public std::iterator<std::input_iterator_tag, nsCOMPtr<nsIDOMNode>,
+                          void, void, void>
+{
+public:
+    link_iterator();
+    explicit link_iterator(nsIDOMDocument * document);
+
+    already_AddRefed<nsIDOMNode> operator*() const;
+    link_iterator & operator++();
+    bool operator==(const link_iterator &) const;
+    bool operator!=(const link_iterator & other) const
+       {
+           return !(*this == other);
+       }
+
+private:
+    nsCOMPtr<nsIDOMHTMLCollection> collection_;
+    unsigned int index_, length_;
+};
+
+#endif // !INC_LINK_ITERATOR_HPP
diff --git a/linkiterator.cpp b/linkiterator.cpp
deleted file mode 100644 (file)
index b751c1d..0000000
+++ /dev/null
@@ -1,52 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#include "linkiterator.hpp"
-
-#include <cassert>
-
-#include <nsIDOMHTMLCollection.h>
-#include <nsIDOMHTMLDocument.h>
-
-LinkIterator::LinkIterator()
-{}
-
-LinkIterator::LinkIterator(nsIDOMDocument * document)
-{
-    nsCOMPtr<nsIDOMHTMLDocument> htmlDoc(do_QueryInterface(document));
-    if (!htmlDoc)
-       return;
-
-    htmlDoc->GetLinks(getter_AddRefs(collection_));
-    assert(collection_);
-
-    index_ = 0;
-    length_ = 0;
-    collection_->GetLength(&length_);
-    if (length_ == 0)
-       collection_ = 0;
-}
-
-already_AddRefed<nsIDOMNode> LinkIterator::operator*() const
-{
-    assert(collection_);
-    nsIDOMNode * result = 0;
-    collection_->Item(index_, &result);
-    assert(result);
-    return dont_AddRef(result);
-}
-
-LinkIterator & LinkIterator::operator++()
-{
-    assert(collection_);
-    ++index_;
-    if (index_ == length_)
-       collection_ = 0;
-    return *this;
-}
-
-bool LinkIterator::operator==(const LinkIterator & other) const
-{
-    return (collection_ == other.collection_
-           && (!collection_ || index_ == other.index_));
-}
diff --git a/linkiterator.hpp b/linkiterator.hpp
deleted file mode 100644 (file)
index 2f93a2f..0000000
+++ /dev/null
@@ -1,36 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#ifndef INC_LINKITERATOR_HPP
-#define INC_LINKITERATOR_HPP
-
-#include <iterator>
-
-#include <nsCOMPtr.h>
-#include <nsIDOMHTMLCollection.h>
-#include <nsIDOMNode.h>
-
-class nsIDOMDocument;
-
-class LinkIterator
-    : public std::iterator<std::input_iterator_tag, nsCOMPtr<nsIDOMNode>,
-                          void, void, void>
-{
-public:
-    LinkIterator();
-    explicit LinkIterator(nsIDOMDocument * document);
-
-    already_AddRefed<nsIDOMNode> operator*() const;
-    LinkIterator & operator++();
-    bool operator==(const LinkIterator &) const;
-    bool operator!=(const LinkIterator & other) const
-       {
-           return !(*this == other);
-       }
-
-private:
-    nsCOMPtr<nsIDOMHTMLCollection> collection_;
-    unsigned int index_, length_;
-};
-
-#endif // !INC_LINKITERATOR_HPP
diff --git a/style_sheets.cpp b/style_sheets.cpp
new file mode 100644 (file)
index 0000000..5767800
--- /dev/null
@@ -0,0 +1,50 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#include "style_sheets.hpp"
+
+#include <nsContentCID.h>
+#include <nsICSSLoader.h>
+#include <nsICSSStyleSheet.h>
+#include <nsIPresShell.h>
+#include <nsIServiceManagerUtils.h>
+#include <nsIURI.h>
+#include <nsNetUtil.h>
+
+#include "xpcom_support.hpp"
+
+using xpcom_support::check;
+
+// Load a CSS from an (absolute) URI.
+// TODO: Support loading from an absolute, or better, relative filename.
+already_AddRefed<nsIStyleSheet> load_css(const char * uri)
+{
+    nsCOMPtr<nsICSSLoader> css_loader;
+    static const nsCID css_loader_cid = NS_CSS_LOADER_CID;
+    check(CallGetService<nsICSSLoader>(css_loader_cid,
+                                      getter_AddRefs(css_loader)));
+
+    nsCOMPtr<nsIURI> style_sheet_uri;
+    check(NS_NewURI(getter_AddRefs(style_sheet_uri), nsCString(uri)));
+
+    nsICSSStyleSheet * style_sheet;
+    check(css_loader->LoadAgentSheet(style_sheet_uri, &style_sheet));
+    return style_sheet;
+}
+
+// Apply a style-sheet to a given presentation shell as the top-priority
+// agent style-sheet and disable the preferences-derived style rules.
+void apply_style_sheet(nsIStyleSheet * style_sheet, nsIPresShell * pres_shell)
+{
+    nsCOMArray<nsIStyleSheet> style_sheets;
+    check(pres_shell->GetAgentStyleSheets(style_sheets));
+    check(style_sheets.InsertObjectAt(style_sheet, 0));
+    check(pres_shell->SetAgentStyleSheets(style_sheets));
+
+    check(pres_shell->EnablePrefStyleRules(false));
+
+    // Update the display
+    check(pres_shell->ReconstructStyleData());
+    check(pres_shell->FlushPendingNotifications(true));
+}
+
diff --git a/style_sheets.hpp b/style_sheets.hpp
new file mode 100644 (file)
index 0000000..aa9d942
--- /dev/null
@@ -0,0 +1,20 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#ifndef INC_STYLESHEETS_HPP
+#define INC_STYLESHEETS_HPP
+
+#include <nsCOMPtr.h>
+#include <nsIStyleSheet.h>
+
+class nsIPresShell;
+
+// Load a CSS from an (absolute) URI.
+// TODO: Support loading from an absolute, or better, relative filename.
+already_AddRefed<nsIStyleSheet> load_css(const char * uri);
+
+// Apply a style-sheet to a given presentation shell as the top-priority
+// agent style-sheet and disable the preferences-derived style rules.
+void apply_style_sheet(nsIStyleSheet *, nsIPresShell *);
+
+#endif // !INC_STYLESHEETS_HPP
diff --git a/stylesheets.cpp b/stylesheets.cpp
deleted file mode 100644 (file)
index aa34643..0000000
+++ /dev/null
@@ -1,50 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#include "stylesheets.hpp"
-
-#include <nsContentCID.h>
-#include <nsICSSLoader.h>
-#include <nsICSSStyleSheet.h>
-#include <nsIPresShell.h>
-#include <nsIServiceManagerUtils.h>
-#include <nsIURI.h>
-#include <nsNetUtil.h>
-
-#include "xpcom_support.hpp"
-
-using xpcom_support::check;
-
-// Load a CSS from an (absolute) URI.
-// TODO: Support loading from an absolute, or better, relative filename.
-already_AddRefed<nsIStyleSheet> load_css(const char * uri)
-{
-    nsCOMPtr<nsICSSLoader> css_loader;
-    static const nsCID css_loader_cid = NS_CSS_LOADER_CID;
-    check(CallGetService<nsICSSLoader>(css_loader_cid,
-                                      getter_AddRefs(css_loader)));
-
-    nsCOMPtr<nsIURI> style_sheet_uri;
-    check(NS_NewURI(getter_AddRefs(style_sheet_uri), nsCString(uri)));
-
-    nsICSSStyleSheet * style_sheet;
-    check(css_loader->LoadAgentSheet(style_sheet_uri, &style_sheet));
-    return style_sheet;
-}
-
-// Apply a style-sheet to a given presentation shell as the top-priority
-// agent style-sheet and disable the preferences-derived style rules.
-void apply_style_sheet(nsIStyleSheet * style_sheet, nsIPresShell * pres_shell)
-{
-    nsCOMArray<nsIStyleSheet> style_sheets;
-    check(pres_shell->GetAgentStyleSheets(style_sheets));
-    check(style_sheets.InsertObjectAt(style_sheet, 0));
-    check(pres_shell->SetAgentStyleSheets(style_sheets));
-
-    check(pres_shell->EnablePrefStyleRules(false));
-
-    // Update the display
-    check(pres_shell->ReconstructStyleData());
-    check(pres_shell->FlushPendingNotifications(true));
-}
-
diff --git a/stylesheets.hpp b/stylesheets.hpp
deleted file mode 100644 (file)
index aa9d942..0000000
+++ /dev/null
@@ -1,20 +0,0 @@
-// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
-// See the file "COPYING" for licence details.
-
-#ifndef INC_STYLESHEETS_HPP
-#define INC_STYLESHEETS_HPP
-
-#include <nsCOMPtr.h>
-#include <nsIStyleSheet.h>
-
-class nsIPresShell;
-
-// Load a CSS from an (absolute) URI.
-// TODO: Support loading from an absolute, or better, relative filename.
-already_AddRefed<nsIStyleSheet> load_css(const char * uri);
-
-// Apply a style-sheet to a given presentation shell as the top-priority
-// agent style-sheet and disable the preferences-derived style rules.
-void apply_style_sheet(nsIStyleSheet *, nsIPresShell *);
-
-#endif // !INC_STYLESHEETS_HPP
index 5eca6c8..9a5dd04 100644 (file)
 #include <nsIWebBrowser.h>
 #include <nsString.h>
 
-#include "browserwidget.hpp"
-#include "childiterator.hpp"
+#include "browser_widget.hpp"
+#include "child_iterator.hpp"
 #include "dvd.hpp"
-#include "framebuffer.hpp"
-#include "linkiterator.hpp"
+#include "link_iterator.hpp"
 #include "pixbufs.hpp"
-#include "stylesheets.hpp"
+#include "style_sheets.hpp"
 #include "temp_file.hpp"
 #include "video.hpp"
+#include "x_frame_buffer.hpp"
 #include "xpcom_support.hpp"
 
 using xpcom_support::check;
@@ -126,7 +126,7 @@ namespace
        result.bottom = result.top + height;
 
        // Merge bounding boxes of all child elements
-       for (ChildIterator it = ChildIterator(elem), end; it != end; ++it)
+       for (child_iterator it = child_iterator(elem), end; it != end; ++it)
        {
            nsCOMPtr<nsIDOMNode> child_node(*it);
            PRUint16 child_type;
@@ -142,10 +142,10 @@ namespace
        return result;
     }
 
-    class WebDvdWindow : public Gtk::Window
+    class webdvd_window : public Gtk::Window
     {
     public:
-       WebDvdWindow(
+       webdvd_window(
            const video::frame_params & frame_params,
            const std::string & main_page_uri,
            const std::string & output_dir);
@@ -162,14 +162,14 @@ namespace
                           nsIDOMWindow * dom_window);
        void generate_dvd();
 
-       enum ResourceType { page_resource, video_resource };
-       typedef std::pair<ResourceType, int> ResourceEntry;
+       enum resource_type { page_resource, video_resource };
+       typedef std::pair<resource_type, int> resource_entry;
        video::frame_params frame_params_;
        std::string output_dir_;
-       BrowserWidget browser_widget_;
+       browser_widget browser_widget_;
        nsCOMPtr<nsIStyleSheet> stylesheet_;
        std::queue<std::string> page_queue_;
-       std::map<std::string, ResourceEntry> resource_map_;
+       std::map<std::string, resource_entry> resource_map_;
        std::vector<std::vector<std::string> > page_links_;
        std::vector<std::string> video_paths_;
        bool pending_window_update_;
@@ -181,7 +181,7 @@ namespace
        std::vector<boost::shared_ptr<temp_file> > page_temp_files_;
     };
 
-    WebDvdWindow::WebDvdWindow(
+    webdvd_window::webdvd_window(
        const video::frame_params & frame_params,
        const std::string & main_page_uri,
        const std::string & output_dir)
@@ -198,27 +198,27 @@ namespace
        add(browser_widget_);
        browser_widget_.show();
        browser_widget_.signal_net_state().connect(
-           SigC::slot(*this, &WebDvdWindow::on_net_state_change));
+           SigC::slot(*this, &webdvd_window::on_net_state_change));
 
        add_page(main_page_uri);
        load_next_page();
     }
 
-    void WebDvdWindow::add_page(const std::string & uri)
+    void webdvd_window::add_page(const std::string & uri)
     {
        if (resource_map_.insert(
-               std::make_pair(uri, ResourceEntry(page_resource, 0)))
+               std::make_pair(uri, resource_entry(page_resource, 0)))
            .second)
        {
            page_queue_.push(uri);
        }
     }
 
-    void WebDvdWindow::add_video(const std::string & uri)
+    void webdvd_window::add_video(const std::string & uri)
     {
        if (resource_map_.insert(
-               std::make_pair(uri, ResourceEntry(video_resource,
-                                                 video_paths_.size() + 1)))
+               std::make_pair(uri, resource_entry(video_resource,
+                                                  video_paths_.size() + 1)))
            .second)
        {
            Glib::ustring hostname;
@@ -231,7 +231,7 @@ namespace
        }
     }
 
-    void WebDvdWindow::load_next_page()
+    void webdvd_window::load_next_page()
     {
        assert(!page_queue_.empty());
        const std::string & uri = page_queue_.front();
@@ -244,11 +244,11 @@ namespace
        browser_widget_.load_uri(uri);
     }
 
-    void WebDvdWindow::on_net_state_change(const char * uri,
+    void webdvd_window::on_net_state_change(const char * uri,
                                           gint flags, guint status)
     {
 #       ifdef DEBUG_ON_NET_STATE_CHANGE
-       std::cout << "WebDvdWindow::on_net_state_change(";
+       std::cout << "webdvd_window::on_net_state_change(";
        if (uri)
            std::cout << '"' << uri << '"';
        else
@@ -335,7 +335,7 @@ namespace
        }
     }
 
-    bool WebDvdWindow::process_page()
+    bool webdvd_window::process_page()
     {
        assert(!page_queue_.empty());
 
@@ -399,7 +399,7 @@ namespace
        return true;
     }
 
-    void WebDvdWindow::save_screenshot()
+    void webdvd_window::save_screenshot()
     {
        Glib::RefPtr<Gdk::Window> window(get_window());
        assert(window);
@@ -415,7 +415,7 @@ namespace
            ->save(background_temp_->get_name(), "png");
     }
 
-    struct WebDvdWindow::page_state
+    struct webdvd_window::page_state
     {
        page_state(nsIDOMDocument * doc, int width, int height)
                : diff_pixbuf(Gdk::Pixbuf::create(
@@ -440,14 +440,14 @@ namespace
        temp_file links_temp;
 
        int link_num;
-       LinkIterator links_it, links_end;
+       link_iterator links_it, links_end;
 
        rectangle link_rect;
        bool link_changing;
        Glib::RefPtr<Gdk::Pixbuf> norm_pixbuf;
     };
 
-    void WebDvdWindow::process_links(nsIPresShell * pres_shell,
+    void webdvd_window::process_links(nsIPresShell * pres_shell,
                                     nsIPresContext * pres_context,
                                     nsIDOMWindow * dom_window)
     {
@@ -707,7 +707,7 @@ namespace
     void generate_page_dispatch(std::ostream &, int indent,
                                int first_page, int last_page);
 
-    void WebDvdWindow::generate_dvd()
+    void webdvd_window::generate_dvd()
     {
        temp_file temp("webdvd-dvdauthor-");
        temp.close();
@@ -818,7 +818,7 @@ namespace
                    " g1 = " << link_num * link_mult + page_num << ";";
 
                // Jump to appropriate resource.
-               const ResourceEntry & resource_loc =
+               const resource_entry & resource_loc =
                    resource_map_[page_links[link_num - 1]];
                if (resource_loc.first == page_resource)
                    file <<
@@ -1050,16 +1050,17 @@ int main(int argc, char ** argv)
            }
        }
 
-       std::auto_ptr<FrameBuffer> fb;
+       std::auto_ptr<x_frame_buffer> fb;
        if (!preview_mode)
        {
            // Spawn Xvfb and set env variables so that Xlib will use it
            // Use 8 bits each for RGB components, which should translate into
            // "enough" bits for YUV components.
-           fb.reset(new FrameBuffer(frame_params.width, frame_params.height,
-                                    3 * 8));
-           setenv("XAUTHORITY", fb->get_x_authority().c_str(), true);
-           setenv("DISPLAY", fb->get_x_display().c_str(), true);
+           fb.reset(new x_frame_buffer(frame_params.width,
+                                       frame_params.height,
+                                       3 * 8));
+           setenv("XAUTHORITY", fb->get_authority().c_str(), true);
+           setenv("DISPLAY", fb->get_display().c_str(), true);
        }
 
        // Initialise Gtk
@@ -1118,11 +1119,11 @@ int main(int argc, char ** argv)
            output_dir = argv[argi + 1];
 
        // Initialise Mozilla
-       BrowserWidget::Initialiser browser_init;
+       browser_widget::initialiser browser_init;
        set_browser_preferences();
 
        // Run the browser/converter
-       WebDvdWindow window(frame_params, menu_url, output_dir);
+       webdvd_window window(frame_params, menu_url, output_dir);
        Gtk::Main::run(window);
     }
     catch (std::exception & e)
diff --git a/x_frame_buffer.cpp b/x_frame_buffer.cpp
new file mode 100644 (file)
index 0000000..75d9595
--- /dev/null
@@ -0,0 +1,265 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#include "x_frame_buffer.hpp"
+
+#include <cassert>
+#include <cstdio>
+#include <cstring>
+#include <stdexcept>
+
+#include <sys/types.h>
+#include <errno.h>
+#include <fcntl.h>
+#include <netdb.h>
+#include <sys/socket.h>
+#include <sys/stat.h>
+#include <sys/utsname.h>
+#include <unistd.h>
+#include <wait.h>
+
+#include "auto_fd.hpp"
+#include "auto_handle.hpp"
+#include "temp_file.hpp"
+
+namespace
+{
+    struct addrinfo_factory
+    {
+       addrinfo * operator()() const { return NULL; }
+    };
+    struct addrinfo_closer
+    {
+       void operator()(addrinfo * addr_list) const
+           {
+               if (addr_list)
+                   freeaddrinfo(addr_list);
+           }
+    };
+    typedef auto_handle<addrinfo *, addrinfo_closer, addrinfo_factory>
+        auto_addrinfo;
+
+    int select_display_num(auto_fd & tcp4_socket, auto_fd & tcp6_socket)
+    {
+       // Minimum and maximum display numbers to use.  Xvnc and ssh's
+       // proxies start at 10, so we'll follow that convention.  We
+       // have to put a limit on iteration somewhere, and 100
+       // displays seems rather excessive so we'll stop there.
+       const int min_display_num = 10;
+       const int max_display_num = 99;
+
+       for (int display_num = min_display_num;
+            display_num <= max_display_num;
+            ++display_num)
+       {
+           // Check that there's no lock file for the local socket
+           // for this display.  We could also check for stale locks,
+           // but this will probably do.
+           char lock_file_name[20];
+           std::sprintf(lock_file_name, "/tmp/.X%d-lock", display_num);
+           if (!(access(lock_file_name, 0) == -1 && errno == ENOENT))
+               continue;
+
+           // Attempt to create TCP socket(s) and bind them to the
+           // appropriate port number.  We won't set the X server to
+           // listen on a TCP socket but this does ensure that ssh
+           // isn't using and won't use this display number.  This is
+           // roughly based on the x11_create_display_inet function
+           // in OpenSSH.
+
+           auto_addrinfo addr_list;
+
+           {
+               addrinfo hints = {};
+               hints.ai_family = AF_UNSPEC;
+               hints.ai_socktype = SOCK_STREAM;
+               char port_str[5 + 1];
+               std::sprintf(port_str, "%d", 6000 + display_num);
+               addrinfo * addr_list_temp;
+               int error = getaddrinfo(NULL, port_str, &hints,
+                                            &addr_list_temp);
+               if (error != 0)
+                   throw std::runtime_error(
+                       std::string("getaddrinfo: ")
+                       .append(gai_strerror(error)));
+               addr_list.reset(addr_list_temp);
+           }
+
+           const addrinfo * addr;
+
+           for (addr = addr_list.get(); addr != NULL; addr = addr->ai_next)
+           {
+               // We're only interested in TCPv4 and TCPv6.
+               if (addr->ai_family != AF_INET && addr->ai_family != AF_INET6)
+                   continue;
+               auto_fd & tcp_socket =
+                   (addr->ai_family == AF_INET) ? tcp4_socket : tcp6_socket;
+
+               tcp_socket.reset(socket(addr->ai_family,
+                                       SOCK_STREAM,
+                                       addr->ai_protocol));
+               if (tcp_socket.get() < 0)
+               {
+                   // If the family is unsupported, no-one can bind
+                   // to this address, so this is not a problem.
+                   if (errno == EAFNOSUPPORT
+#                      ifdef EPFNOSUPPORT
+                       || errno == EPFNOSUPPORT
+#                      endif
+                       )
+                       continue;
+                   throw std::runtime_error(
+                       std::string("socket: ").append(strerror(errno)));
+               }
+
+               // Don't let TCPv6 sockets interfere with TCPv4 sockets.
+#              ifdef IPV6_V6ONLY
+               if (addr->ai_family == AF_INET6)
+               {
+                   int on = 1;
+                   if (setsockopt(tcp_socket.get(), IPPROTO_IPV6, IPV6_V6ONLY,
+                                  &on, sizeof(on)) != 0)
+                   {
+                       throw std::runtime_error(
+                           std::string("setsockopt IPV6_V6ONLY: ")
+                           .append(strerror(errno)));
+                   }
+               }
+#              endif
+
+               if (bind(tcp_socket.get(), addr->ai_addr, addr->ai_addrlen)
+                   != 0)
+                   break;
+           }
+
+           // If we reached the end of the address list, we've
+           // successfully bound to all appropriate addresses for
+           // this display number, so we can use it.
+           if (addr == NULL)
+               return display_num;
+       }
+
+       throw std::runtime_error("did not find a free X display");
+    }
+
+    void get_random_bytes(unsigned char * buf, int len)
+    {
+       assert(len > 0);
+       auto_fd random_fd(open("/dev/urandom", O_RDONLY));
+       if (random_fd.get() == -1 || read(random_fd.get(), buf, len) != len)
+           throw std::runtime_error(std::strerror(errno));
+    }
+
+    std::auto_ptr<temp_file> create_temp_auth_file(int display_num)
+    {
+       std::auto_ptr<temp_file> auth_file(new temp_file("Xvfb-auth-"));
+
+       // An xauth entry consists of the following fields.  All u16 fields
+       // are big-endian and unaligned.  Character arrays are not null-
+       // terminated.
+       // u16     address family (= 256 for local socket)
+       // u16     length of address
+       // char[]  address (= hostname)
+       // u16     length of display number
+       // char[]  display number
+       // u16     auth type name length
+       // char[]  auth type name (= "MIT-MAGIC-COOKIE-1")
+       // u16     length of auth data (= 16)
+       // char[]  auth data (= random bytes)
+       uint16_t family = htons(0x100);
+       write(auth_file->get_fd(), &family, sizeof(family));
+       utsname my_uname;
+       uname(&my_uname);
+       uint16_t len = htons(strlen(my_uname.nodename));
+       write(auth_file->get_fd(), &len, sizeof(len));
+       write(auth_file->get_fd(),
+             my_uname.nodename, strlen(my_uname.nodename));
+       char display[15];
+       std::sprintf(display, "%d", display_num);
+       len = htons(strlen(display));
+       write(auth_file->get_fd(), &len, sizeof(len));
+       write(auth_file->get_fd(), display, strlen(display));
+       static const char auth_type[] = "MIT-MAGIC-COOKIE-1";
+       len = htons(sizeof(auth_type) - 1);
+       write(auth_file->get_fd(), &len, sizeof(len));
+       write(auth_file->get_fd(), auth_type, sizeof(auth_type) - 1);
+       unsigned char auth_key[16];
+       get_random_bytes(auth_key, sizeof(auth_key));
+       len = htons(sizeof(auth_key));
+       write(auth_file->get_fd(), &len, sizeof(len));
+       write(auth_file->get_fd(), auth_key, sizeof(auth_key));
+
+       return auth_file;
+    }
+
+    // Run the X server with the specified auth file, dimensions and
+    // assigned display number.
+    auto_kill_proc spawn_x_server(int display_num,
+                                 const std::string & auth_file_name,
+                                 int width, int height, int depth)
+    {
+       char display[15];
+       std::sprintf(display, ":%d", display_num);
+       const char * auth_file_c_str = auth_file_name.c_str();
+       std::fflush(NULL);
+       auto_kill_proc server_proc(fork());
+       if (server_proc.get() == -1)
+           throw std::runtime_error(std::strerror(errno));
+
+       if (server_proc.get() == 0)
+       {
+           char dimensions[40];
+           std::sprintf(dimensions, "%dx%dx%d", width, height, depth);
+           execlp("Xvfb",
+                  "Xvfb",
+                  "-auth", auth_file_c_str,
+                  "-nolisten", "tcp",
+                  "-screen", "0", dimensions,
+                  "-terminate",
+                  display,
+                  NULL);
+           _exit(128 + errno);
+       }
+
+       // Wait for the lock file to appear or the server to exit.  We can't
+       // really wait on both of these, so poll at 1-second intervals.
+       char lock_file_name[20];
+       std::sprintf(lock_file_name, "/tmp/.X%d-lock", display_num);
+       for (;;)
+       {
+           if (access(lock_file_name, 0) == 0)
+               break;
+           if (errno != ENOENT) // huh?
+               throw std::runtime_error(std::strerror(errno));
+           if (waitpid(server_proc.get(), NULL, WNOHANG) == server_proc.get())
+           {
+               server_proc.release(); // pid is now invalid
+               // TODO: Get the exit status and decode it properly.
+               throw std::runtime_error("X server failed to create display");
+           }
+           sleep(1);
+       }
+
+       return server_proc;
+    }
+}
+
+x_frame_buffer::x_frame_buffer(int width, int height, int depth)
+       : display_num_(select_display_num(tcp4_socket_, tcp6_socket_)),
+         auth_file_(create_temp_auth_file(display_num_)),
+         server_proc_(spawn_x_server(display_num_,
+                                     get_authority(),
+                                     width, height, depth))
+{}
+
+std::string x_frame_buffer::get_authority() const
+{
+    return auth_file_->get_name();
+}
+
+std::string x_frame_buffer::get_display() const
+{
+    char display[15];
+    std::sprintf(display, ":%d", display_num_);
+    return display;
+}
diff --git a/x_frame_buffer.hpp b/x_frame_buffer.hpp
new file mode 100644 (file)
index 0000000..198d586
--- /dev/null
@@ -0,0 +1,29 @@
+// Copyright 2005 Ben Hutchings <ben@decadentplace.org.uk>.
+// See the file "COPYING" for licence details.
+
+#ifndef INC_X_FRAME_BUFFER_HPP
+#define INC_X_FRAME_BUFFER_HPP
+
+#include <memory>
+#include <string>
+
+#include "auto_fd.hpp"
+#include "auto_proc.hpp"
+#include "temp_file.hpp"
+
+// Run Xvfb with a frame buffer of the given dimensions.
+class x_frame_buffer
+{
+public:
+    x_frame_buffer(int width, int height, int depth);
+    std::string get_authority() const;
+    std::string get_display() const;
+
+private:
+    auto_fd tcp4_socket_, tcp6_socket_;
+    int display_num_;
+    std::auto_ptr<temp_file> auth_file_;
+    auto_kill_proc server_proc_;
+};
+
+#endif // !INC_X_FRAME_BUFFER_HPP