summaryrefslogtreecommitdiff
path: root/src/backend/bacon-video-widget.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/backend/bacon-video-widget.c')
-rw-r--r--src/backend/bacon-video-widget.c999
1 files changed, 150 insertions, 849 deletions
diff --git a/src/backend/bacon-video-widget.c b/src/backend/bacon-video-widget.c
index 030e21224..0564e8598 100644
--- a/src/backend/bacon-video-widget.c
+++ b/src/backend/bacon-video-widget.c
@@ -63,9 +63,6 @@
/* for the cover metadata info */
#include <gst/tag/tag.h>
-#include <clutter-gst/clutter-gst.h>
-#include "totem-aspect-frame.h"
-
/* system */
#include <unistd.h>
#include <time.h>
@@ -83,8 +80,6 @@
#include "totem-gst-pixbuf-helpers.h"
#include "bacon-video-widget.h"
#include "bacon-video-widget-gst-missing-plugins.h"
-#include "bacon-video-controls-actor.h"
-#include "bacon-video-spinner-actor.h"
#include "bacon-video-widget-enums.h"
#define DEFAULT_USER_AGENT "Videos/"VERSION
@@ -92,7 +87,6 @@
#define DEFAULT_CONTROLS_WIDTH 600 /* In pixels */
#define LOGO_SIZE 256 /* Maximum size of the logo */
#define REWIND_OR_PREVIOUS 4000
-#define POPUP_HIDING_TIMEOUT 2
#define MAX_NETWORK_SPEED 10752
#define BUFFERING_LEFT_RATIO 1.1
@@ -127,6 +121,7 @@ enum
SIGNAL_SEEK_REQUESTED,
SIGNAL_TRACK_SKIP_REQUESTED,
SIGNAL_VOLUME_CHANGE_REQUESTED,
+ SIGNAL_PLAY_STARTING,
LAST_SIGNAL
};
@@ -150,7 +145,7 @@ enum
PROP_HUE,
PROP_AUDIO_OUTPUT_TYPE,
PROP_AV_OFFSET,
- PROP_REVEAL_CONTROLS
+ PROP_SHOW_CURSOR,
};
static const gchar *video_props_str[4] = {
@@ -162,7 +157,7 @@ static const gchar *video_props_str[4] = {
struct _BaconVideoWidget
{
- GtkClutterEmbed parent;
+ GtkOverlay parent;
char *user_agent;
@@ -178,8 +173,6 @@ struct _BaconVideoWidget
guint update_id;
guint fill_id;
- GdkPixbuf *logo_pixbuf;
-
gboolean media_has_video;
gboolean media_has_audio;
gint seekable; /* -1 = don't know, FALSE = no */
@@ -197,23 +190,10 @@ struct _BaconVideoWidget
gboolean got_redirect;
- ClutterActor *stage;
- ClutterActor *texture;
- ClutterActor *frame;
- ClutterActor *header_controls;
- ClutterActor *controls;
- ClutterActor *spinner;
-
- ClutterActor *logo_frame;
- ClutterContent *logo;
+ GtkWidget *stack;
GdkCursor *cursor;
- /* Controls */
- gboolean reveal_controls;
- guint transition_timeout_id;
- GHashTable *busy_popup_ht; /* key=reason string, value=gboolean */
-
/* Visual effects */
GstElement *audio_capsfilter;
GstElement *audio_pitchcontrol;
@@ -230,10 +210,6 @@ struct _BaconVideoWidget
gint video_width; /* Movie width */
gint video_height; /* Movie height */
- gint movie_par_n; /* Movie pixel aspect ratio numerator */
- gint movie_par_d; /* Movie pixel aspect ratio denominator */
- gint video_width_pixels; /* Scaled movie width */
- gint video_height_pixels; /* Scaled movie height */
gint video_fps_n;
gint video_fps_d;
@@ -279,7 +255,7 @@ struct _BaconVideoWidget
float rate;
};
-G_DEFINE_TYPE_WITH_CODE (BaconVideoWidget, bacon_video_widget, GTK_CLUTTER_TYPE_EMBED,
+G_DEFINE_TYPE_WITH_CODE (BaconVideoWidget, bacon_video_widget, GTK_TYPE_OVERLAY,
G_IMPLEMENT_INTERFACE (G_TYPE_INITABLE,
bacon_video_widget_initable_iface_init))
@@ -302,9 +278,6 @@ static gboolean bacon_video_widget_seek_time_no_lock (BaconVideoWidget *bvw,
gint64 _time,
GstSeekFlags flag,
GError **error);
-static void set_controls_visibility (BaconVideoWidget *bvw,
- gboolean visible,
- gboolean animate);
typedef struct {
GstTagList *tags;
@@ -399,245 +372,12 @@ bvw_check_if_video_decoder_is_missing (BaconVideoWidget * bvw)
}
static void
-set_display_pixel_aspect_ratio (GdkMonitor *monitor,
- GValue *value)
-{
- static const gint par[][2] = {
- {1, 1}, /* regular screen */
- {16, 15}, /* PAL TV */
- {11, 10}, /* 525 line Rec.601 video */
- {54, 59}, /* 625 line Rec.601 video */
- {64, 45}, /* 1280x1024 on 16:9 display */
- {5, 3}, /* 1280x1024 on 4:3 display */
- {4, 3} /* 800x600 on 16:9 display */
- };
- guint i;
- gint par_index;
- gdouble ratio;
- gdouble delta;
- GdkRectangle rect;
-
-#define DELTA(idx) (ABS (ratio - ((gdouble) par[idx][0] / par[idx][1])))
-
- /* first calculate the "real" ratio based on the X values;
- * which is the "physical" w/h divided by the w/h in pixels of the display */
- gdk_monitor_get_geometry (monitor, &rect);
-
- ratio = (gdouble) (gdk_monitor_get_width_mm (monitor) * rect.height) /
- (gdk_monitor_get_height_mm (monitor) * rect.width);
-
- GST_DEBUG ("calculated pixel aspect ratio: %f", ratio);
- /* now find the one from par[][2] with the lowest delta to the real one */
- delta = DELTA (0);
- par_index = 0;
-
- for (i = 1; i < sizeof (par) / (sizeof (gint) * 2); ++i) {
- gdouble this_delta = DELTA (i);
-
- if (this_delta < delta) {
- par_index = i;
- delta = this_delta;
- }
- }
-
- GST_DEBUG ("Decided on index %d (%d/%d)", par_index,
- par[par_index][0], par[par_index][1]);
- gst_value_set_fraction (value, par[par_index][0], par[par_index][1]);
-}
-
-static void
-get_media_size (BaconVideoWidget *bvw, gint *width, gint *height)
-{
- if (bvw->media_has_video) {
- GValue disp_par = {0, };
- guint movie_par_n, movie_par_d, disp_par_n, disp_par_d, num, den;
-
- /* Create and init the fraction value */
- g_value_init (&disp_par, GST_TYPE_FRACTION);
-
- /* Square pixel is our default */
- gst_value_set_fraction (&disp_par, 1, 1);
-
- /* Now try getting display's pixel aspect ratio */
- if (gtk_widget_get_realized (GTK_WIDGET (bvw))) {
- GdkDisplay *display;
- GdkWindow *window;
- GdkMonitor *monitor;
-
- display = gtk_widget_get_display (GTK_WIDGET (bvw));
- window = gtk_widget_get_window (GTK_WIDGET (bvw));
- if (window)
- monitor = gdk_display_get_monitor_at_window (display, window);
- else
- monitor = gdk_display_get_primary_monitor (display);
- set_display_pixel_aspect_ratio (monitor, &disp_par);
- }
-
- disp_par_n = gst_value_get_fraction_numerator (&disp_par);
- disp_par_d = gst_value_get_fraction_denominator (&disp_par);
-
- GST_DEBUG ("display PAR is %d/%d", disp_par_n, disp_par_d);
-
- /* If movie pixel aspect ratio is enforced, use that */
- if (bvw->ratio_type != BVW_RATIO_AUTO) {
- switch (bvw->ratio_type) {
- case BVW_RATIO_SQUARE:
- movie_par_n = 1;
- movie_par_d = 1;
- break;
- case BVW_RATIO_FOURBYTHREE:
- movie_par_n = 4 * bvw->video_height;
- movie_par_d = 3 * bvw->video_width;
- break;
- case BVW_RATIO_ANAMORPHIC:
- movie_par_n = 16 * bvw->video_height;
- movie_par_d = 9 * bvw->video_width;
- break;
- case BVW_RATIO_DVB:
- movie_par_n = 20 * bvw->video_height;
- movie_par_d = 9 * bvw->video_width;
- break;
- /* handle these to avoid compiler warnings */
- case BVW_RATIO_AUTO:
- default:
- movie_par_n = 0;
- movie_par_d = 0;
- g_assert_not_reached ();
- }
- } else {
- /* Use the movie pixel aspect ratio if any */
- movie_par_n = bvw->movie_par_n;
- movie_par_d = bvw->movie_par_d;
- }
-
- GST_DEBUG ("movie PAR is %d/%d", movie_par_n, movie_par_d);
-
- if (bvw->video_width == 0 || bvw->video_height == 0) {
- GST_DEBUG ("width and/or height 0, assuming 1/1 ratio");
- num = 1;
- den = 1;
- } else if (!gst_video_calculate_display_ratio (&num, &den,
- bvw->video_width, bvw->video_height,
- movie_par_n, movie_par_d, disp_par_n, disp_par_d)) {
- GST_WARNING ("overflow calculating display aspect ratio!");
- num = 1; /* FIXME: what values to use here? */
- den = 1;
- }
-
- GST_DEBUG ("calculated scaling ratio %d/%d for video %dx%d", num, den,
- bvw->video_width, bvw->video_height);
-
- /* now find a width x height that respects this display ratio.
- * prefer those that have one of w/h the same as the incoming video
- * using wd / hd = num / den */
-
- /* start with same height, because of interlaced video */
- /* check hd / den is an integer scale factor, and scale wd with the PAR */
- if (bvw->video_height % den == 0) {
- GST_DEBUG ("keeping video height");
- bvw->video_width_pixels =
- (guint) gst_util_uint64_scale (bvw->video_height, num, den);
- bvw->video_height_pixels = bvw->video_height;
- } else if (bvw->video_width % num == 0) {
- GST_DEBUG ("keeping video width");
- bvw->video_width_pixels = bvw->video_width;
- bvw->video_height_pixels =
- (guint) gst_util_uint64_scale (bvw->video_width, den, num);
- } else {
- GST_DEBUG ("approximating while keeping video height");
- bvw->video_width_pixels =
- (guint) gst_util_uint64_scale (bvw->video_height, num, den);
- bvw->video_height_pixels = bvw->video_height;
- }
- GST_DEBUG ("scaling to %dx%d", bvw->video_width_pixels,
- bvw->video_height_pixels);
-
- *width = bvw->video_width_pixels;
- *height = bvw->video_height_pixels;
-
- /* Free the PAR fraction */
- g_value_unset (&disp_par);
- }
- else {
- if (bvw->logo_pixbuf) {
- *width = gdk_pixbuf_get_width (bvw->logo_pixbuf);
- *height = gdk_pixbuf_get_height (bvw->logo_pixbuf);
- if (*width == *height) {
- /* The icons will be square, so lie so we get a 16:9
- * ratio */
- *width = (int) ((float) *height / 9. * 16.);
- }
- } else {
- *width = 0;
- *height = 0;
- }
- }
-}
-
-static gboolean
-leave_notify_cb (GtkWidget *widget,
- GdkEventCrossing *event,
- gpointer user_data)
-{
- gboolean res = GDK_EVENT_PROPAGATE;
- BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (user_data);
- GdkDevice *device;
-
- if (event->detail != GDK_NOTIFY_NONLINEAR &&
- event->detail != GDK_NOTIFY_NONLINEAR_VIRTUAL)
- return res;
-
- device = gdk_event_get_source_device ((GdkEvent *) event);
- if (gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN)
- return res;
-
- if (bvw->reveal_controls) {
- gboolean not_busy;
-
- not_busy = g_hash_table_size (bvw->busy_popup_ht) == 0;
- if (not_busy) {
- GST_DEBUG ("will hide because we're not busy and cursor left");
- set_controls_visibility (bvw, FALSE, TRUE);
- }
- }
-
- return res;
-}
-
-static void
-bvw_set_logo (BaconVideoWidget *bvw, const gchar *name)
-{
- GtkIconTheme *theme;
- GError *error = NULL;
-
- theme = gtk_icon_theme_get_for_screen (gtk_widget_get_screen (GTK_WIDGET (bvw)));
- bvw->logo_pixbuf = gtk_icon_theme_load_icon (theme, name, LOGO_SIZE, 0, &error);
-
- if (error) {
- g_warning ("An error occurred trying to open logo %s: %s", name, error->message);
- g_error_free (error);
- return;
- }
-}
-
-static void
bacon_video_widget_realize (GtkWidget * widget)
{
BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
- GtkWidget *toplevel;
GTK_WIDGET_CLASS (parent_class)->realize (widget);
- gtk_widget_set_realized (widget, TRUE);
-
- bvw_set_logo (bvw, APPLICATION_ID);
-
- /* setup the toplevel, ready to be resized */
- toplevel = gtk_widget_get_toplevel (widget);
- gtk_window_set_geometry_hints (GTK_WINDOW (toplevel), widget, NULL, 0);
- g_signal_connect (G_OBJECT (toplevel), "leave-notify-event",
- G_CALLBACK (leave_notify_cb), bvw);
-
bvw->missing_plugins_cancellable = g_cancellable_new ();
g_object_set_data_full (G_OBJECT (bvw), "missing-plugins-cancellable",
bvw->missing_plugins_cancellable, g_object_unref);
@@ -648,16 +388,9 @@ static void
bacon_video_widget_unrealize (GtkWidget *widget)
{
BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
- GtkWidget *toplevel;
GTK_WIDGET_CLASS (parent_class)->unrealize (widget);
- gtk_widget_set_realized (widget, FALSE);
-
- toplevel = gtk_widget_get_toplevel (widget);
- g_signal_handlers_disconnect_by_func (G_OBJECT (toplevel),
- leave_notify_cb, bvw);
-
g_cancellable_cancel (bvw->missing_plugins_cancellable);
bvw->missing_plugins_cancellable = NULL;
g_object_set_data (G_OBJECT (bvw), "missing-plugins-cancellable", NULL);
@@ -668,119 +401,10 @@ set_current_actor (BaconVideoWidget *bvw)
{
gboolean draw_logo;
- if (bvw->stage == NULL)
- return;
-
- /* If there's only audio draw the logo as well. */
+ /* If there's only audio draw the logo */
draw_logo = bvw->media_has_audio && !bvw->media_has_video;
-
- if (draw_logo) {
- if (bvw->logo_pixbuf != NULL) {
- gboolean ret;
- GError *err = NULL;
-
- ret = clutter_image_set_data (CLUTTER_IMAGE (bvw->logo),
- gdk_pixbuf_get_pixels (bvw->logo_pixbuf),
- gdk_pixbuf_get_has_alpha (bvw->logo_pixbuf) ? COGL_PIXEL_FORMAT_RGBA_8888 : COGL_PIXEL_FORMAT_RGB_888,
- gdk_pixbuf_get_width (bvw->logo_pixbuf),
- gdk_pixbuf_get_height (bvw->logo_pixbuf),
- gdk_pixbuf_get_rowstride (bvw->logo_pixbuf),
- &err);
- if (ret == FALSE) {
- g_warning ("clutter_image_set_data() failed %s", err->message);
- g_error_free (err);
- } else {
- clutter_actor_show (CLUTTER_ACTOR (bvw->logo_frame));
- clutter_actor_hide (CLUTTER_ACTOR (bvw->frame));
- return;
- }
- }
- }
-
- clutter_actor_show (CLUTTER_ACTOR (bvw->frame));
- clutter_actor_hide (CLUTTER_ACTOR (bvw->logo_frame));
-}
-
-static void
-unschedule_hiding_popup (BaconVideoWidget *bvw)
-{
- if (bvw->transition_timeout_id > 0)
- g_source_remove (bvw->transition_timeout_id);
- bvw->transition_timeout_id = 0;
-}
-
-static gboolean
-hide_popup_timeout_cb (BaconVideoWidget *bvw)
-{
- set_controls_visibility (bvw, FALSE, TRUE);
- unschedule_hiding_popup (bvw);
- return G_SOURCE_REMOVE;
-}
-
-static void
-schedule_hiding_popup (BaconVideoWidget *bvw)
-{
- unschedule_hiding_popup (bvw);
- bvw->transition_timeout_id = g_timeout_add_seconds (POPUP_HIDING_TIMEOUT, (GSourceFunc) hide_popup_timeout_cb, bvw);
- g_source_set_name_by_id (bvw->transition_timeout_id, "[totem] hide_popup_timeout_cb");
-}
-
-static void
-set_show_cursor (BaconVideoWidget *bvw,
- gboolean show_cursor)
-{
- GdkWindow *window;
-
- bvw->cursor_shown = show_cursor;
- window = gtk_widget_get_window (GTK_WIDGET (bvw));
-
- if (!window)
- return;
-
- if (show_cursor == FALSE) {
- GdkCursor *cursor;
- GdkDisplay *display;
-
- display = gdk_window_get_display (window);
- cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR);
- gdk_window_set_cursor (window, cursor);
- g_object_unref (cursor);
- } else {
- gdk_window_set_cursor (window, bvw->cursor);
- }
-}
-
-static void
-set_controls_visibility (BaconVideoWidget *bvw,
- gboolean visible,
- gboolean animate)
-{
- guint8 opacity = visible ? OVERLAY_OPACITY : 0;
- gint header_controls_height;
- gfloat header_controls_y;
- guint duration;
-
- gtk_widget_get_preferred_height (gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (bvw->header_controls)),
- NULL,
- &header_controls_height);
- header_controls_y = visible ? 0 : -header_controls_height;
-
- duration = animate ? 250 : 0;
-
- /* FIXME:
- * Using a show/hide seems to not trigger the
- * controls to redraw, so let's change the opacity instead */
- clutter_actor_set_easing_duration (bvw->controls, duration);
- clutter_actor_set_easing_duration (bvw->header_controls, duration);
- clutter_actor_set_opacity (bvw->controls, opacity);
- clutter_actor_set_y (bvw->header_controls, header_controls_y);
-
- set_show_cursor (bvw, visible);
- if (visible && animate)
- schedule_hiding_popup (bvw);
-
- bvw->reveal_controls = visible;
- g_object_notify (G_OBJECT (bvw), "reveal-controls");
+ gtk_stack_set_visible_child_name (GTK_STACK (bvw->stack),
+ draw_logo ? "logo" : "video");
}
static void
@@ -802,22 +426,6 @@ translate_coords (GtkWidget *widget,
}
}
-static gboolean
-ignore_event (BaconVideoWidget *bvw,
- int x,
- int y)
-{
- ClutterActor *actor;
-
- actor = clutter_stage_get_actor_at_pos (CLUTTER_STAGE (bvw->stage), CLUTTER_PICK_REACTIVE, x, y);
-
- /* Eat the GTK+ event if we're not clicking on the video itself */
- if (actor == bvw->controls)
- return TRUE;
-
- return FALSE;
-}
-
/* need to use gstnavigation interface for these vmethods, to allow for the sink
to map screen coordinates to video coordinates in the presence of e.g.
hardware scaling */
@@ -827,8 +435,6 @@ bacon_video_widget_motion_notify (GtkWidget *widget, GdkEventMotion *event)
{
gboolean res = GDK_EVENT_PROPAGATE;
BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
- GdkDevice *device;
- int x, y;
g_return_val_if_fail (bvw->play != NULL, FALSE);
@@ -838,21 +444,6 @@ bacon_video_widget_motion_notify (GtkWidget *widget, GdkEventMotion *event)
if (GTK_WIDGET_CLASS (parent_class)->motion_notify_event)
res |= GTK_WIDGET_CLASS (parent_class)->motion_notify_event (widget, event);
- device = gdk_event_get_source_device ((GdkEvent *) event);
- if (gdk_device_get_source (device) == GDK_SOURCE_TOUCHSCREEN)
- return res;
-
- if (!bvw->reveal_controls)
- set_controls_visibility (bvw, TRUE, TRUE);
-
- translate_coords (widget, event->window, event->x, event->y, &x, &y);
- if (ignore_event (bvw, x, y)) {
- /* Is the mouse on the popups? */
- unschedule_hiding_popup (bvw);
- } else {
- schedule_hiding_popup (bvw);
- }
-
return res;
}
@@ -861,7 +452,6 @@ bacon_video_widget_button_press_or_release (GtkWidget *widget, GdkEventButton *e
{
gboolean res = FALSE;
BaconVideoWidget *bvw = BACON_VIDEO_WIDGET (widget);
- int x, y;
GdkDevice *device;
device = gdk_event_get_source_device ((GdkEvent *) event);
@@ -870,10 +460,6 @@ bacon_video_widget_button_press_or_release (GtkWidget *widget, GdkEventButton *e
g_return_val_if_fail (bvw->play != NULL, FALSE);
- translate_coords (widget, event->window, event->x, event->y, &x, &y);
- if (ignore_event (bvw, x, y))
- return GDK_EVENT_STOP;
-
if (event->type != GDK_BUTTON_PRESS &&
event->type != GDK_BUTTON_RELEASE)
goto bail;
@@ -881,8 +467,10 @@ bacon_video_widget_button_press_or_release (GtkWidget *widget, GdkEventButton *e
if (bvw->navigation &&
event->button == 1 &&
bvw->is_menu != FALSE) {
+ int x, y;
const char *event_str;
event_str = (event->type == GDK_BUTTON_PRESS) ? "mouse-button-press" : "mouse-button-release";
+ translate_coords (widget, event->window, event->x, event->y, &x, &y);
gst_navigation_send_mouse_event (bvw->navigation,
event_str, event->button, x, y);
@@ -900,49 +488,6 @@ bail:
return res;
}
-static gboolean
-bacon_video_widget_handle_scroll (GtkWidget *widget,
- GdkEventScroll *event,
- BaconVideoWidget *bvw)
-{
- int x, y;
- gboolean forward;
- gdouble delta_y;
-
- g_return_val_if_fail (bvw->play != NULL, FALSE);
-
- if (event->direction != GDK_SCROLL_SMOOTH)
- return GDK_EVENT_PROPAGATE;
-
- if (widget == (gpointer) bvw) {
- translate_coords (widget, event->window, event->x, event->y, &x, &y);
- if (ignore_event (bvw, x, y))
- return GDK_EVENT_STOP;
- }
-
- gdk_event_get_scroll_deltas ((GdkEvent *) event, NULL, &delta_y);
- if (delta_y == 0.0)
- return GDK_EVENT_PROPAGATE;
- forward = delta_y >= 0.0 ? FALSE : TRUE;
-
- if (widget == (gpointer) bvw ||
- widget == g_object_get_data (G_OBJECT (bvw->controls), "seek_scale")) {
- if (bvw->seekable > 0)
- g_signal_emit (G_OBJECT (bvw), bvw_signals[SIGNAL_SEEK_REQUESTED], 0, forward);
- } else if (widget == g_object_get_data (G_OBJECT (bvw->controls), "volume_button")) {
- if (bacon_video_widget_can_set_volume (bvw))
- g_signal_emit (G_OBJECT (bvw), bvw_signals[SIGNAL_VOLUME_CHANGE_REQUESTED], 0, forward);
- }
-
- return GDK_EVENT_STOP;
-}
-
-static gboolean
-bacon_video_widget_scroll (GtkWidget *widget, GdkEventScroll *event)
-{
- return bacon_video_widget_handle_scroll (widget, event, BACON_VIDEO_WIDGET (widget));
-}
-
static void
bacon_video_widget_get_preferred_width (GtkWidget *widget,
gint *minimum,
@@ -980,8 +525,6 @@ bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
GObjectClass *object_class;
GtkWidgetClass *widget_class;
- clutter_gst_init (NULL, NULL);
-
object_class = (GObjectClass *) klass;
widget_class = (GtkWidgetClass *) klass;
@@ -996,7 +539,6 @@ bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
widget_class->motion_notify_event = bacon_video_widget_motion_notify;
widget_class->button_press_event = bacon_video_widget_button_press_or_release;
widget_class->button_release_event = bacon_video_widget_button_press_or_release;
- widget_class->scroll_event = bacon_video_widget_scroll;
/* GObject */
object_class->set_property = bacon_video_widget_set_property;
@@ -1174,14 +716,14 @@ bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
G_PARAM_STATIC_STRINGS));
/**
- * BaconVideoWidget:reveal-controls:
+ * BaconVideoWidget:show-cursor:
*
- * Whether to show or hide the controls.
+ * Whether the mouse cursor is shown.
**/
- g_object_class_install_property (object_class, PROP_REVEAL_CONTROLS,
- g_param_spec_boolean ("reveal-controls", "Reveal controls",
- "Whether to show or hide the controls.", FALSE,
- G_PARAM_READABLE |
+ g_object_class_install_property (object_class, PROP_SHOW_CURSOR,
+ g_param_spec_boolean ("show-cursor", "Show cursor",
+ "Whether the mouse cursor is shown.", FALSE,
+ G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS));
/* Signals */
@@ -1384,6 +926,25 @@ bacon_video_widget_class_init (BaconVideoWidgetClass * klass)
0,
NULL, NULL,
g_cclosure_marshal_generic, G_TYPE_NONE, 1, G_TYPE_BOOLEAN);
+
+ /**
+ * BaconVideoWidget::play-starting:
+ * @bvw: the #BaconVideoWidget which received the signal
+ *
+ * Emitted when a movie will start playing, meaning it's not buffering, or paused
+ * waiting for plugins to be installed, drives to be mounted or authentication
+ * to succeed.
+ *
+ * This usually means that OSD popups can be hidden.
+ *
+ **/
+ bvw_signals[SIGNAL_PLAY_STARTING] =
+ g_signal_new ("play-starting",
+ G_TYPE_FROM_CLASS (object_class),
+ G_SIGNAL_RUN_LAST,
+ 0,
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID, G_TYPE_NONE, 0);
}
static void
@@ -1395,14 +956,11 @@ bacon_video_widget_init (BaconVideoWidget * bvw)
g_type_class_ref (BVW_TYPE_DVD_EVENT);
g_type_class_ref (BVW_TYPE_ROTATION);
- g_object_set (G_OBJECT (bvw), "use-layout-size", TRUE, NULL);
-
bvw->update_id = 0;
bvw->tagcache = NULL;
bvw->audiotags = NULL;
bvw->videotags = NULL;
bvw->volume = -1.0;
- bvw->movie_par_n = bvw->movie_par_d = 1;
bvw->rate = FORWARD_RATE;
bvw->tag_update_queue = g_async_queue_new_full ((GDestroyNotify) update_tags_delayed_data_destroy);
@@ -1421,8 +979,6 @@ bacon_video_widget_init (BaconVideoWidget * bvw)
bvw->auth_last_result = G_MOUNT_OPERATION_HANDLED;
bvw->auth_dialog = NULL;
- bvw->busy_popup_ht = g_hash_table_new_full (g_str_hash, g_str_equal, g_free, NULL);
-
bacon_video_widget_gst_missing_plugins_block ();
}
@@ -1455,15 +1011,7 @@ bvw_handle_application_message (BaconVideoWidget *bvw, GstMessage *msg)
bvw_update_stream_info (bvw);
}
else if (strcmp (msg_name, "video-size") == 0) {
- int w, h;
-
g_signal_emit (bvw, bvw_signals[SIGNAL_GOT_METADATA], 0, NULL);
-
- /* This is necessary for the pixel-aspect-ratio of the
- * display to be taken into account. */
- get_media_size (bvw, &w, &h);
- clutter_actor_set_size (bvw->texture, w, h);
-
set_current_actor (bvw);
} else {
g_debug ("Unhandled application message %s", msg_name);
@@ -1600,7 +1148,7 @@ bvw_handle_element_message (BaconVideoWidget *bvw, GstMessage *msg)
val = gst_structure_get_value (structure, "file");
if (val == NULL)
goto done;
-
+
file = G_FILE (g_value_get_object (val));
if (file == NULL)
goto done;
@@ -1977,37 +1525,6 @@ bvw_check_missing_plugins_on_preroll (BaconVideoWidget * bvw)
}
static void
-update_orientation_from_video (BaconVideoWidget *bvw)
-{
- BvwRotation rotation = BVW_ROTATION_R_ZERO;
- char *orientation_str = NULL;
- gboolean ret;
- gdouble angle;
-
- /* Don't change the rotation if explicitely set */
- if (bvw->rotation != BVW_ROTATION_R_ZERO)
- return;
-
- ret = gst_tag_list_get_string_index (bvw->tagcache,
- GST_TAG_IMAGE_ORIENTATION, 0, &orientation_str);
- if (!ret || !orientation_str || g_str_equal (orientation_str, "rotate-0"))
- rotation = BVW_ROTATION_R_ZERO;
- else if (g_str_equal (orientation_str, "rotate-90"))
- rotation = BVW_ROTATION_R_90R;
- else if (g_str_equal (orientation_str, "rotate-180"))
- rotation = BVW_ROTATION_R_180;
- else if (g_str_equal (orientation_str, "rotate-270"))
- rotation = BVW_ROTATION_R_90L;
- else
- g_warning ("Unhandled orientation value: '%s'", orientation_str);
-
- g_free (orientation_str);
-
- angle = rotation * 90.0;
- totem_aspect_frame_set_rotation (TOTEM_ASPECT_FRAME (bvw->frame), angle);
-}
-
-static void
bvw_update_tags (BaconVideoWidget * bvw, GstTagList *tag_list, const gchar *type)
{
GstTagList **cache = NULL;
@@ -2048,8 +1565,6 @@ bvw_update_tags (BaconVideoWidget * bvw, GstTagList *tag_list, const gchar *type
g_signal_emit (bvw, bvw_signals[SIGNAL_GOT_METADATA], 0);
- update_orientation_from_video (bvw);
-
set_current_actor (bvw);
}
@@ -2215,15 +1730,6 @@ bvw_handle_buffering_message (GstMessage * message, BaconVideoWidget *bvw)
g_signal_emit (bvw, bvw_signals[SIGNAL_BUFFERING], 0, (gdouble) percent / 100.0);
if (percent >= 100) {
- clutter_actor_hide (bvw->spinner);
- /* Reset */
- g_object_set (G_OBJECT (bvw->spinner), "percent", 0.0, NULL);
- } else {
- clutter_actor_show (bvw->spinner);
- g_object_set (G_OBJECT (bvw->spinner), "percent", (float) percent, NULL);
- }
-
- if (percent >= 100) {
/* a 100% message means buffering is done */
bvw->buffering = FALSE;
/* if the desired state is playing, go back */
@@ -2833,29 +2339,12 @@ caps_set (GObject * obj,
/* Get video decoder caps */
s = gst_caps_get_structure (caps, 0);
if (s) {
- const GValue *movie_par;
-
/* We need at least width/height and framerate */
- if (!(gst_structure_get_fraction (s, "framerate", &bvw->video_fps_n,
+ if (!(gst_structure_get_fraction (s, "framerate", &bvw->video_fps_n,
&bvw->video_fps_d) &&
gst_structure_get_int (s, "width", &bvw->video_width) &&
gst_structure_get_int (s, "height", &bvw->video_height)))
return;
-
- /* Get the movie PAR if available */
- movie_par = gst_structure_get_value (s, "pixel-aspect-ratio");
- if (movie_par) {
- bvw->movie_par_n = gst_value_get_fraction_numerator (movie_par);
- bvw->movie_par_d = gst_value_get_fraction_denominator (movie_par);
- }
- else {
- /* Square pixels */
- bvw->movie_par_n = 1;
- bvw->movie_par_d = 1;
- }
-
- /* Now set for real */
- bacon_video_widget_set_aspect_ratio (bvw, bvw->ratio_type);
}
gst_caps_unref (caps);
@@ -2921,8 +2410,6 @@ bacon_video_widget_finalize (GObject * object)
g_type_class_unref (g_type_class_peek (BVW_TYPE_DVD_EVENT));
g_type_class_unref (g_type_class_peek (BVW_TYPE_ROTATION));
- unschedule_hiding_popup (bvw);
-
if (bvw->bus) {
/* make bus drop all messages to make sure none of our callbacks is ever
* called again (main loop might be run again to display error dialog) */
@@ -2938,7 +2425,6 @@ bacon_video_widget_finalize (GObject * object)
g_clear_pointer (&bvw->referrer, g_free);
g_clear_pointer (&bvw->mrl, g_free);
g_clear_pointer (&bvw->subtitle_uri, g_free);
- g_clear_pointer (&bvw->busy_popup_ht, g_hash_table_destroy);
g_clear_object (&bvw->clock);
@@ -3020,6 +2506,9 @@ bacon_video_widget_set_property (GObject * object, guint property_id,
case PROP_AV_OFFSET:
g_object_set_property (G_OBJECT (bvw->play), "av-offset", value);
break;
+ case PROP_SHOW_CURSOR:
+ bacon_video_widget_set_show_cursor (bvw, g_value_get_boolean (value));
+ break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
break;
@@ -3080,8 +2569,8 @@ bacon_video_widget_get_property (GObject * object, guint property_id,
case PROP_AV_OFFSET:
g_object_get_property (G_OBJECT (bvw->play), "av-offset", value);
break;
- case PROP_REVEAL_CONTROLS:
- g_value_set_boolean (value, bvw->reveal_controls);
+ case PROP_SHOW_CURSOR:
+ g_value_set_boolean (value, bvw->cursor_shown);
break;
default:
G_OBJECT_WARN_INVALID_PROPERTY_ID (object, property_id, pspec);
@@ -3678,113 +3167,6 @@ bacon_video_widget_set_audio_output_type (BaconVideoWidget *bvw,
set_audio_filter (bvw);
}
-/**
- * bacon_video_widget_show_popup:
- * @bvw: a #BaconVideoWidget
- *
- * Show the video controls popup, and schedule for it to be hidden again after
- * a timeout.
- *
- * Since: 3.12
- */
-void
-bacon_video_widget_show_popup (BaconVideoWidget *bvw)
-{
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
-
- set_controls_visibility (bvw, TRUE, FALSE);
- schedule_hiding_popup (bvw);
-}
-
-/**
- * bacon_video_widget_mark_popup_busy:
- * @bvw: a #BaconVideoWidget
- * @reason: human-readable reason for the controls popup being marked as busy
- *
- * Mark the video controls popup as busy, for the given @reason. Use
- * bacon_video_widget_unmark_popup_busy() to undo.
- *
- * Since: 3.12
- */
-void
-bacon_video_widget_mark_popup_busy (BaconVideoWidget *bvw,
- const char *reason)
-{
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
-
- g_hash_table_insert (bvw->busy_popup_ht,
- g_strdup (reason),
- GINT_TO_POINTER (1));
-
- set_controls_visibility (bvw, TRUE, FALSE);
-
- GST_DEBUG ("Adding popup busy for reason %s", reason);
-
- unschedule_hiding_popup (bvw);
-}
-
-/**
- * bacon_video_widget_unmark_popup_busy:
- * @bvw: a #BaconVideoWidget
- * @reason: human-readable reason for the controls popup being unmarked as busy
- *
- * Unmark the video controls popup as busy, for the given @reason. The popup
- * must previously have been marked as busy using
- * bacon_video_widget_mark_popup_busy().
- *
- * Since: 3.12
- */
-void
-bacon_video_widget_unmark_popup_busy (BaconVideoWidget *bvw,
- const char *reason)
-{
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
-
- g_hash_table_remove (bvw->busy_popup_ht, reason);
-
- GST_DEBUG ("Removing popup busy for reason %s", reason);
-
- if (g_hash_table_size (bvw->busy_popup_ht) == 0 &&
- clutter_actor_get_opacity (bvw->controls) != 0) {
- GST_DEBUG ("Will hide popup soon");
- schedule_hiding_popup (bvw);
- }
-}
-
-/**
- * bacon_video_widget_get_controls_object:
- * @bvw: a #BaconVideoWidget
- *
- * Get the widget which displays the video controls.
- *
- * Returns: (transfer none): controls widget
- * Since: 3.12
- */
-GObject *
-bacon_video_widget_get_controls_object (BaconVideoWidget *bvw)
-{
- g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), NULL);
-
- return G_OBJECT (bvw->controls);
-}
-
-/**
- * bacon_video_widget_get_header_controls_object:
- * @bvw: a #BaconVideoWidget
- *
- * Get the widget which displays the video header controls.
- *
- * Returns: (transfer none): header controls widget
- * Since: 3.20
- */
-GObject *
-bacon_video_widget_get_header_controls_object (BaconVideoWidget *bvw)
-{
- g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), NULL);
-
- return G_OBJECT (gtk_clutter_actor_get_widget (GTK_CLUTTER_ACTOR (bvw->header_controls)));
-}
-
/* =========================================== */
/* */
/* Play/Pause, Stop */
@@ -4059,8 +3441,6 @@ bacon_video_widget_open (BaconVideoWidget *bvw,
bvw->target_state = GST_STATE_PAUSED;
bvw_clear_missing_plugins_messages (bvw);
- bacon_video_widget_mark_popup_busy (bvw, "opening file");
-
gst_element_set_state (bvw->play, GST_STATE_PAUSED);
g_signal_emit (bvw, bvw_signals[SIGNAL_CHANNELS_CHANGE], 0);
@@ -4125,7 +3505,7 @@ bacon_video_widget_play (BaconVideoWidget * bvw, GError ** error)
return FALSE;
}
- bacon_video_widget_unmark_popup_busy (bvw, "opening file");
+ g_signal_emit (bvw, bvw_signals[SIGNAL_PLAY_STARTING], 0);
GST_DEBUG ("play");
gst_element_set_state (bvw->play, GST_STATE_PLAYING);
@@ -4334,10 +3714,10 @@ bvw_stop_play_pipeline (BaconVideoWidget * bvw)
g_clear_pointer (&bvw->download_filename, g_free);
bvw->buffering_left = -1;
bvw_reconfigure_fill_timeout (bvw, 0);
- bvw->movie_par_n = bvw->movie_par_d = 1;
- clutter_actor_hide (bvw->spinner);
- g_object_set (G_OBJECT (bvw->spinner), "percent", 0.0, NULL);
- totem_aspect_frame_set_internal_rotation (TOTEM_ASPECT_FRAME (bvw->frame), 0.0);
+ g_signal_emit (bvw, bvw_signals[SIGNAL_BUFFERING], 0, 100.0);
+ g_object_set (bvw->video_sink,
+ "rotate-method", GST_VIDEO_ORIENTATION_AUTO,
+ NULL);
GST_DEBUG ("stopped");
}
@@ -4800,6 +4180,43 @@ bacon_video_widget_get_volume (BaconVideoWidget * bvw)
}
/**
+ * bacon_video_widget_set_show_cursor:
+ * @bvw: a #BaconVideoWidget
+ * @show_cursor: %TRUE to show the cursor, %FALSE otherwise
+ *
+ * Sets whether the cursor should be shown when it is over the video
+ * widget. If @show_cursor is %FALSE, the cursor will be invisible
+ * when it is moved over the video widget.
+ **/
+void
+bacon_video_widget_set_show_cursor (BaconVideoWidget * bvw,
+ gboolean show_cursor)
+{
+ GdkWindow *window;
+
+ g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
+
+
+ bvw->cursor_shown = show_cursor;
+ window = gtk_widget_get_window (GTK_WIDGET (bvw));
+
+ if (!window)
+ return;
+
+ if (show_cursor == FALSE) {
+ GdkCursor *cursor;
+ GdkDisplay *display;
+
+ display = gdk_window_get_display (window);
+ cursor = gdk_cursor_new_for_display (display, GDK_BLANK_CURSOR);
+ gdk_window_set_cursor (window, cursor);
+ g_object_unref (cursor);
+ } else {
+ gdk_window_set_cursor (window, bvw->cursor);
+ }
+}
+
+/**
* bacon_video_widget_set_aspect_ratio:
* @bvw: a #BaconVideoWidget
* @ratio: the new aspect ratio
@@ -4810,18 +4227,41 @@ bacon_video_widget_get_volume (BaconVideoWidget * bvw)
**/
void
bacon_video_widget_set_aspect_ratio (BaconVideoWidget *bvw,
- BvwAspectRatio ratio)
+ BvwAspectRatio ratio)
{
- GstMessage *msg;
-
g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
bvw->ratio_type = ratio;
- msg = gst_message_new_application (GST_OBJECT (bvw->play),
- gst_structure_new ("video-size", "width", G_TYPE_INT,
- bvw->video_width, "height", G_TYPE_INT,
- bvw->video_height, NULL));
- gst_element_post_message (bvw->play, msg);
+
+ switch (bvw->ratio_type) {
+ case BVW_RATIO_SQUARE:
+ g_object_set (bvw->video_sink,
+ "video-aspect-ratio-override", 1, 1,
+ NULL);
+ break;
+ case BVW_RATIO_FOURBYTHREE:
+ g_object_set (bvw->video_sink,
+ "video-aspect-ratio-override", 4, 3,
+ NULL);
+ break;
+ case BVW_RATIO_ANAMORPHIC:
+ g_object_set (bvw->video_sink,
+ "video-aspect-ratio-override", 16, 9,
+ NULL);
+ break;
+ case BVW_RATIO_DVB:
+ g_object_set (bvw->video_sink,
+ "video-aspect-ratio-override", 20, 9,
+ NULL);
+ break;
+ /* handle these to avoid compiler warnings */
+ case BVW_RATIO_AUTO:
+ default:
+ g_object_set (bvw->video_sink,
+ "video-aspect-ratio-override", 0, 1,
+ NULL);
+ break;
+ }
}
/**
@@ -4854,11 +4294,7 @@ bacon_video_widget_set_zoom (BaconVideoWidget *bvw,
{
g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
- if (bvw->frame == NULL)
- return;
-
- totem_aspect_frame_set_expand (TOTEM_ASPECT_FRAME (bvw->frame),
- (mode == BVW_ZOOM_EXPAND));
+ g_debug ("%s not implemented", G_STRFUNC);
}
/**
@@ -4872,12 +4308,10 @@ bacon_video_widget_set_zoom (BaconVideoWidget *bvw,
BvwZoomMode
bacon_video_widget_get_zoom (BaconVideoWidget *bvw)
{
- gboolean expand;
+ g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), BVW_ZOOM_NONE);
- g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), 1.0);
-
- expand = totem_aspect_frame_get_expand (TOTEM_ASPECT_FRAME (bvw->frame));
- return expand ? BVW_ZOOM_EXPAND : BVW_ZOOM_NONE;
+ g_debug ("%s not implemented", G_STRFUNC);
+ return BVW_ZOOM_NONE;
}
/**
@@ -4891,22 +4325,15 @@ void
bacon_video_widget_set_rotation (BaconVideoWidget *bvw,
BvwRotation rotation)
{
- gfloat angle;
-
g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
- if (bvw->frame == NULL)
- return;
-
GST_DEBUG ("Rotating to %s (%f degrees) from %s",
g_enum_to_string (BVW_TYPE_ROTATION, rotation),
rotation * 90.0,
g_enum_to_string (BVW_TYPE_ROTATION, bvw->rotation));
bvw->rotation = rotation;
-
- angle = rotation * 90.0;
- totem_aspect_frame_set_rotation (TOTEM_ASPECT_FRAME (bvw->frame), angle);
+ g_object_set (bvw->video_sink, "rotate-method", rotation, NULL);
}
/**
@@ -5867,59 +5294,6 @@ bvw_set_playback_direction (BaconVideoWidget *bvw, gboolean forward)
return retval;
}
-static gboolean
-navigation_event (ClutterActor *actor,
- ClutterEvent *event,
- BaconVideoWidget *bvw)
-{
- ClutterGstFrame *frame =
- clutter_gst_video_sink_get_frame (CLUTTER_GST_VIDEO_SINK (bvw->video_sink));
- gfloat actor_width, actor_height;
- gfloat x, y;
-
- if (frame == NULL)
- return CLUTTER_EVENT_PROPAGATE;
-
- /* Get event coordinates into the actor's coordinates. */
- clutter_event_get_coords (event, &x, &y);
- clutter_actor_transform_stage_point (actor, x, y, &x, &y);
-
- clutter_actor_get_size (actor, &actor_width, &actor_height);
-
- /* Convert event's coordinates into the frame's coordinates. */
- x = x * frame->resolution.width / actor_width;
- y = y * frame->resolution.height / actor_height;
-
- if (event->type == CLUTTER_MOTION) {
- gst_navigation_send_mouse_event (GST_NAVIGATION (bvw->video_sink),
- "mouse-move", 0, x, y);
- } else if (event->type == CLUTTER_BUTTON_PRESS ||
- event->type == CLUTTER_BUTTON_RELEASE) {
- ClutterButtonEvent *bevent = (ClutterButtonEvent *) event;
- const char *type = (event->type == CLUTTER_BUTTON_PRESS) ?
- "mouse-button-press" : "mouse-button-release";
- gst_navigation_send_mouse_event (GST_NAVIGATION (bvw->video_sink), type,
- bevent->button, x, y);
- }
-
- return CLUTTER_EVENT_PROPAGATE;
-}
-
-static void
-listen_navigation_events (ClutterActor *actor,
- BaconVideoWidget *bvw)
-{
- const char * const events[] = {
- "button-press-event",
- "button-release-event",
- "motion-event"
- };
- guint i;
-
- for (i = 0; i < G_N_ELEMENTS (events); i++)
- g_signal_connect (actor, events[i], G_CALLBACK (navigation_event), bvw);
-}
-
static GstElement *
element_make_or_warn (const char *plugin,
const char *name)
@@ -5940,10 +5314,9 @@ bacon_video_widget_initable_init (GInitable *initable,
GstElement *audio_sink = NULL;
gchar *version_str;
GstPlayFlags flags;
- ClutterActor *layout;
- GstElement *audio_bin;
+ GtkWidget *tmp;
+ GstElement *glsinkbin, *audio_bin;
GstPad *audio_pad;
- GObject *item;
char *template;
bvw = BACON_VIDEO_WIDGET (initable);
@@ -5961,10 +5334,20 @@ bacon_video_widget_initable_init (GInitable *initable,
gst_pb_utils_init ();
+ gtk_widget_set_events (GTK_WIDGET (bvw),
+ gtk_widget_get_events (GTK_WIDGET (bvw)) |
+ GDK_SCROLL_MASK |
+ GDK_POINTER_MOTION_MASK |
+ GDK_BUTTON_MOTION_MASK |
+ GDK_BUTTON_PRESS_MASK |
+ GDK_BUTTON_RELEASE_MASK |
+ GDK_KEY_PRESS_MASK);
+
/* Instantiate all the fallible plugins */
bvw->play = element_make_or_warn ("playbin", "play");
bvw->audio_pitchcontrol = element_make_or_warn ("scaletempo", "scaletempo");
- bvw->video_sink = GST_ELEMENT (clutter_gst_video_sink_new ());
+ bvw->video_sink = element_make_or_warn ("gtkglsink", "video-sink");
+ glsinkbin = element_make_or_warn ("glsinkbin", "glsinkbin");
audio_sink = element_make_or_warn ("autoaudiosink", "audio-sink");
if (!bvw->play ||
@@ -6006,93 +5389,28 @@ bacon_video_widget_initable_init (GInitable *initable,
bvw->cursor_shown = TRUE;
- bvw->stage = gtk_clutter_embed_get_stage (GTK_CLUTTER_EMBED (bvw));
- clutter_actor_set_text_direction (bvw->stage,
- CLUTTER_TEXT_DIRECTION_LTR);
- clutter_actor_set_layout_manager (bvw->stage,
- clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_FILL, CLUTTER_BIN_ALIGNMENT_FILL));
- clutter_actor_set_name (bvw->stage, "stage");
- clutter_actor_set_background_color (bvw->stage, CLUTTER_COLOR_Black);
-
- /* Video sink, with aspect frame */
- bvw->texture = g_object_new (CLUTTER_TYPE_ACTOR,
- "content", g_object_new (CLUTTER_GST_TYPE_CONTENT,
- "sink", bvw->video_sink,
- NULL),
- "name", "texture",
- "reactive", TRUE,
- NULL);
- listen_navigation_events (bvw->texture, bvw);
-
- /* The logo */
- bvw->logo_frame = clutter_actor_new ();
- clutter_actor_set_name (bvw->logo_frame, "logo-frame");
- bvw->logo = clutter_image_new ();
- clutter_actor_set_content (bvw->logo_frame, bvw->logo);
- clutter_actor_set_content_gravity (bvw->logo_frame, CLUTTER_CONTENT_GRAVITY_RESIZE_ASPECT);
- clutter_actor_add_child (bvw->stage, bvw->logo_frame);
- clutter_actor_hide (CLUTTER_ACTOR (bvw->logo_frame));
-
- /* The video */
- bvw->frame = totem_aspect_frame_new ();
- clutter_actor_set_name (bvw->frame, "frame");
- totem_aspect_frame_set_child (TOTEM_ASPECT_FRAME (bvw->frame), bvw->texture);
-
- clutter_actor_add_child (bvw->stage, bvw->frame);
-
- clutter_actor_set_child_above_sibling (bvw->stage,
- bvw->logo_frame,
- bvw->frame);
-
- /* The spinner */
- bvw->spinner = bacon_video_spinner_actor_new ();
- clutter_actor_set_name (bvw->spinner, "spinner");
- clutter_actor_add_child (bvw->stage, bvw->spinner);
- clutter_actor_set_child_above_sibling (bvw->stage,
- bvw->spinner,
- bvw->frame);
- clutter_actor_hide (bvw->spinner);
-
- /* Fullscreen header controls */
- bvw->header_controls = gtk_clutter_actor_new ();
- clutter_actor_set_opacity (bvw->header_controls, OVERLAY_OPACITY);
- clutter_actor_set_name (bvw->header_controls, "header-controls");
- clutter_actor_add_constraint (bvw->header_controls,
- clutter_bind_constraint_new (bvw->stage,
- CLUTTER_BIND_WIDTH,
- 0));
- layout = g_object_new (CLUTTER_TYPE_ACTOR,
- "layout-manager", clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, CLUTTER_BIN_ALIGNMENT_START),
- NULL);
- clutter_actor_set_name (layout, "layout");
- clutter_actor_add_child (layout, bvw->header_controls);
- clutter_actor_add_child (bvw->stage, layout);
-
- /* The controls */
- bvw->controls = bacon_video_controls_actor_new ();
- clutter_actor_set_name (bvw->controls, "controls");
- layout = g_object_new (CLUTTER_TYPE_ACTOR,
- "layout-manager", clutter_bin_layout_new (CLUTTER_BIN_ALIGNMENT_CENTER, CLUTTER_BIN_ALIGNMENT_END),
- NULL);
- clutter_actor_set_name (layout, "layout");
- clutter_actor_add_child (layout, bvw->controls);
+ /* Create video output widget and logo */
+ bvw->stack = gtk_stack_new ();
+ gtk_container_add (GTK_CONTAINER (bvw), bvw->stack);
+ gtk_widget_show (bvw->stack);
- clutter_actor_add_child (bvw->stage, layout);
- clutter_actor_set_child_above_sibling (bvw->stage,
- layout,
- bvw->logo_frame);
+ g_object_set (glsinkbin, "sink", bvw->video_sink, NULL);
+ g_object_get (bvw->video_sink, "widget", &tmp, NULL);
+ gtk_stack_add_named (GTK_STACK (bvw->stack), tmp, "video");
+ gtk_widget_show (tmp);
+ g_object_unref (tmp);
- clutter_actor_set_opacity (bvw->controls, 0);
+ tmp = gtk_image_new_from_icon_name (APPLICATION_ID, GTK_ICON_SIZE_DIALOG);
+ gtk_image_set_pixel_size (GTK_IMAGE (tmp), LOGO_SIZE);
+ gtk_stack_add_named (GTK_STACK (bvw->stack), tmp, "logo");
+ gtk_widget_show (tmp);
- item = g_object_get_data (G_OBJECT (bvw->controls), "seek_scale");
- g_signal_connect (item, "scroll-event",
- G_CALLBACK (bacon_video_widget_handle_scroll), bvw);
- item = g_object_get_data (G_OBJECT (bvw->controls), "volume_button");
- g_signal_connect (item, "scroll-event",
- G_CALLBACK (bacon_video_widget_handle_scroll), bvw);
+ g_object_set (bvw->video_sink,
+ "rotate-method", GST_VIDEO_ORIENTATION_AUTO,
+ NULL);
/* And tell playbin */
- g_object_set (bvw->play, "video-sink", bvw->video_sink, NULL);
+ g_object_set (bvw->play, "video-sink", glsinkbin, NULL);
/* Link the audiopitch element */
bvw->audio_capsfilter =
@@ -6228,23 +5546,6 @@ bacon_video_widget_set_rate (BaconVideoWidget *bvw,
return retval;
}
-/**
- * bacon_video_widget_set_fullscreen:
- * @bvw: a #BaconVideoWidget
- * @fullscreen: the new fullscreen state
- *
- * Sets the fullscreen state, enabling a toplevel header bar sliding from
- * the top of the video widget.
- **/
-void
-bacon_video_widget_set_fullscreen (BaconVideoWidget *bvw,
- gboolean fullscreen)
-{
- g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
-
- g_object_set (bvw->header_controls, "visible", fullscreen, NULL);
-}
-
/*
* vim: sw=2 ts=8 cindent noai bs=2
*/