Description: <short summary of the patch>
 TODO: Put a short summary on the line above and replace this paragraph
 with a longer explanation of this change. Complete the meta-information
 with other relevant fields (see below for details). To make it easier, the
 information below has been extracted from the changelog. Adjust it or drop
 it.
 .
 pdf-presenter-console (4.0.7-2) unstable; urgency=medium
 .
   * Merge upstream fixes, should address various video bugs
Author: Barak A. Pearlmutter <bap@debian.org>

---
The information above should follow the Patch Tagging Guidelines, please
checkout http://dep.debian.net/deps/dep3/ to learn about the format. Here
are templates for supplementary fields that you might want to add:

Origin: <vendor|upstream|other>, <url of original patch>
Bug: <url in upstream bugtracker>
Bug-Debian: https://bugs.debian.org/<bugnumber>
Bug-Ubuntu: https://launchpad.net/bugs/<bugnumber>
Forwarded: <no|not-needed|url proving that it has been forwarded>
Reviewed-By: <name and email of someone who approved the patch>
Last-Update: 2017-07-25

--- pdf-presenter-console-4.0.7.orig/README.rst
+++ pdf-presenter-console-4.0.7/README.rst
@@ -165,8 +165,9 @@ Embedded video playback is not working.
 
 You likely have a ``gstreamer`` codec issue.  First, try to install
 ``gstreamer``'s 'bad' codecs (package ``libgstreamer-plugins-bad1.0-0`` on
-Debian/Ubuntu). By doing so, ``pdfpc`` will use ``gstreamer``'s OpenGL backend
-for rendering, which might solve your issue.
+Debian/Ubuntu) and add ``option gstreamer-pipeline glimagesink`` to your
+``pdfpcrc`` file.  By doing so, ``pdfpc`` will use ``gstreamer``'s OpenGL
+backend for rendering, which might solve your issue.
 
 If the problem persists, try loading the video file you want to play with the
 following command: ``gst-launch-1.0 filesrc location=<your video> ! decodebin !
--- pdf-presenter-console-4.0.7.orig/man/pdfpcrc.in
+++ pdf-presenter-console-4.0.7/man/pdfpcrc.in
@@ -60,6 +60,9 @@ Add an additional black slide at the end
 .B current-height
 Percentage of the height of the presenter screen to be used for the current slide. (int, Default 80)
 .TP
+.B current-size
+Percentage of the presenter screen to be used for the current slide. (int, Default 60)
+.TP
 .BI disable-caching
 see
 .B pdfpcrc(5)
@@ -68,8 +71,9 @@ see
 see
 .B pdfpcrc(5)
 .TP
-.B current-size
-Percentage of the presenter screen to be used for the current slide. (int, Default 60)
+.B gstreamer-pipeline
+Video rendering methods. Valid values are \fIxvimagesink\fR and \fIglimagesink\fR. (Default
+xvimagesink)
 .TP
 .B next-height
 Percentage of the height of the presenter screen to be used for the next slide. (int, Default 70)
--- pdf-presenter-console-4.0.7.orig/src/CMakeLists.txt
+++ pdf-presenter-console-4.0.7/src/CMakeLists.txt
@@ -29,11 +29,15 @@ if (MOVIES)
     )
 endif ()
 
-if ("${GTK_VERSION}" LESS 3.18 OR "${VALA_VERSION}" LESS 0.30)
+if ("${GTK_VERSION}" VERSION_LESS 3.18 OR "${VALA_VERSION}" VERSION_LESS 0.30)
     message(WARNING "Using legacy GTK API")
     set(EXTRA_VALA_OPTIONS ${EXTRA_VALA_OPTIONS} -D GTK_LEGACY)
 endif ()
 
+if ("${POPPLER_VERSION}" VERSION_GREATER 0.53 AND "${VALA_VERSION}" VERSION_GREATER 0.36.3)
+    set(EXTRA_VALA_OPTIONS ${EXTRA_VALA_OPTIONS} -D NEW_POPPLER)
+endif()
+
 set(CFLAGS
     ${GOBJECT_CFLAGS} ${GOBJECT_CFLAGS_OTHER}
     ${GIO_CFLAGS} ${GIO_CFLAGS_OTHER}
@@ -79,7 +83,7 @@ set(LIB_PATHS
 if(${WITH_X11})
     set(CFLAGS ${CFLAGS} ${X11_CFLAGS} ${X11_CFLAGS_OTHER})
     set(LIBS ${LIBS} ${X11_LIBRARIES})
-    set(LIB_PATH ${LIB_PATH} ${X11_LIBRARY_DIRS})
+    set(LIB_PATHS ${LIB_PATHS} ${X11_LIBRARY_DIRS})
 endif()
 
 add_definitions(${CFLAGS})
--- pdf-presenter-console-4.0.7.orig/src/classes/action/movie.vala
+++ pdf-presenter-console-4.0.7/src/classes/action/movie.vala
@@ -265,6 +265,9 @@ namespace pdfpc {
                 uri = filename_to_uri(file, controller.get_pdf_fname());
                 temp = false;
                 noprogress = !movie.show_controls();
+                #if NEW_POPPLER
+                loop = movie.get_play_mode() == Poppler.MoviePlayMode.REPEAT;
+                #endif
                 break;
 
             default:
@@ -295,28 +298,45 @@ namespace pdfpc {
                     break;
                 }
                 Gst.Element sink;
-                // if the gstreamer OpenGL sink is installed (in gstreamer-plugins-bad), use it
-                // as it fixes video issues (cf pdfpc/pdfpc#197). Otherwise, fallback on
-                // default xvimagesink.
-                Gst.ElementFactory glimagesinkFactory = Gst.ElementFactory.find("glimagesink");
-                if(glimagesinkFactory != null) {
-                    sink = glimagesinkFactory.create(@"sink$n");
-                } else {
-                    GLib.printerr("gstreamer's OpenGL plugin glimagesink not available. Using xvimagesink instead.\n");
-                    sink = Gst.ElementFactory.make("xvimagesink", @"sink$n");
+
+                switch(Options.gstreamer_pipeline) {
+                    case Options.GstreamerPipeline.XVIMAGESINK:
+                        sink = Gst.ElementFactory.make("xvimagesink", @"sink$n");
+                        break;
+                    case Options.GstreamerPipeline.GLIMAGESINK:
+                        sink = Gst.ElementFactory.make("glimagesink", @"sink$n");
+                        break;
+                    default:
+                        GLib.printerr("Invalid gstreamer-pipeline selected. Falling back to autovideosink.\n");
+                        sink = Gst.ElementFactory.make("autovideosink", @"sink$n");
+                        break;
                 }
+
                 Gst.Element queue = Gst.ElementFactory.make("queue", @"queue$n");
                 bin.add_many(queue,sink);
                 tee.link(queue);
                 Gst.Element ad_element = this.link_additional(n, queue, bin, rect);
                 ad_element.link(sink);
                 sink.set("force_aspect_ratio", false);
-
                 Gst.Video.Overlay xoverlay = (Gst.Video.Overlay) sink;
-                xoverlay.set_window_handle(xid);
+
+                if(Options.gstreamer_pipeline == Options.GstreamerPipeline.GLIMAGESINK) {
+                    var overlay_widget = this.controller.overlay_widget(n, this.area);
+                    if (overlay_widget.get_realized()) {
+                        xoverlay.set_window_handle((uint*)((Gdk.X11.Window) overlay_widget.get_window()).get_xid());
+                    }
+                    else {
+                        overlay_widget.realize.connect((event) => {
+                            xoverlay.set_window_handle((uint*)((Gdk.X11.Window) overlay_widget.get_window()).get_xid());
+                        });
+                    }
+                }
+                else if(Options.gstreamer_pipeline == Options.GstreamerPipeline.XVIMAGESINK) {
+                    xoverlay.set_window_handle(xid);
+                    xoverlay.set_render_rectangle(rect.x*gdk_scale, rect.y*gdk_scale,
+                                                  rect.width*gdk_scale, rect.height*gdk_scale);
+                }
                 xoverlay.handle_events(false);
-                xoverlay.set_render_rectangle(rect.x*gdk_scale, rect.y*gdk_scale,
-                                              rect.width*gdk_scale, rect.height*gdk_scale);
                 n++;
             }
 
--- pdf-presenter-console-4.0.7.orig/src/classes/config_file_reader.vala
+++ pdf-presenter-console-4.0.7/src/classes/config_file_reader.vala
@@ -253,6 +253,19 @@ namespace pdfpc {
                         Options.use_time_of_day = true;
                     }
                     break;
+                case "gstreamer-pipeline":
+                    switch(fields[2]) {
+                        case "xvimagesink":
+                            Options.gstreamer_pipeline = Options.GstreamerPipeline.XVIMAGESINK;
+                            break;
+                        case "glimagesink":
+                            Options.gstreamer_pipeline = Options.GstreamerPipeline.GLIMAGESINK;
+                            break;
+                        default:
+                            GLib.printerr("Invalid value for option gstreamer-pipeline, only xvimagesink and glimagesink are supported\n");
+                            break;
+                    }
+                    break;
                 default:
                     GLib.printerr("Unknown option %s in pdfpcrc\n", fields[1]);
                     break;
--- pdf-presenter-console-4.0.7.orig/src/classes/options.vala
+++ pdf-presenter-console-4.0.7/src/classes/options.vala
@@ -157,6 +157,16 @@ namespace pdfpc {
          */
         public static bool version = false;
 
+        public enum GstreamerPipeline {
+            XVIMAGESINK,
+            GLIMAGESINK,
+        }
+
+        /**
+         * Select the gstreamer pipeline to use for video output
+         */
+        public static GstreamerPipeline gstreamer_pipeline = GstreamerPipeline.XVIMAGESINK;
+
         public class BindTuple {
             public string type;
             public uint keyCode;
--- pdf-presenter-console-4.0.7.orig/src/classes/presentation_controller.vala
+++ pdf-presenter-console-4.0.7/src/classes/presentation_controller.vala
@@ -39,7 +39,6 @@ namespace pdfpc {
      * Controller handling all the triggered events/signals
      */
     public class PresentationController : Object {
-
         /**
          * The currently displayed slide
          */
@@ -1369,6 +1368,70 @@ namespace pdfpc {
             gdk_scale = view.scale_factor;
             return (uint*) ((Gdk.X11.Window) view.get_window()).get_xid();
         }
+
+        /**
+         * Create a widget corresponding to the Poppler.Rectangle for the nth
+         * controllable's main view, and return it. The widget is automatically
+         * destroyed when the slide changes. Note that the widget might not
+         * have been realized yet right after creation.
+         */
+        public Gtk.Widget overlay_widget(int n, Poppler.Rectangle area) {
+            Controllable c = (n < this.controllables.size) ? this.controllables.get(n) : null;
+            View.Pdf view = c.main_view;
+            Gdk.Rectangle rect = view.convert_poppler_rectangle_to_gdk_rectangle(area);
+
+            var widget = new Gtk.EventBox();
+            widget.set_size_request(rect.width, rect.height);
+            widget.add_events(Gdk.EventMask.BUTTON_PRESS_MASK | Gdk.EventMask.BUTTON_RELEASE_MASK | Gdk.EventMask.POINTER_MOTION_MASK);
+
+            // Find the fixed view that the view belongs to; this could be
+            // improved by refactoring the API. Then add the widget to it.
+            Gtk.Container parent = view.parent;
+            while(parent != null && !(parent is Gtk.Fixed)) {
+                parent = parent.parent;
+            }
+            if(parent == null) {
+                printerr("Warning: Unhandled case in presentation_controller.overlay_pos(): View is not contained in a Gtk.Fixed\n");
+            }
+            else {
+                var allocation = Gtk.Allocation();
+                view.get_allocation(out allocation);
+                (parent as Gtk.Fixed).put(widget, rect.x + allocation.x, rect.y + allocation.y);
+
+                // Pass events on to the underlying view
+                widget.motion_notify_event.connect((event) => {
+                    event.x += allocation.x + rect.x;
+                    event.y += allocation.y + rect.y;
+                    view.motion_notify_event(event);
+                    return true;
+                });
+                widget.button_press_event.connect((event) => {
+                    event.x += allocation.x + rect.x;
+                    event.y += allocation.y + rect.y;
+                    view.button_press_event(event);
+                    return true;
+                });
+                widget.button_release_event.connect((event) => {
+                    event.x += allocation.x + rect.x;
+                    event.y += allocation.y + rect.y;
+                    view.button_release_event(event);
+                    return true;
+                });
+            }
+
+            // Set up automated removal of the widget
+            ulong handler_id = 0;
+            int slide_at_setup = this.current_slide_number;
+            handler_id = this.update_request.connect(() => {
+                if(this.current_slide_number != slide_at_setup) {
+                    widget.destroy();
+                    this.disconnect(handler_id);
+                }
+            });
+
+            widget.show();
+            return widget;
+        }
 #endif
     }
 }
