X-Git-Url: https://git.decadent.org.uk/gitweb/?p=videolink.git;a=blobdiff_plain;f=webdvd.cpp;h=a6d456a8f0de6ed9ee20dba636c7b0d14d9c1a4b;hp=8e586e2d230fbc4d20aa6a1cca9fc99b5dbb87c3;hb=c5b2c095ea46391abe7c916aa3aaa819882fc726;hpb=410c2b9017bc26a7e79269c1f7fc606ad89249bb diff --git a/webdvd.cpp b/webdvd.cpp index 8e586e2..a6d456a 100644 --- a/webdvd.cpp +++ b/webdvd.cpp @@ -18,6 +18,7 @@ #include #include +#include #include #include #include @@ -132,10 +133,12 @@ namespace class WebDvdWindow : public Gtk::Window { public: - WebDvdWindow(int width, int height); - void add_page(const std::string & uri); + WebDvdWindow( + const video::frame_params & frame_params, + const std::string & main_page_uri); private: + void add_page(const std::string & uri); void add_video(const std::string & uri); void load_next_page(); void on_net_state_change(const char * uri, gint flags, guint status); @@ -147,7 +150,7 @@ namespace enum ResourceType { page_resource, video_resource }; typedef std::pair ResourceEntry; - int width_, height_; + video::frame_params frame_params_; BrowserWidget browser_widget_; nsCOMPtr stylesheet_; std::queue page_queue_; @@ -160,17 +163,22 @@ namespace std::auto_ptr link_state_; }; - WebDvdWindow::WebDvdWindow(int width, int height) - : width_(width), height_(height), + WebDvdWindow::WebDvdWindow( + const video::frame_params & frame_params, + const std::string & main_page_uri) + : frame_params_(frame_params), stylesheet_(load_css("file://" WEBDVD_LIB_DIR "/webdvd.css")), loading_(false), pending_req_count_(0) { - set_default_size(width, height); + set_default_size(frame_params_.width, frame_params_.height); add(browser_widget_); browser_widget_.show(); browser_widget_.signal_net_state().connect( SigC::slot(*this, &WebDvdWindow::on_net_state_change)); + + add_page(main_page_uri); + load_next_page(); } void WebDvdWindow::add_page(const std::string & uri) @@ -180,8 +188,6 @@ namespace .second) { page_queue_.push(uri); - if (!loading_) - load_next_page(); } } @@ -247,7 +253,10 @@ namespace try { - check(status); + // Check whether the load was successful, ignoring this + // pseudo-error. + if (status != NS_IMAGELIB_ERROR_LOAD_ABORTED) + check(status); nsCOMPtr browser( browser_widget_.get_browser()); @@ -294,7 +303,7 @@ namespace void WebDvdWindow::save_screenshot() { - char filename[20]; + char filename[25]; std::sprintf(filename, "page_%06d_back.png", page_links_.size()); Glib::RefPtr window(get_window()); assert(window); @@ -302,7 +311,8 @@ namespace std::cout << "saving " << filename << std::endl; Gdk::Pixbuf::create(Glib::RefPtr(window), window->get_colormap(), - 0, 0, 0, 0, width_, height_) + 0, 0, 0, 0, + frame_params_.width, frame_params_.height) ->save(filename, "png"); } @@ -348,10 +358,10 @@ namespace { state.reset(new link_state); - state->diff_pixbuf = Gdk::Pixbuf::create(Gdk::COLORSPACE_RGB, - true, // has_alpha - 8, // bits_per_sample - width_, height_); + state->diff_pixbuf = Gdk::Pixbuf::create( + Gdk::COLORSPACE_RGB, + true, 8, // has_alpha, bits_per_sample + frame_params_.width, frame_params_.height); char spumux_filename[20]; std::sprintf(spumux_filename, @@ -373,7 +383,9 @@ namespace state->link_changing = false; } - rectangle window_rect = { 0, 0, width_, height_ }; + rectangle window_rect = { + 0, 0, frame_params_.width, frame_params_.height + }; for (/* no initialisation */; state->links_it != state->links_end; @@ -751,38 +763,98 @@ namespace } } + const video::frame_params & lookup_frame_params(const char * str) + { + assert(str); + static const struct { const char * str; bool is_ntsc; } + known_strings[] = { + { "NTSC", true }, + { "ntsc", true }, + { "PAL", false }, + { "pal", false }, + // For DVD purposes, SECAM can be treated identically to PAL. + { "SECAM", false }, + { "secam", false } + }; + for (std::size_t i = 0; + i != sizeof(known_strings)/sizeof(known_strings[0]); + ++i) + if (std::strcmp(str, known_strings[i].str) == 0) + return known_strings[i].is_ntsc ? + video::ntsc_params : video::pal_params; + throw std::runtime_error( + std::string("Invalid video standard: ").append(str)); + } + } // namespace int main(int argc, char ** argv) { - // Get dimensions - int width = video::pal_oscan_width, height = video::pal_oscan_height; - for (int i = 1; i < argc - 1; ++i) - if (std::strcmp(argv[i], "-geometry") == 0) - { - std::sscanf(argv[i + 1], "%dx%d", &width, &height); - break; - } - // A depth of 24 results in 8 bits each for RGB components, which - // translates into "enough" bits for YUV components. - const int depth = 24; - try { + // Determine video frame parameters. + video::frame_params frame_params = video::pal_params; + for (int argi = 1; argi != argc; ++argi) + { + if (std::strcmp(argv[argi], "--") == 0) + break; + if (std::strcmp(argv[argi], "--video-std") == 0) + { + if (argi + 1 == argc) + { + std::cerr << "Missing argument to --video-std\n"; + return EXIT_FAILURE; + } + frame_params = lookup_frame_params(argv[argi + 1]); + break; + } + } + // Spawn Xvfb and set env variables so that Xlib will use it - FrameBuffer fb(width, height, depth); + // Use 8 bits each for RGB components, which should translate into + // "enough" bits for YUV components. + FrameBuffer fb(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); - // Initialise Gtk and Mozilla + // Initialise Gtk Gtk::Main kit(argc, argv); + + // Check we have the right number of arguments. We can't + // do this earlier because we need to let Gtk read and remove + // any of the many options it understands. + int argi = 1; + while (argi != argc) + { + if (std::strcmp(argv[argi], "--video-std") == 0) + { + argi += 2; + } + else if (std::strcmp(argv[argi], "--") == 0) + { + argi += 1; + break; + } + else if (argv[argi][0] == '-') + { + std::cerr << "Invalid option: " << argv[argi] << "\n"; + return EXIT_FAILURE; + } + else + break; + } + if (argi != argc - 1) + { + std::cerr << "Usage: " << argv[0] + << (" [gtk-options] [--video-std std-name]" + "front-page-url\n"); + return EXIT_FAILURE; + } + + // Initialise Mozilla BrowserWidget::init(); - WebDvdWindow window(width, height); - for (int argi = 1; argi < argc; ++argi) - window.add_page(argv[argi]); - if (argc < 2) - window.add_page("about:"); + WebDvdWindow window(frame_params, argv[argi]); Gtk::Main::run(window); } catch (std::exception & e)