#include <nsIInterfaceRequestorUtils.h>
#include <nsIURI.h> // required before nsILink.h
#include <nsILink.h>
+#include <nsIPrefBranch.h>
+#include <nsIPrefService.h>
#include <nsIPresContext.h>
#include <nsIPresShell.h>
+#include <nsIServiceManagerUtils.h>
#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;
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;
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);
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_;
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)
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;
- video_paths_.push_back(Glib::filename_from_uri(uri, hostname));
+ std::string filename(Glib::filename_from_uri(uri, hostname));
// FIXME: Should check the hostname
+ if (!Glib::file_test(filename, Glib::FILE_TEST_IS_REGULAR))
+ throw std::runtime_error(
+ filename + " is missing or not a regular file");
+ video_paths_.push_back(filename);
}
}
- void WebDvdWindow::load_next_page()
+ void webdvd_window::load_next_page()
{
assert(!page_queue_.empty());
const std::string & uri = page_queue_.front();
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 << "webdvd_window::on_net_state_change(";
+ if (uri)
+ std::cout << '"' << uri << '"';
+ else
+ std::cout << "NULL";
+ std::cout << ", ";
+ {
+ gint flags_left = flags;
+ static const struct {
+ gint value;
+ const char * name;
+ } flag_names[] = {
+ { GTK_MOZ_EMBED_FLAG_START, "STATE_START" },
+ { GTK_MOZ_EMBED_FLAG_REDIRECTING, "STATE_REDIRECTING" },
+ { GTK_MOZ_EMBED_FLAG_TRANSFERRING, "STATE_TRANSFERRING" },
+ { GTK_MOZ_EMBED_FLAG_NEGOTIATING, "STATE_NEGOTIATING" },
+ { GTK_MOZ_EMBED_FLAG_STOP, "STATE_STOP" },
+ { GTK_MOZ_EMBED_FLAG_IS_REQUEST, "STATE_IS_REQUEST" },
+ { GTK_MOZ_EMBED_FLAG_IS_DOCUMENT, "STATE_IS_DOCUMENT" },
+ { GTK_MOZ_EMBED_FLAG_IS_NETWORK, "STATE_IS_NETWORK" },
+ { GTK_MOZ_EMBED_FLAG_IS_WINDOW, "STATE_IS_WINDOW" }
+ };
+ for (int i = 0; i != sizeof(flag_names)/sizeof(flag_names[0]); ++i)
+ {
+ if (flags & flag_names[i].value)
+ {
+ std::cout << flag_names[i].name;
+ flags_left -= flag_names[i].value;
+ if (flags_left)
+ std::cout << " | ";
+ }
+ }
+ if (flags_left)
+ std::cout << "0x" << std::setbase(16) << flags_left;
+ }
+ std::cout << ", " << "0x" << std::setbase(16) << status << ")\n";
+# endif // DEBUG_ON_NET_STATE_CHANGE
+
if (flags & GTK_MOZ_EMBED_FLAG_IS_REQUEST)
{
if (flags & GTK_MOZ_EMBED_FLAG_START)
}
}
- bool WebDvdWindow::process_page()
+ bool webdvd_window::process_page()
{
assert(!page_queue_.empty());
return true;
}
- void WebDvdWindow::save_screenshot()
+ void webdvd_window::save_screenshot()
{
Glib::RefPtr<Gdk::Window> window(get_window());
assert(window);
->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(
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)
{
check(uri->GetPath(path));
// FIXME: This is a bit of a hack. Perhaps we could decide
// later based on the MIME type determined by Mozilla?
- if (path.Length() > 4
- && std::strcmp(path.EndReading() - 4, ".vob") == 0)
+ if ((path.Length() > 4
+ && std::strcmp(path.EndReading() - 4, ".vob") == 0)
+ || (path.Length() > 8
+ && std::strcmp(path.EndReading() - 8, ".voblist")
+ == 0))
{
PRBool is_file;
check(uri->SchemeIs("file", &is_file));
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();
" 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 <<
" <titles>\n"
" <pgc>\n"
// Record calling page/menu.
- " <pre> g12 = g1; </pre>\n"
+ " <pre> g12 = g1; </pre>\n";
+
+ // Write a reference to a linked VOB file, or the contents
+ // of a linked VOB list file.
+ const std::string & video_path = video_paths_[video_num - 1];
+ if (video_path.compare(video_path.size() - 4, 4, ".vob") == 0)
+ {
// FIXME: Should XML-escape the path
- " <vob file='" << video_paths_[video_num - 1]
- << "'/>\n"
+ file << " <vob file='" << video_path << "'/>\n";
+ }
+ else
+ {
+ assert(video_path.compare(video_path.size() - 8, 8,
+ ".voblist") == 0);
+ // TODO: Validate the file contents;
+ file << Glib::file_get_contents(video_path);
+ }
+
+ file <<
// If page/menu location has not been changed during the
// video, change the location to be the following
// link/button when returning to it. In any case,
" [--preview] menu-url [output-dir]\n");
}
+ void set_browser_preferences()
+ {
+ // Disable IE-compatibility kluge that causes backgrounds to
+ // sometimes/usually be missing from snapshots. This is only
+ // effective from Mozilla 1.8 onward.
+# if MOZ_VERSION_MAJOR > 1 \
+ || (MOZ_VERSION_MAJOR == 1 && MOZ_VERSION_MINOR >= 8)
+ nsCOMPtr<nsIPrefService> pref_service;
+ static const nsCID pref_service_cid = NS_PREFSERVICE_CID;
+ check(CallGetService<nsIPrefService>(pref_service_cid,
+ getter_AddRefs(pref_service)));
+ nsCOMPtr<nsIPrefBranch> pref_branch;
+ check(pref_service->GetDefaultBranch("layout",
+ getter_AddRefs(pref_branch)));
+ check(pref_branch->SetBoolPref(
+ "fire_onload_after_image_background_loads",
+ true));
+# endif
+
+ // TODO: Set display resolution? Unfortunately Mozilla doesn't
+ // support non-square pixels (and neither do fontconfig or Xft
+ // anyway).
+ }
+
} // namespace
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
output_dir = argv[argi + 1];
// Initialise Mozilla
- BrowserWidget::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)