[evince] ev-media: Make EvMediaPlayer a self contained widget to show the video and the controls



commit 1f31e0815e2c40c8983d2c9fd759220134050642
Author: Carlos Garcia Campos <cgarcia igalia com>
Date:   Fri Jun 5 10:09:02 2015 +0200

    ev-media: Make EvMediaPlayer a self contained widget to show the video and the controls
    
    Using the EvView window with gst_video_overlay_set_render_rectangle()
    to paint the videos seems to cause issues in some cases where the video
    is not correctly positioned, or uses the whole view area. To avoid that,
    we use now a specific widget (a GtkDrawingArea) to render the video
    instead. EvMediaPlayer is not a GtkBox containing the drawing area and
    the media controls. This simplifies the code a lot and requires less
    code in EvView which will also make easier to add support for videos
    in presentation view.

 libview/Makefile.am         |    2 -
 libview/ev-media-controls.c |  179 -------------------
 libview/ev-media-controls.h |   45 -----
 libview/ev-media-player.c   |  410 ++++++++++++++++++++++---------------------
 libview/ev-media-player.h   |   17 +--
 libview/ev-view.c           |  174 ++++---------------
 6 files changed, 246 insertions(+), 581 deletions(-)
---
diff --git a/libview/Makefile.am b/libview/Makefile.am
index 3ffabeb..52e48e1 100644
--- a/libview/Makefile.am
+++ b/libview/Makefile.am
@@ -57,8 +57,6 @@ libevview3_la_SOURCES =                       \
 
 if ENABLE_MULTIMEDIA
 libevview3_la_SOURCES +=       \
-       ev-media-controls.h     \
-       ev-media-controls.c     \
        ev-media-player.h       \
        ev-media-player.c
 endif
diff --git a/libview/ev-media-player.c b/libview/ev-media-player.c
index acde3d7..1c7f1a2 100644
--- a/libview/ev-media-player.c
+++ b/libview/ev-media-player.c
@@ -24,30 +24,30 @@
 
 #include <gst/video/videooverlay.h>
 
+#if defined (GDK_WINDOWING_X11)
+#include <gdk/gdkx.h>
+#elif defined (GDK_WINDOWING_WIN32)
+#include <gdk/gdkwin32.h>
+#endif
+
 enum {
         PROP_0,
         PROP_MEDIA,
-        PROP_WINDOW_ID,
-        PROP_RENDER_AREA,
-        PROP_DURATION,
-        PROP_POSITION
-};
-
-enum {
-        STATE_CHANGED,
-        N_SIGNALS
 };
 
 struct _EvMediaPlayer {
-        GObject          parent;
+        GtkBox           parent;
 
         EvMedia         *media;
-        guint64          window_id;
-        GdkRectangle     render_area;
+        GtkWidget       *drawing_area;
+        GtkWidget       *controls;
+        GtkWidget       *play_button;
+        GtkWidget       *slider;
 
         GstElement      *pipeline;
         GstBus          *bus;
         GstVideoOverlay *overlay;
+        guint64          window_handle;
         gboolean         is_playing;
         gboolean         is_seeking;
         gdouble          duration;
@@ -57,38 +57,48 @@ struct _EvMediaPlayer {
 };
 
 struct _EvMediaPlayerClass {
-        GObjectClass parent_class;
+        GtkBoxClass parent_class;
 };
 
-static guint signals[N_SIGNALS];
+G_DEFINE_TYPE (EvMediaPlayer, ev_media_player, GTK_TYPE_BOX)
+
+static void
+ev_media_player_update_position (EvMediaPlayer *player)
+{
+        if (!ev_media_get_show_controls (player->media))
+                return;
 
-G_DEFINE_TYPE (EvMediaPlayer, ev_media_player, G_TYPE_OBJECT)
+        gtk_range_set_value (GTK_RANGE (player->slider), player->position);
+}
 
 static gboolean
-update_position_cb (EvMediaPlayer *player)
+query_position_cb (EvMediaPlayer *player)
 {
         gint64 position;
 
         gst_element_query_position (player->pipeline, GST_FORMAT_TIME, &position);
         player->position = (gdouble)position / GST_SECOND;
-        g_object_notify (G_OBJECT (player), "position");
+        ev_media_player_update_position (player);
 
         return G_SOURCE_CONTINUE;
 }
 
 static void
-ev_media_player_update_position_start (EvMediaPlayer *player)
+ev_media_player_query_position_start (EvMediaPlayer *player)
 {
         if (player->position_timeout_id > 0)
                 return;
 
+        if (!ev_media_get_show_controls (player->media))
+                return;
+
         player->position_timeout_id = g_timeout_add (1000 / 15,
-                                                     (GSourceFunc)update_position_cb,
+                                                     (GSourceFunc)query_position_cb,
                                                      player);
 }
 
 static void
-ev_media_player_update_position_stop (EvMediaPlayer *player)
+ev_media_player_query_position_stop (EvMediaPlayer *player)
 {
         if (player->position_timeout_id > 0) {
                 g_source_remove (player->position_timeout_id);
@@ -97,16 +107,30 @@ ev_media_player_update_position_stop (EvMediaPlayer *player)
 }
 
 static void
-ev_media_player_update_position (EvMediaPlayer *player)
+ev_media_player_query_position (EvMediaPlayer *player)
 {
+        if (!ev_media_get_show_controls (player->media))
+                return;
+
         if (player->duration <= 0)
                 return;
 
         if (player->is_playing)
-                ev_media_player_update_position_start (player);
+                ev_media_player_query_position_start (player);
         else
-                ev_media_player_update_position_stop (player);
-        update_position_cb (player);
+                ev_media_player_query_position_stop (player);
+        query_position_cb (player);
+}
+
+static void
+ev_media_player_update_play_button (EvMediaPlayer *player)
+{
+        if (!ev_media_get_show_controls (player->media))
+                return;
+
+        gtk_image_set_from_icon_name (GTK_IMAGE (gtk_button_get_image (GTK_BUTTON (player->play_button))),
+                                      player->is_playing ? "media-playback-pause-symbolic" : 
"media-playback-start-symbolic",
+                                      GTK_ICON_SIZE_MENU);
 }
 
 static void
@@ -121,8 +145,8 @@ ev_media_player_update_state (EvMediaPlayer *player,
         is_playing = state == GST_STATE_PLAYING;
         if (is_playing != player->is_playing) {
                 player->is_playing = is_playing;
-                g_signal_emit (player, signals[STATE_CHANGED], 0, player->is_playing ? 
EV_MEDIA_PLAYER_STATE_PLAY : EV_MEDIA_PLAYER_STATE_PAUSE);
-                ev_media_player_update_position (player);
+                ev_media_player_update_play_button (player);
+                ev_media_player_query_position (player);
         }
 
         if (new_state)
@@ -130,12 +154,53 @@ ev_media_player_update_state (EvMediaPlayer *player,
 }
 
 static void
+ev_media_player_toggle_state (EvMediaPlayer *player)
+{
+        GstState current, pending, new_state;
+
+        if (!player->pipeline)
+                return;
+
+        gst_element_get_state (player->pipeline, &current, &pending, 0);
+        new_state = current == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
+        if (pending != new_state)
+                gst_element_set_state (player->pipeline, new_state);
+}
+
+static void
+ev_media_player_seek (EvMediaPlayer *player,
+                      GtkScrollType  scroll,
+                      gdouble        position)
+{
+        if (!player->pipeline)
+                return;
+
+        position = CLAMP (position, 0, player->duration);
+        if (gst_element_seek_simple (player->pipeline,
+                                     GST_FORMAT_TIME,
+                                     GST_SEEK_FLAG_FLUSH,
+                                     (gint64)(position * GST_SECOND))) {
+                player->is_seeking = TRUE;
+                ev_media_player_query_position_stop (player);
+                player->position = position;
+                ev_media_player_update_position (player);
+        }
+}
+
+
+static void
 ev_media_player_notify_eos (EvMediaPlayer *player)
 {
-        g_signal_emit (player, signals[STATE_CHANGED], 0, EV_MEDIA_PLAYER_STATE_PAUSE);
-        ev_media_player_update_position_stop (player);
+        if (!ev_media_get_show_controls (player->media)) {
+                /* A media without controls can't be played again */
+                gtk_widget_destroy (GTK_WIDGET (player));
+                return;
+        }
+
+        ev_media_player_update_play_button (player);
+        ev_media_player_query_position_stop (player);
         player->position = 0;
-        g_object_notify (G_OBJECT (player), "position");
+        ev_media_player_update_position (player);
         gst_element_set_state (player->pipeline, GST_STATE_READY);
 }
 
@@ -150,12 +215,7 @@ bus_sync_handle (GstBus        *bus,
                 return GST_BUS_PASS;
 
         overlay = GST_VIDEO_OVERLAY (GST_MESSAGE_SRC (message));
-        gst_video_overlay_set_window_handle (overlay, (guintptr)player->window_id);
-        gst_video_overlay_set_render_rectangle (overlay,
-                                                player->render_area.x,
-                                                player->render_area.y,
-                                                player->render_area.width,
-                                                player->render_area.height);
+        gst_video_overlay_set_window_handle (overlay, (guintptr)player->window_handle);
         gst_video_overlay_expose (overlay);
 
         player->overlay = overlay;
@@ -195,10 +255,13 @@ bus_message_handle (GstBus        *bus,
                 if (GST_MESSAGE_SRC (message) != (GstObject *)player->pipeline)
                         return;
 
+                if (!ev_media_get_show_controls (player->media))
+                        return;
+
                 if (player->is_seeking) {
                         player->is_seeking = FALSE;
                         if (player->is_playing)
-                                ev_media_player_update_position_start (player);
+                                ev_media_player_query_position_start (player);
                 } else {
                         ev_media_player_update_state (player, &state);
 
@@ -207,7 +270,7 @@ bus_message_handle (GstBus        *bus,
 
                                 gst_element_query_duration (player->pipeline, GST_FORMAT_TIME, &duration);
                                 player->duration = (gdouble)duration / GST_SECOND;
-                                g_object_notify (G_OBJECT (player), "duration");
+                                gtk_range_set_range (GTK_RANGE (player->slider), 0, player->duration);
                         }
                 }
 
@@ -224,11 +287,51 @@ bus_message_handle (GstBus        *bus,
 }
 
 static void
+drawing_area_realize_cb (GtkWidget     *widget,
+                         EvMediaPlayer *player)
+{
+#if defined (GDK_WINDOWING_X11)
+        player->window_handle = (guint64)GDK_WINDOW_XID (gtk_widget_get_window (widget));
+#elif defined (GDK_WINDOWING_WIN32)
+        player->window_handle = (guint64)GDK_WINDOW_HWND (gtk_widget_get_window (widget));
+#else
+        g_assert_not_reached ();
+#endif
+}
+
+static void
+ev_media_player_size_allocate (GtkWidget     *widget,
+                               GtkAllocation *allocation)
+{
+        EvMediaPlayer *player = EV_MEDIA_PLAYER (widget);
+        GdkRectangle   controls_allocation;
+
+        GTK_WIDGET_CLASS (ev_media_player_parent_class)->size_allocate (widget, allocation);
+
+        if (!ev_media_get_show_controls (player->media))
+                return;
+
+        /* Give all the allocated size to the drawing area */
+        gtk_widget_size_allocate (player->drawing_area, allocation);
+
+        /* And give space for the controls below */
+        controls_allocation.x = allocation->x;
+        controls_allocation.y = allocation->y + allocation->height;
+        controls_allocation.width = allocation->width;
+        controls_allocation.height = gtk_widget_get_allocated_height (player->controls);
+        gtk_widget_size_allocate (player->controls, &controls_allocation);
+
+        allocation->height += controls_allocation.height;
+
+        gtk_widget_set_allocation (widget, allocation);
+}
+
+static void
 ev_media_player_dispose (GObject *object)
 {
         EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
 
-        ev_media_player_update_position_stop (player);
+        ev_media_player_query_position_stop (player);
 
         if (player->bus) {
                 gst_bus_remove_signal_watch (player->bus);
@@ -248,26 +351,6 @@ ev_media_player_dispose (GObject *object)
 }
 
 static void
-ev_media_player_get_property (GObject    *object,
-                              guint       prop_id,
-                              GValue     *value,
-                              GParamSpec *pspec)
-{
-        EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
-
-        switch (prop_id) {
-        case PROP_DURATION:
-                g_value_set_double (value, player->duration);
-                break;
-        case PROP_POSITION:
-                g_value_set_double (value, player->position);
-                break;
-        default:
-                G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-        }
-}
-
-static void
 ev_media_player_set_property (GObject      *object,
                               guint         prop_id,
                               const GValue *value,
@@ -279,12 +362,6 @@ ev_media_player_set_property (GObject      *object,
         case PROP_MEDIA:
                 player->media = EV_MEDIA (g_value_dup_object (value));
                 break;
-        case PROP_WINDOW_ID:
-                player->window_id = g_value_get_uint64 (value);
-                break;
-        case PROP_RENDER_AREA:
-                ev_media_player_set_render_area (player, (GdkRectangle *)g_value_get_boxed (value));
-                break;
         default:
                 G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
         }
@@ -293,12 +370,21 @@ ev_media_player_set_property (GObject      *object,
 static void
 ev_media_player_init (EvMediaPlayer *player)
 {
+        gtk_orientable_set_orientation (GTK_ORIENTABLE (player), GTK_ORIENTATION_VERTICAL);
+
         player->pipeline = gst_element_factory_make ("playbin", NULL);
         if (!player->pipeline) {
                 g_warning ("Failed to create playbin\n");
                 return;
         }
 
+        player->drawing_area = gtk_drawing_area_new ();
+        g_signal_connect (player->drawing_area, "realize",
+                          G_CALLBACK (drawing_area_realize_cb),
+                          player);
+        gtk_box_pack_start (GTK_BOX (player), player->drawing_area, TRUE, TRUE, 0);
+        gtk_widget_show (player->drawing_area);
+
         player->bus = gst_pipeline_get_bus (GST_PIPELINE (player->pipeline));
         gst_bus_set_sync_handler (player->bus, (GstBusSyncHandler)bus_sync_handle, player, NULL);
         gst_bus_add_signal_watch (player->bus);
@@ -308,12 +394,62 @@ ev_media_player_init (EvMediaPlayer *player)
 }
 
 static void
+ev_media_player_setup_media_controls (EvMediaPlayer *player)
+{
+        GtkAdjustment  *adjustment;
+        GtkCssProvider *provider;
+
+        player->controls = gtk_box_new (GTK_ORIENTATION_HORIZONTAL, 0);
+
+        gtk_style_context_add_class (gtk_widget_get_style_context (player->controls), GTK_STYLE_CLASS_OSD);
+
+        player->play_button = gtk_button_new ();
+        g_signal_connect_swapped (player->play_button, "clicked",
+                                  G_CALLBACK (ev_media_player_toggle_state),
+                                  player);
+        gtk_widget_set_name (player->play_button, "ev-media-player-play-button");
+        gtk_widget_set_valign (player->play_button, GTK_ALIGN_CENTER);
+        gtk_button_set_relief (GTK_BUTTON (player->play_button), GTK_RELIEF_NONE);
+        gtk_button_set_image (GTK_BUTTON (player->play_button),
+                              gtk_image_new_from_icon_name ("media-playback-start-symbolic",
+                                                            GTK_ICON_SIZE_MENU));
+        gtk_button_set_label(GTK_BUTTON (player->play_button), NULL);
+        gtk_button_set_focus_on_click (GTK_BUTTON (player->play_button), FALSE);
+
+        provider = gtk_css_provider_new ();
+        gtk_css_provider_load_from_data (provider, "#ev-media-player-play-button { padding: 0px 8px 0px 8px; 
}", -1, NULL);
+        gtk_style_context_add_provider (gtk_widget_get_style_context (player->play_button),
+                                        GTK_STYLE_PROVIDER (provider),
+                                        GTK_STYLE_PROVIDER_PRIORITY_USER);
+        g_object_unref (provider);
+
+        gtk_box_pack_start (GTK_BOX (player->controls), player->play_button, FALSE, TRUE, 0);
+        gtk_widget_show (player->play_button);
+
+        adjustment = gtk_adjustment_new (0, 0, 1, 0.1, 0.10, 0);
+        player->slider = gtk_scale_new (GTK_ORIENTATION_HORIZONTAL, adjustment);
+        g_signal_connect_swapped (player->slider, "change-value",
+                                  G_CALLBACK (ev_media_player_seek),
+                                  player);
+        gtk_widget_set_hexpand (player->slider, TRUE);
+        gtk_scale_set_draw_value (GTK_SCALE (player->slider), FALSE);
+        gtk_box_pack_start (GTK_BOX (player->controls), player->slider, FALSE, TRUE, 0);
+        gtk_widget_show (player->slider);
+
+        gtk_box_pack_start (GTK_BOX (player), player->controls, FALSE, FALSE, 0);
+        gtk_widget_show (player->controls);
+}
+
+static void
 ev_media_player_constructed (GObject *object)
 {
         EvMediaPlayer *player = EV_MEDIA_PLAYER (object);
 
         G_OBJECT_CLASS (ev_media_player_parent_class)->constructed (object);
 
+        if (ev_media_get_show_controls (player->media))
+                ev_media_player_setup_media_controls (player);
+
         if (!player->pipeline)
                 return;
 
@@ -324,7 +460,8 @@ ev_media_player_constructed (GObject *object)
 static void
 ev_media_player_class_init (EvMediaPlayerClass *klass)
 {
-        GObjectClass *g_object_class = G_OBJECT_CLASS (klass);
+        GObjectClass   *g_object_class = G_OBJECT_CLASS (klass);
+        GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
 
         if (!gst_is_initialized ()) {
                 GError  *error = NULL;
@@ -337,8 +474,8 @@ ev_media_player_class_init (EvMediaPlayerClass *klass)
 
         g_object_class->constructed = ev_media_player_constructed;
         g_object_class->dispose = ev_media_player_dispose;
-        g_object_class->get_property = ev_media_player_get_property;
         g_object_class->set_property = ev_media_player_set_property;
+        widget_class->size_allocate = ev_media_player_size_allocate;
 
         g_object_class_install_property (g_object_class,
                                          PROP_MEDIA,
@@ -349,147 +486,20 @@ ev_media_player_class_init (EvMediaPlayerClass *klass)
                                                               G_PARAM_WRITABLE |
                                                               G_PARAM_CONSTRUCT_ONLY |
                                                               G_PARAM_STATIC_STRINGS));
-        g_object_class_install_property (g_object_class,
-                                         PROP_WINDOW_ID,
-                                         g_param_spec_uint64 ("window-id",
-                                                              "Window ID",
-                                                              "The identifier of the window where the media 
will be rendered",
-                                                              0, G_MAXUINT64, 0,
-                                                              G_PARAM_WRITABLE |
-                                                              G_PARAM_CONSTRUCT_ONLY |
-                                                              G_PARAM_STATIC_STRINGS));
-        g_object_class_install_property (g_object_class,
-                                         PROP_RENDER_AREA,
-                                         g_param_spec_boxed ("render-area",
-                                                             "Render area",
-                                                             "The area of the window where the media will be 
rendered",
-                                                             GDK_TYPE_RECTANGLE,
-                                                             G_PARAM_WRITABLE |
-                                                             G_PARAM_CONSTRUCT |
-                                                             G_PARAM_STATIC_STRINGS));
-        g_object_class_install_property (g_object_class,
-                                         PROP_DURATION,
-                                         g_param_spec_double ("duration",
-                                                              "Duration",
-                                                              "Duration of the media",
-                                                              0, G_MAXDOUBLE, 0,
-                                                              G_PARAM_READABLE |
-                                                              G_PARAM_STATIC_STRINGS));
-        g_object_class_install_property (g_object_class,
-                                         PROP_POSITION,
-                                         g_param_spec_double ("position",
-                                                              "Position",
-                                                              "Current position of the media",
-                                                              0, G_MAXDOUBLE, 0,
-                                                              G_PARAM_READABLE |
-                                                              G_PARAM_STATIC_STRINGS));
-
-        signals[STATE_CHANGED] =
-                g_signal_new ("state-changed",
-                              G_TYPE_FROM_CLASS (g_object_class),
-                              G_SIGNAL_RUN_LAST,
-                              0, NULL, NULL,
-                              g_cclosure_marshal_VOID__UINT,
-                              G_TYPE_NONE, 1, G_TYPE_UINT);
 }
 
-EvMediaPlayer *
-ev_media_player_new (EvMedia      *media,
-                     guint64       window_id,
-                     GdkRectangle *area)
+GtkWidget *
+ev_media_player_new (EvMedia *media)
 {
         g_return_val_if_fail (EV_IS_MEDIA (media), NULL);
-        g_return_val_if_fail (window_id > 0, NULL);
-        g_return_val_if_fail (area != NULL, NULL);
-
-        return EV_MEDIA_PLAYER (g_object_new (EV_TYPE_MEDIA_PLAYER,
-                                              "media", media,
-                                              "window-id", window_id,
-                                              "render-area", area,
-                                              NULL));
-}
 
-void
-ev_media_player_set_render_area (EvMediaPlayer *player,
-                                 GdkRectangle  *area)
-{
-        g_return_if_fail (EV_IS_MEDIA_PLAYER (player));
-        g_return_if_fail (area != NULL);
-
-        if (player->render_area.x == area->x &&
-            player->render_area.y == area->y &&
-            player->render_area.width == area->width &&
-            player->render_area.height == area->height)
-                return;
-
-        player->render_area = *area;
-        if (!player->overlay)
-                return;
-
-        gst_video_overlay_set_render_rectangle (player->overlay, area->x, area->y, area->width, 
area->height);
-        gst_video_overlay_expose (player->overlay);
+        return GTK_WIDGET (g_object_new (EV_TYPE_MEDIA_PLAYER, "media", media, NULL));
 }
 
-void
-ev_media_player_expose (EvMediaPlayer *player)
+EvMedia *
+ev_media_player_get_media (EvMediaPlayer *player)
 {
-        g_return_if_fail (EV_IS_MEDIA_PLAYER (player));
-
-        if (!player->overlay)
-                return;
+        g_return_val_if_fail (EV_IS_MEDIA_PLAYER (player), NULL);
 
-        gst_video_overlay_expose (player->overlay);
-}
-
-gdouble
-ev_media_player_get_duration (EvMediaPlayer *player)
-{
-        g_return_val_if_fail (EV_IS_MEDIA_PLAYER (player), 0);
-
-        return player->duration;
-}
-
-gdouble
-ev_media_player_get_position (EvMediaPlayer *player)
-{
-        g_return_val_if_fail (EV_IS_MEDIA_PLAYER (player), 0);
-
-        return player->position;
-}
-
-void
-ev_media_player_toggle_state (EvMediaPlayer *player)
-{
-        GstState current, pending, new_state;
-
-        g_return_if_fail (EV_IS_MEDIA_PLAYER (player));
-
-        if (!player->pipeline)
-                return;
-
-        gst_element_get_state (player->pipeline, &current, &pending, 0);
-        new_state = current == GST_STATE_PLAYING ? GST_STATE_PAUSED : GST_STATE_PLAYING;
-        if (pending != new_state)
-                gst_element_set_state (player->pipeline, new_state);
-}
-
-void
-ev_media_player_seek (EvMediaPlayer *player,
-                      gdouble        position)
-{
-        g_return_if_fail (EV_IS_MEDIA_PLAYER (player));
-
-        if (!player->pipeline)
-                return;
-
-        position = CLAMP (position, 0, player->duration);
-        if (gst_element_seek_simple (player->pipeline,
-                                     GST_FORMAT_TIME,
-                                     GST_SEEK_FLAG_FLUSH,
-                                     (gint64)(position * GST_SECOND))) {
-                player->is_seeking = TRUE;
-                ev_media_player_update_position_stop (player);
-                player->position = position;
-                g_object_notify (G_OBJECT (player), "position");
-        }
+        return player->media;
 }
diff --git a/libview/ev-media-player.h b/libview/ev-media-player.h
index 083df1e..ef7b686 100644
--- a/libview/ev-media-player.h
+++ b/libview/ev-media-player.h
@@ -22,7 +22,7 @@
 #define EV_MEDIA_PLAYER_H
 
 #include <glib-object.h>
-#include <gdk/gdk.h>
+#include <gtk/gtk.h>
 #include "ev-media.h"
 
 G_BEGIN_DECLS
@@ -42,18 +42,9 @@ typedef enum {
 typedef struct _EvMediaPlayer      EvMediaPlayer;
 typedef struct _EvMediaPlayerClass EvMediaPlayerClass;
 
-GType          ev_media_player_get_type        (void) G_GNUC_CONST;
-EvMediaPlayer *ev_media_player_new             (EvMedia       *media,
-                                                guint64        window_id,
-                                                GdkRectangle  *area);
-void           ev_media_player_set_render_area (EvMediaPlayer *player,
-                                                GdkRectangle  *area);
-void           ev_media_player_expose          (EvMediaPlayer *player);
-gdouble        ev_media_player_get_duration    (EvMediaPlayer *player);
-gdouble        ev_media_player_get_position    (EvMediaPlayer *player);
-void           ev_media_player_toggle_state    (EvMediaPlayer *player);
-void           ev_media_player_seek            (EvMediaPlayer *player,
-                                                gdouble        position);
+GType      ev_media_player_get_type  (void) G_GNUC_CONST;
+GtkWidget *ev_media_player_new       (EvMedia       *media);
+EvMedia   *ev_media_player_get_media (EvMediaPlayer *player);
 
 G_END_DECLS
 
diff --git a/libview/ev-view.c b/libview/ev-view.c
index 9a99954..0ddf1a1 100644
--- a/libview/ev-view.c
+++ b/libview/ev-view.c
@@ -47,14 +47,7 @@
 #include "ev-debug.h"
 
 #ifdef ENABLE_MULTIMEDIA
-#if defined (GDK_WINDOWING_X11)
-#include <gdk/gdkx.h>
-#elif defined (GDK_WINDOWING_WIN32)
-#include <gdk/gdkwin32.h>
-#endif
-
 #include "ev-media-player.h"
-#include "ev-media-controls.h"
 #endif
 
 enum {
@@ -154,6 +147,8 @@ static EvFormField *ev_view_get_form_field_at_location       (EvView
 static EvMedia     *ev_view_get_media_at_location            (EvView             *view,
                                                              gdouble             x,
                                                              gdouble             y);
+static gboolean     ev_view_find_player_for_media            (EvView             *view,
+                                                             EvMedia            *media);
 /*** Annotations ***/
 static EvAnnotation *ev_view_get_annotation_at_location      (EvView             *view,
                                                              gdouble             x,
@@ -2132,7 +2127,7 @@ ev_view_handle_cursor_over_xy (EvView *view, gint x, gint y)
                        ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
                }
        } else if ((media = ev_view_get_media_at_location (view, x, y))) {
-               if (!g_object_get_data (G_OBJECT (media), "view-player"))
+               if (!ev_view_find_player_for_media (view, media))
                        ev_view_set_cursor (view, EV_VIEW_CURSOR_LINK);
                else
                        ev_view_set_cursor (view, EV_VIEW_CURSOR_NORMAL);
@@ -2818,154 +2813,57 @@ ev_view_get_media_at_location (EvView  *view,
        return media_mapping ? media_mapping->data : NULL;
 }
 
-#ifdef ENABLE_MULTIMEDIA
-static void
-media_player_state_changed (EvMediaPlayer *player,
-                           guint          state,
-                           EvMedia       *media)
+static gboolean
+ev_view_find_player_for_media (EvView  *view,
+                              EvMedia *media)
 {
-       /* A media without controls can't be played again */
-       if (state == EV_MEDIA_PLAYER_STATE_PAUSE)
-               g_object_set_data (G_OBJECT (media), "view-player", NULL);
-}
+#ifdef ENABLE_MULTIMEDIA
+       GList *l;
+
+       for (l = view->children; l; l = g_list_next (l)) {
+               EvViewChild *child = (EvViewChild *)l->data;
+
+               if (!EV_IS_MEDIA_PLAYER (child->widget))
+                       continue;
+
+               if (ev_media_player_get_media (EV_MEDIA_PLAYER (child->widget)) == media)
+                       return TRUE;
+       }
 #endif
 
+       return FALSE;
+}
+
 static void
 ev_view_handle_media (EvView  *view,
                      EvMedia *media)
 {
 #ifdef ENABLE_MULTIMEDIA
-       EvMediaPlayer *player;
+       GtkWidget     *player;
        EvMappingList *media_mapping;
+       EvMapping     *mapping;
        GdkRectangle   render_area;
        guint          page;
-       guint64        window_handle;
 
        page = ev_media_get_page_index (media);
        media_mapping = ev_page_cache_get_media_mapping (view->page_cache, page);
 
        /* TODO: focus? */
 
-       player = g_object_get_data (G_OBJECT (media), "view-player");
-       if (player)
+       if (ev_view_find_player_for_media (view, media))
                return;
 
-#if defined (GDK_WINDOWING_X11)
-       window_handle = (guint64)GDK_WINDOW_XID (gtk_widget_get_window (GTK_WIDGET (view)));
-#elif defined (GDK_WINDOWING_WIN32)
-       window_handle = (guint64)GDK_WINDOW_HWND (gtk_widget_get_window (GTK_WIDGET (view)));
-#else
-       g_assert_not_reached ();
-#endif
-
-       ev_view_get_area_from_mapping (view, page, media_mapping, media, &render_area);
-       player = ev_media_player_new (media, window_handle, &render_area);
-       g_object_set_data_full (G_OBJECT (media), "view-player", player, g_object_unref);
-
-       if (ev_media_get_show_controls (media)) {
-               GtkWidget   *controls;
-               EvMapping   *mapping;
-               EvRectangle  doc_rect;
-
-               mapping = ev_mapping_list_find (media_mapping, media);
-               doc_rect.x1 = mapping->area.x1;
-               doc_rect.x2 = mapping->area.x2;
-               doc_rect.y1 = mapping->area.y2;
-               doc_rect.y2 = doc_rect.y1 + 16;
-
-               controls = ev_media_controls_new (player);
-               ev_view_put (view, controls,
-                            render_area.x,
-                            render_area.y + render_area.height,
-                            page, &doc_rect);
-               gtk_widget_show (controls);
-       } else {
-               /* A media without controls will be paused when reaching EOS */
-               g_signal_connect (player, "state-changed",
-                                 G_CALLBACK (media_player_state_changed),
-                                 media);
-       }
-#endif /* ENABLE_MULTIMEDIA */
-}
-
-static void
-ev_view_update_media_render_area (EvView *view)
-{
-#ifdef ENABLE_MULTIMEDIA
-       guint i;
-
-       for (i = view->start_page; i >= 0 && i <= view->end_page; i++) {
-               EvMappingList *media_mapping;
-               GList         *l;
-
-               media_mapping = ev_page_cache_get_media_mapping (view->page_cache, i);
-               if (!media_mapping)
-                       continue;
-
-               for (l = ev_mapping_list_get_list (media_mapping); l; l = g_list_next (l)) {
-                       EvMapping     *mapping = (EvMapping *)l->data;
-                       EvMedia       *media = (EvMedia *)mapping->data;
-                       EvMediaPlayer *player;
-                       GdkRectangle   render_area;
-
-                       player = g_object_get_data (G_OBJECT (media), "view-player");
-                       if (!player)
-                               continue;
-
-                       _ev_view_transform_doc_rect_to_view_rect (view, i,
-                                                                 &mapping->area,
-                                                                 &render_area);
-                       render_area.x -= view->scroll_x;
-                       render_area.y -= view->scroll_y;
-                       ev_media_player_set_render_area (player, &render_area);
-               }
-       }
-#endif
-}
-
-#ifdef ENABLE_MULTIMEDIA
-static void
-draw_media (EvView       *view,
-           cairo_t      *cr,
-           gint          page,
-           GdkRectangle *clip)
-{
-       EvMappingList *media_mapping;
-       GList         *l;
-
-       media_mapping = ev_page_cache_get_media_mapping (view->page_cache, page);
-
-       for (l = ev_mapping_list_get_list (media_mapping); l; l = g_list_next (l)) {
-               EvMapping     *mapping = (EvMapping *)l->data;
-               EvMediaPlayer *player;
-               GdkRectangle   media_rect;
-               GdkRectangle   intersect;
+       player = ev_media_player_new (media);
 
-               player = g_object_get_data (G_OBJECT (mapping->data), "view-player");
-               if (!player)
-                       continue;
+       mapping = ev_mapping_list_find (media_mapping, media);
+       _ev_view_transform_doc_rect_to_view_rect (view, page, &mapping->area, &render_area);
+       render_area.x -= view->scroll_x;
+       render_area.y -= view->scroll_y;
 
-               _ev_view_transform_doc_rect_to_view_rect (view, page,
-                                                         &mapping->area,
-                                                         &media_rect);
-               media_rect.x -= view->scroll_x;
-               media_rect.y -= view->scroll_y;
-
-               /* Draw a black background to avoid showing the builtin poster */
-               if (gdk_rectangle_intersect (&media_rect, clip, &intersect)) {
-                       cairo_save (cr);
-                       cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
-                       cairo_rectangle (cr,
-                                        intersect.x, intersect.y,
-                                        intersect.width, intersect.height);
-                       cairo_fill (cr);
-                       cairo_restore (cr);
-
-                       ev_media_player_expose (player);
-               }
-       }
+       ev_view_put (view, player, render_area.x, render_area.y, page, &mapping->area);
+       gtk_widget_show (player);
+#endif /* ENABLE_MULTIMEDIA */
 }
-#endif
 
 /* Annotations */
 static EvViewWindowChild *
@@ -4194,8 +4092,6 @@ ev_view_size_allocate (GtkWidget      *widget,
                        ev_view_window_child_move (view, child, view_rect.x + root_x, view_rect.y + root_y);
                }
        }
-
-       ev_view_update_media_render_area (view);
 }
 
 static gboolean
@@ -4663,10 +4559,6 @@ ev_view_draw (GtkWidget *widget,
                        draw_focus (view, cr, i, &clip_rect);
                if (page_ready && view->synctex_result)
                        highlight_forward_search_results (view, cr, i);
-#ifdef ENABLE_MULTIMEDIA
-               if (page_ready && EV_IS_DOCUMENT_MEDIA (view->document))
-                       draw_media (view, cr, i, &clip_rect);
-#endif
 #ifdef EV_ENABLE_DEBUG
                if (page_ready)
                        draw_debug_borders (view, cr, i, &clip_rect);
@@ -7649,8 +7541,6 @@ on_adjustment_value_changed (GtkAdjustment *adjustment,
 
        if (view->document)
                view_update_range_and_current_page (view);
-
-       ev_view_update_media_render_area (view);
 }
 
 GtkWidget*


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]