]> git.decadent.org.uk Git - videolink.git/blobdiff - webdvd.cpp
Implemented preview mode. Updated documentation accordingly.
[videolink.git] / webdvd.cpp
index a6064b2bf33bf65fc9b904fd9b54b023c0861ba5..113198c6a27ecdf4aae4db906ed6bcb8734be907 100644 (file)
@@ -165,7 +165,7 @@ namespace
        std::map<std::string, ResourceEntry> resource_map_;
        std::vector<std::vector<std::string> > page_links_;
        std::vector<std::string> video_paths_;
-       bool loading_;
+       bool pending_window_update_;
        int pending_req_count_;
        std::auto_ptr<temp_file> background_temp_;
        struct link_state;
@@ -180,7 +180,7 @@ namespace
            : frame_params_(frame_params),
              output_dir_(output_dir),
              stylesheet_(load_css("file://" WEBDVD_LIB_DIR "/webdvd.css")),
-             loading_(false),
+             pending_window_update_(false),
              pending_req_count_(0)
     {
        set_default_size(frame_params_.width, frame_params_.height);
@@ -220,8 +220,6 @@ namespace
 
     void WebDvdWindow::load_next_page()
     {
-       loading_ = true;
-
        assert(!page_queue_.empty());
        const std::string & uri = page_queue_.front();
        std::cout << "loading " << uri << std::endl;
@@ -229,39 +227,33 @@ namespace
        std::size_t page_count = page_links_.size();
        resource_map_[uri].second = ++page_count;
        page_links_.resize(page_count);
+
+       pending_window_update_ = true;
        browser_widget_.load_uri(uri);
     }
 
     void WebDvdWindow::on_net_state_change(const char * uri,
                                           gint flags, guint status)
     {
-       enum {
-           process_nothing,
-           process_new_page,
-           process_current_link
-       } action = process_nothing;
-
        if (flags & GTK_MOZ_EMBED_FLAG_IS_REQUEST)
        {
            if (flags & GTK_MOZ_EMBED_FLAG_START)
                ++pending_req_count_;
+
            if (flags & GTK_MOZ_EMBED_FLAG_STOP)
            {
                assert(pending_req_count_ != 0);
                --pending_req_count_;
            }
-           if (pending_req_count_ == 0 && link_state_.get())
-               action = process_current_link;
        }
            
        if (flags & GTK_MOZ_EMBED_FLAG_STOP
            && flags & GTK_MOZ_EMBED_FLAG_IS_WINDOW)
-           action = process_new_page;
+           pending_window_update_ = false;
 
-       if (action != process_nothing)
+       if (pending_req_count_ == 0 && !pending_window_update_)
        {
-           assert(loading_ && !page_queue_.empty());
-           assert(pending_req_count_ == 0);
+           assert(!page_queue_.empty());
 
            try
            {
@@ -283,22 +275,33 @@ namespace
                check(browser->GetContentDOMWindow(
                          getter_AddRefs(dom_window)));
 
-               if (action == process_new_page)
+               if (output_dir_.empty())
                {
                    apply_style_sheet(stylesheet_, pres_shell);
-                   save_screenshot();
                }
-               process_links(pres_shell, pres_context, dom_window);
-               if (!link_state_.get())
+               else
                {
-                   page_queue_.pop();
-                   if (page_queue_.empty())
+                   if (!link_state_.get())
                    {
-                       generate_dvd();
-                       Gtk::Main::quit();
+                       apply_style_sheet(stylesheet_, pres_shell);
+                       save_screenshot();
+                   }
+
+                   process_links(pres_shell, pres_context, dom_window);
+
+                   if (!link_state_.get())
+                   {
+                       page_queue_.pop();
+                       if (page_queue_.empty())
+                       {
+                           generate_dvd();
+                           Gtk::Main::quit();
+                       }
+                       else
+                       {
+                           load_next_page();
+                       }
                    }
-                   else
-                       load_next_page();
                }
            }
            catch (std::exception & e)
@@ -867,75 +870,114 @@ namespace
            std::string("Invalid video standard: ").append(str));
     }
 
+    void print_usage(std::ostream & stream, const char * command_name)
+    {
+       stream << "Usage: " << command_name
+              << (" [gtk-options] [--video-std std-name]"
+                  " [--preview] menu-url [output-dir]\n");
+    }
+    
 } // namespace
 
 int main(int argc, char ** argv)
 {
     try
     {
-       // Determine video frame parameters.
        video::frame_params frame_params = video::pal_params;
-       for (int argi = 1; argi != argc; ++argi)
+       bool preview_mode = false;
+
+       // Do initial argument parsing.  We have to do this before
+       // letting Gtk parse the arguments since we may need to spawn
+       // Xvfb first.
+       int argi = 1;
+       while (argi != argc)
        {
            if (std::strcmp(argv[argi], "--") == 0)
+           {
                break;
-           if (std::strcmp(argv[argi], "--video-std") == 0)
+           }
+           else if (std::strcmp(argv[argi], "--help") == 0)
+           {
+               print_usage(std::cout, argv[0]);
+               return EXIT_SUCCESS;
+           }
+           else if (std::strcmp(argv[argi], "--preview") == 0)
+           {
+               preview_mode = true;
+               argi += 1;
+           }
+           else if (std::strcmp(argv[argi], "--video-std") == 0)
            {
                if (argi + 1 == argc)
                {
                    std::cerr << "Missing argument to --video-std\n";
+                   print_usage(std::cerr, argv[0]);
                    return EXIT_FAILURE;
                }
                frame_params = lookup_frame_params(argv[argi + 1]);
-               break;
+               argi += 2;
+           }
+           else
+           {
+               argi += 1;
            }
        }
-       
-       // 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.
-       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);
+
+       std::auto_ptr<FrameBuffer> 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);
+       }
 
        // 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;
+       // Complete argument parsing with Gtk's options out of the way.
+       argi = 1;
        while (argi != argc)
        {
-           if (std::strcmp(argv[argi], "--video-std") == 0)
+           if (std::strcmp(argv[argi], "--") == 0)
            {
-               argi += 2;
+               argi += 1;
+               break;
            }
-           else if (std::strcmp(argv[argi], "--") == 0)
+           else if (std::strcmp(argv[argi], "--preview") == 0)
            {
                argi += 1;
-               break;
+           }
+           else if (std::strcmp(argv[argi], "--video-std") == 0)
+           {
+               argi += 2;
            }
            else if (argv[argi][0] == '-')
            {
                std::cerr << "Invalid option: " << argv[argi] << "\n";
+               print_usage(std::cerr, argv[0]);
                return EXIT_FAILURE;
            }
            else
+           {
                break;
+           }
        }
-       if (argi != argc - 2)
+       if (argc - argi != (preview_mode ? 1 : 2))
        {
-           std::cerr << "Usage: " << argv[0]
-                     << (" [gtk-options] [--video-std std-name]"
-                         "front-page-url output-dir\n");
+           print_usage(std::cerr, argv[0]);
            return EXIT_FAILURE;
        }
 
        // Initialise Mozilla
        BrowserWidget::init();
 
-       WebDvdWindow window(frame_params, argv[argi], argv[argi + 1]);
+       WebDvdWindow window(frame_params,
+                           argv[argi],
+                           preview_mode ? "" : argv[argi + 1]);
        Gtk::Main::run(window);
     }
     catch (std::exception & e)