class WebDvdWindow : public Gtk::Window
{
public:
- WebDvdWindow(int width, int height);
+ WebDvdWindow(const video::frame_params & frame_params);
void add_page(const std::string & uri);
private:
enum ResourceType { page_resource, video_resource };
typedef std::pair<ResourceType, int> ResourceEntry;
- int width_, height_;
+ video::frame_params frame_params_;
BrowserWidget browser_widget_;
nsCOMPtr<nsIStyleSheet> stylesheet_;
std::queue<std::string> page_queue_;
std::auto_ptr<link_state> link_state_;
};
- WebDvdWindow::WebDvdWindow(int width, int height)
- : width_(width), height_(height),
+ WebDvdWindow::WebDvdWindow(const video::frame_params & frame_params)
+ : 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(
std::cout << "saving " << filename << std::endl;
Gdk::Pixbuf::create(Glib::RefPtr<Gdk::Drawable>(window),
window->get_colormap(),
- 0, 0, 0, 0, width_, height_)
+ 0, 0, 0, 0,
+ frame_params_.width, frame_params_.height)
->save(filename, "png");
}
{
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,
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;
}
}
+ 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
Gtk::Main kit(argc, argv);
BrowserWidget::init();
-
- WebDvdWindow window(width, height);
- for (int argi = 1; argi < argc; ++argi)
- window.add_page(argv[argi]);
- if (argc < 2)
+
+ WebDvdWindow window(frame_params);
+ int argi = 1;
+ if (std::strcmp(argv[argi], "--video-std") == 0)
+ argi += 2;
+ else if (std::strcmp(argv[argi], "--") == 0)
+ argi += 1;
+ else if (argv[argi][0] == '-')
+ throw std::runtime_error(
+ std::string("Invalid option: ").append(argv[argi]));
+ if (argi == argc)
window.add_page("about:");
+ else
+ for (/* no initialisation */; argi != argc; ++argi)
+ window.add_page(argv[argi]);
Gtk::Main::run(window);
}
catch (std::exception & e)