~ubuntu-branches/ubuntu/lucid/totem/lucid

« back to all changes in this revision

Viewing changes to src/backend/bacon-video-widget-gst-0.10.c

  • Committer: Bazaar Package Importer
  • Author(s): Sebastien Bacher
  • Date: 2010-02-25 11:43:11 UTC
  • mfrom: (1.11.4 upstream)
  • Revision ID: james.westby@ubuntu.com-20100225114311-vsjdzq9kl2n2g3ss
Tags: 2.29.91-0ubuntu1
* New upstream version:
  - Fix compilation with newer versions of Tracker
  - Update time in the status bar when frame-stepping
  - Fix a lot of build problems with newer GTK+, or using pedantic linkers
  - Update Vala bindings for external plugins
  - Fix problems with the popup menu in the browser plugin
* debian/control.in:
  - updated the gstreamer and gtk requirements
* debian/patches/90_autotools.patch:
  - new version update

Show diffs side-by-side

added added

removed removed

Lines of Context:
553
553
  GdkColor colour;
554
554
  GdkWindow *window;
555
555
  GdkEventMask event_mask;
 
556
  GtkAllocation allocation;
556
557
 
557
558
  event_mask = gtk_widget_get_events (widget)
558
559
    | GDK_POINTER_MOTION_MASK
567
568
  attributes.window_type = GDK_WINDOW_CHILD;
568
569
  attributes.x = 0;
569
570
  attributes.y = 0;
570
 
  attributes.width = widget->allocation.width;
571
 
  attributes.height = widget->allocation.height;
 
571
  gtk_widget_get_allocation (widget, &allocation);
 
572
  attributes.width = allocation.width;
 
573
  attributes.height = allocation.height;
572
574
  attributes.wclass = GDK_INPUT_OUTPUT;
573
575
  attributes.event_mask = gtk_widget_get_events (widget);
574
576
  attributes.event_mask |= GDK_EXPOSURE_MASK |
588
590
  gtk_widget_set_style (widget,
589
591
      gtk_style_attach (gtk_widget_get_style (widget), window));
590
592
 
591
 
  GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
 
593
  gtk_widget_set_realized (widget, TRUE);
592
594
 
593
595
  /* Connect to configure event on the top level window */
594
596
  g_signal_connect (G_OBJECT (gtk_widget_get_toplevel (widget)),
685
687
  gboolean draw_logo;
686
688
  XID window;
687
689
  GdkWindow *win;
 
690
  GtkAllocation allocation;
688
691
 
689
692
  if (event && event->count > 0)
690
693
    return TRUE;
707
710
 
708
711
  /* Start with a nice black canvas */
709
712
  win = gtk_widget_get_window (widget);
 
713
  gtk_widget_get_allocation (widget, &allocation);
710
714
  gdk_draw_rectangle (win, gtk_widget_get_style (widget)->black_gc, TRUE, 0, 0,
711
 
      widget->allocation.width, widget->allocation.height);
 
715
      allocation.width, allocation.height);
712
716
 
713
717
  /* If there's only audio and no visualisation, draw the logo as well.
714
718
   * If we have a cover image to display, we display it regardless of whether we're
729
733
 
730
734
      cr = gdk_cairo_create (gtk_widget_get_window (widget));
731
735
      cairo_set_source_rgb (cr, 0.0, 0.0, 0.0);
732
 
      cairo_rectangle (cr, 0, 0, widget->allocation.width, widget->allocation.height);
 
736
      cairo_rectangle (cr, 0, 0, allocation.width, allocation.height);
733
737
 
734
738
      s_width = gdk_pixbuf_get_width (pixbuf);
735
739
      s_height = gdk_pixbuf_get_height (pixbuf);
736
 
      d_width = widget->allocation.width;
737
 
      d_height = widget->allocation.height;
 
740
      d_width = allocation.width;
 
741
      d_height = allocation.height;
738
742
 
739
743
      /* Limit the width/height to 256×256 pixels, but only if we're displaying the logo proper */
740
744
      if (!bvw->priv->cover_pixbuf && d_width > LOGO_SIZE && d_height > LOGO_SIZE)
763
767
      else
764
768
        logo = g_object_ref (G_OBJECT (pixbuf));
765
769
 
766
 
      gdk_cairo_set_source_pixbuf (cr, logo, (widget->allocation.width - s_width) / 2, (widget->allocation.height - s_height) / 2);
 
770
      gdk_cairo_set_source_pixbuf (cr, logo, (allocation.width - s_width) / 2, (allocation.height - s_height) / 2);
767
771
      cairo_paint (cr);
768
772
      cairo_destroy (cr);
769
773
 
772
776
      /* No pixbuf, just draw a black background then */
773
777
      gdk_window_clear_area (win,
774
778
                             0, 0,
775
 
                             widget->allocation.width,
776
 
                             widget->allocation.height);
 
779
                             allocation.width,
 
780
                             allocation.height);
777
781
    }
778
782
  } else {
779
783
    /* no logo, pass the expose to gst */
783
787
      /* No xoverlay to expose yet */
784
788
      gdk_window_clear_area (win,
785
789
                             0, 0,
786
 
                             widget->allocation.width,
787
 
                             widget->allocation.height);
 
790
                             allocation.width,
 
791
                             allocation.height);
788
792
    }
789
793
  }
790
794
  if (xoverlay != NULL)
896
900
static void
897
901
resize_video_window (BaconVideoWidget *bvw)
898
902
{
899
 
  const GtkAllocation *allocation;
 
903
  GtkAllocation allocation;
900
904
  gfloat width, height, ratio, x, y;
901
905
  int w, h;
902
906
 
903
907
  g_return_if_fail (bvw != NULL);
904
908
  g_return_if_fail (BACON_IS_VIDEO_WIDGET (bvw));
905
909
 
906
 
  allocation = &GTK_WIDGET (bvw)->allocation;
 
910
  gtk_widget_get_allocation (GTK_WIDGET (bvw), &allocation);
907
911
 
908
912
  get_media_size (bvw, &w, &h);
909
913
  if (!w || !h) {
910
 
    w = allocation->width;
911
 
    h = allocation->height;
 
914
    w = allocation.width;
 
915
    h = allocation.height;
912
916
  }
913
917
  width = w;
914
918
  height = h;
915
919
 
916
920
  /* calculate ratio for fitting video into the available space */
917
 
  if ((gfloat) allocation->width / width >
918
 
      (gfloat) allocation->height / height) {
919
 
    ratio = (gfloat) allocation->height / height;
 
921
  if ((gfloat) allocation.width / width >
 
922
      (gfloat) allocation.height / height) {
 
923
    ratio = (gfloat) allocation.height / height;
920
924
  } else {
921
 
    ratio = (gfloat) allocation->width / width;
 
925
    ratio = (gfloat) allocation.width / width;
922
926
  }
923
927
 
924
928
  /* apply zoom factor */
926
930
 
927
931
  width *= ratio;
928
932
  height *= ratio;
929
 
  x = (allocation->width - width) / 2;
930
 
  y = (allocation->height - height) / 2;
 
933
  x = (allocation.width - width) / 2;
 
934
  y = (allocation.height - height) / 2;
931
935
 
932
936
  gdk_window_move_resize (bvw->priv->video_window, x, y, width, height);
933
937
  gtk_widget_queue_draw (GTK_WIDGET (bvw));
941
945
  g_return_if_fail (widget != NULL);
942
946
  g_return_if_fail (BACON_IS_VIDEO_WIDGET (widget));
943
947
 
944
 
  widget->allocation = *allocation;
 
948
  gtk_widget_set_allocation (widget, allocation);
945
949
 
946
 
  if (GTK_WIDGET_REALIZED (widget)) {
 
950
  if (gtk_widget_get_realized (widget)) {
947
951
 
948
952
    gdk_window_move_resize (gtk_widget_get_window (widget),
949
953
                            allocation->x, allocation->y,
1274
1278
{
1275
1279
  BaconVideoWidgetPrivate *priv;
1276
1280
 
1277
 
  GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_CAN_FOCUS);
1278
 
  GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
 
1281
  gtk_widget_set_can_focus (GTK_WIDGET (bvw), TRUE);
 
1282
  gtk_widget_set_double_buffered (GTK_WIDGET (bvw), TRUE);
1279
1283
 
1280
1284
  bvw->priv = priv = G_TYPE_INSTANCE_GET_PRIVATE (bvw, BACON_TYPE_VIDEO_WIDGET, BaconVideoWidgetPrivate);
1281
1285
 
1334
1338
{
1335
1339
  const gchar *msg_name;
1336
1340
  GdkWindow *window;
 
1341
  GtkAllocation allocation;
1337
1342
 
1338
1343
  msg_name = gst_structure_get_name (msg->structure);
1339
1344
  g_return_if_fail (msg_name != NULL);
1356
1361
        && !bvw->priv->window_resized) {
1357
1362
      bacon_video_widget_set_scale_ratio (bvw, 1);
1358
1363
    } else {
 
1364
      gtk_widget_get_allocation (GTK_WIDGET (bvw), &allocation);
1359
1365
      bacon_video_widget_size_allocate (GTK_WIDGET (bvw),
1360
 
                                        &GTK_WIDGET (bvw)->allocation);
 
1366
                                        &allocation);
1361
1367
 
1362
1368
      /* Uhm, so this ugly hack here makes media loading work for
1363
1369
       * weird laptops with NVIDIA graphics cards... Dunno what the
1684
1690
  retval = FALSE;
1685
1691
 
1686
1692
  if (bvw->priv->use_type != BVW_USE_TYPE_VIDEO ||
1687
 
      GTK_WIDGET_REALIZED (bvw) == FALSE)
 
1693
      gtk_widget_get_realized (GTK_WIDGET (bvw)) == FALSE)
1688
1694
    return retval;
1689
1695
 
1690
1696
  /* The user already tried, and we aborted */
2146
2152
      break;
2147
2153
    }
2148
2154
 
 
2155
    /* FIXME: at some point we might want to handle CLOCK_LOST and set the
 
2156
     * pipeline back to PAUSED and then PLAYING again to select a different
 
2157
     * clock (this seems to trip up rtspsrc though so has to wait until
 
2158
     * rtspsrc gets fixed) */
2149
2159
    case GST_MESSAGE_CLOCK_PROVIDE:
2150
2160
    case GST_MESSAGE_CLOCK_LOST:
2151
2161
    case GST_MESSAGE_NEW_CLOCK:
2152
2162
    case GST_MESSAGE_STATE_DIRTY:
 
2163
    case GST_MESSAGE_STREAM_STATUS:
2153
2164
      break;
2154
2165
 
2155
2166
    default:
2520
2531
      g_object_get (bvw->priv->play, "flags", &flags, NULL);
2521
2532
      if (bvw->priv->show_vfx) {
2522
2533
        gdk_window_show (bvw->priv->video_window);
2523
 
        GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
 
2534
        gtk_widget_set_double_buffered (GTK_WIDGET (bvw), FALSE);
2524
2535
        flags |= GST_PLAY_FLAGS_VIS;
2525
2536
      } else {
2526
2537
        gdk_window_hide (bvw->priv->video_window);
2527
 
        GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
 
2538
        gtk_widget_set_double_buffered (GTK_WIDGET (bvw), TRUE);
2528
2539
        flags &= ~GST_PLAY_FLAGS_VIS;
2529
2540
      }
2530
2541
      g_object_set (bvw->priv->play, "flags", flags, NULL);
3548
3559
bacon_video_widget_open (BaconVideoWidget * bvw,
3549
3560
                         const gchar * mrl, const gchar *subtitle_uri, GError ** error)
3550
3561
{
 
3562
  GtkAllocation allocation;
3551
3563
  GstMessage *err_msg = NULL;
3552
3564
  GFile *file;
3553
3565
  gboolean ret;
3571
3583
  file = g_file_new_for_commandline_arg (mrl);
3572
3584
 
3573
3585
  /* Only use the URI when FUSE isn't available for a file
3574
 
   * or we're trying to read from an archive */
3575
 
  if (g_file_has_uri_scheme (file, "archive") != FALSE)
 
3586
   * or we're trying to read from an archive or ObexFTP */
 
3587
  if (g_file_has_uri_scheme (file, "archive") != FALSE ||
 
3588
      g_file_has_uri_scheme (file, "obex") != FALSE)
3576
3589
    path = NULL;
3577
3590
  else
3578
3591
    path = g_file_get_path (file);
3617
3630
  if (bvw->priv->video_window) {
3618
3631
    gdk_window_hide (bvw->priv->video_window);
3619
3632
    /* We also take the whole widget until we know video size */
 
3633
    gtk_widget_get_allocation (GTK_WIDGET (bvw), &allocation);
3620
3634
    gdk_window_move_resize (bvw->priv->video_window, 0, 0,
3621
 
        GTK_WIDGET (bvw)->allocation.width,
3622
 
        GTK_WIDGET (bvw)->allocation.height);
 
3635
                            allocation.width,
 
3636
                            allocation.height);
3623
3637
  }
3624
3638
 
3625
3639
  /* Visualization settings changed */
3818
3832
/**
3819
3833
 * bacon_video_widget_seek_time:
3820
3834
 * @bvw: a #BaconVideoWidget
3821
 
 * @time: the time to which to seek, in milliseconds
 
3835
 * @_time: the time to which to seek, in milliseconds
3822
3836
 * @error: a #GError, or %NULL
3823
3837
 *
3824
3838
 * Seeks the currently-playing stream to the absolute position @time, in milliseconds.
3826
3840
 * Return value: %TRUE on success, %FALSE otherwise
3827
3841
 **/
3828
3842
gboolean
3829
 
bacon_video_widget_seek_time (BaconVideoWidget *bvw, gint64 time, GError **error)
 
3843
bacon_video_widget_seek_time (BaconVideoWidget *bvw, gint64 _time, GError **error)
3830
3844
{
3831
3845
  g_return_val_if_fail (bvw != NULL, FALSE);
3832
3846
  g_return_val_if_fail (BACON_IS_VIDEO_WIDGET (bvw), FALSE);
3833
3847
  g_return_val_if_fail (GST_IS_ELEMENT (bvw->priv->play), FALSE);
3834
3848
 
3835
 
  GST_LOG ("Seeking to %" GST_TIME_FORMAT, GST_TIME_ARGS (time * GST_MSECOND));
 
3849
  GST_LOG ("Seeking to %" GST_TIME_FORMAT, GST_TIME_ARGS (_time * GST_MSECOND));
3836
3850
 
3837
 
  if (time > bvw->priv->stream_length
 
3851
  if (_time > bvw->priv->stream_length
3838
3852
      && bvw->priv->stream_length > 0
3839
3853
      && !g_str_has_prefix (bvw->priv->mrl, "dvd:")
3840
3854
      && !g_str_has_prefix (bvw->priv->mrl, "vcd:")) {
3844
3858
  }
3845
3859
 
3846
3860
  /* Emit a time tick of where we are going, we are paused */
3847
 
  got_time_tick (bvw->priv->play, time * GST_MSECOND, bvw);
 
3861
  got_time_tick (bvw->priv->play, _time * GST_MSECOND, bvw);
3848
3862
 
3849
3863
  if (bvw_set_playback_direction (bvw, TRUE) == FALSE)
3850
3864
    return FALSE;
3851
3865
 
3852
3866
  gst_element_seek (bvw->priv->play, FORWARD_RATE,
3853
3867
      GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
3854
 
      GST_SEEK_TYPE_SET, time * GST_MSECOND,
 
3868
      GST_SEEK_TYPE_SET, _time * GST_MSECOND,
3855
3869
      GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE);
3856
3870
  bvw->priv->rate = FORWARD_RATE;
3857
3871
 
3903
3917
bacon_video_widget_step (BaconVideoWidget *bvw, gboolean forward, GError **error)
3904
3918
{
3905
3919
  GstEvent *event;
 
3920
  gboolean retval;
3906
3921
 
3907
3922
  if (bvw_set_playback_direction (bvw, forward) == FALSE)
3908
3923
    return FALSE;
3909
3924
 
3910
3925
  event = gst_event_new_step (GST_FORMAT_BUFFERS, 1, 1.0, TRUE, FALSE);
3911
3926
 
3912
 
  return gst_element_send_event (bvw->priv->play, event);
 
3927
  retval = gst_element_send_event (bvw->priv->play, event);
 
3928
 
 
3929
  if (retval != FALSE)
 
3930
    bvw_query_timeout (bvw);
 
3931
 
 
3932
  return retval;
3913
3933
}
3914
3934
 
3915
3935
static gboolean
4201
4221
    if (priv->video_window) {
4202
4222
      if (logo_mode) {
4203
4223
        gdk_window_hide (priv->video_window);
4204
 
        GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
 
4224
        gtk_widget_set_double_buffered (GTK_WIDGET (bvw), TRUE);
4205
4225
      } else {
4206
4226
        gdk_window_show (priv->video_window);
4207
 
        GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
 
4227
        gtk_widget_set_double_buffered (GTK_WIDGET (bvw), FALSE);
4208
4228
      }
4209
4229
    }
4210
4230
 
4743
4763
    g_object_get (bvw->priv->play, "flags", &flags, NULL);
4744
4764
    if (bvw->priv->show_vfx && !bvw->priv->cover_pixbuf) {
4745
4765
      gdk_window_show (bvw->priv->video_window);
4746
 
      GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
 
4766
      gtk_widget_set_double_buffered (GTK_WIDGET (bvw), FALSE);
4747
4767
      flags |= GST_PLAY_FLAGS_VIS;
4748
4768
    } else {
4749
4769
      gdk_window_hide (bvw->priv->video_window);
4750
 
      GTK_WIDGET_SET_FLAGS (GTK_WIDGET (bvw), GTK_DOUBLE_BUFFERED);
 
4770
      gtk_widget_set_double_buffered (GTK_WIDGET (bvw), TRUE);
4751
4771
      flags &= ~GST_PLAY_FLAGS_VIS;
4752
4772
    }
4753
4773
    g_object_set (bvw->priv->play, "flags", flags, NULL);