]> git.decadent.org.uk Git - videolink.git/blobdiff - webdvd.cpp
Added support for "VOB lists" (files containing <vob> elements to be inserted into...
[videolink.git] / webdvd.cpp
index 6fb547ff510c0431bfddba9adfdc5272b0f60598..cf71bb61843abc64a455ed3db46fd045a036ad16 100644 (file)
@@ -14,7 +14,6 @@
 #include <string>
 
 #include <stdlib.h>
-#include <unistd.h>
 
 #include <boost/shared_ptr.hpp>
 
@@ -30,6 +29,7 @@
 #include <nsIContent.h>
 #include <nsIDocShell.h>
 #include <nsIDOMAbstractView.h>
+#include <nsIDOMBarProp.h>
 #include <nsIDOMDocumentEvent.h>
 #include <nsIDOMDocumentView.h>
 #include <nsIDOMElement.h>
@@ -171,6 +171,7 @@ namespace
        std::vector<std::string> video_paths_;
        bool pending_window_update_;
        int pending_req_count_;
+       bool have_tweaked_page_;
        std::auto_ptr<temp_file> background_temp_;
        struct page_state;
        std::auto_ptr<page_state> page_state_;
@@ -185,7 +186,8 @@ namespace
              output_dir_(output_dir),
              stylesheet_(load_css("file://" WEBDVD_LIB_DIR "/webdvd.css")),
              pending_window_update_(false),
-             pending_req_count_(0)
+             pending_req_count_(0),
+             have_tweaked_page_(false)
     {
        set_size_request(frame_params_.width, frame_params_.height);
        set_resizable(false);
@@ -217,8 +219,12 @@ namespace
            .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);
        }
     }
 
@@ -232,7 +238,6 @@ namespace
        resource_map_[uri].second = ++page_count;
        page_links_.resize(page_count);
 
-       pending_window_update_ = true;
        browser_widget_.load_uri(uri);
     }
 
@@ -251,8 +256,15 @@ namespace
            }
        }
            
-       if (flags & GTK_MOZ_EMBED_FLAG_STOP
-           && flags & GTK_MOZ_EMBED_FLAG_IS_WINDOW)
+       if (flags & GTK_MOZ_EMBED_FLAG_IS_DOCUMENT
+           && flags & GTK_MOZ_EMBED_FLAG_START)
+       {
+           pending_window_update_ = true;
+           have_tweaked_page_ = false;
+       }
+
+       if (flags & GTK_MOZ_EMBED_FLAG_IS_WINDOW
+           && flags & GTK_MOZ_EMBED_FLAG_STOP)
        {
            // Check whether the load was successful, ignoring this
            // pseudo-error.
@@ -295,22 +307,32 @@ namespace
        nsCOMPtr<nsIDOMWindow> dom_window;
        check(browser->GetContentDOMWindow(getter_AddRefs(dom_window)));
 
-       if (output_dir_.empty())
+       // If we haven't done so already, apply the stylesheet and
+       // disable scrollbars.
+       if (!have_tweaked_page_)
        {
-           // In preview mode, just apply the stylesheet and let the
-           // user select links.
            apply_style_sheet(stylesheet_, pres_shell);
+
+           // This actually only needs to be done once.
+           nsCOMPtr<nsIDOMBarProp> dom_bar_prop;
+           check(dom_window->GetScrollbars(getter_AddRefs(dom_bar_prop)));
+           check(dom_bar_prop->SetVisible(false));
+
+           have_tweaked_page_ = true;
+
+           // Might need to wait a while for things to load or more
+           // likely for a re-layout.
+           if (pending_req_count_ > 0)
+               return true;
        }
-       else
+
+       // All further work should only be done if we're not in preview mode.
+       if (!output_dir_.empty())
        {
-           // If we haven't already started work on this page, apply
-           // the stylesheet and save a screenshot of its normal
-           // appearance.
+           // If we haven't already started work on this page, save a
+           // screenshot of its normal appearance.
            if (!page_state_.get())
-           {
-               apply_style_sheet(stylesheet_, pres_shell);
                save_screenshot();
-           }
 
            // Start or continue processing links.
            process_links(pres_shell, pres_context, dom_window);
@@ -480,8 +502,11 @@ namespace
                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));
@@ -788,10 +813,25 @@ namespace
                "    <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,