~ubuntu-branches/ubuntu/hardy/gxine/hardy

« back to all changes in this revision

Viewing changes to src/gtkvideo.c

  • Committer: Bazaar Package Importer
  • Author(s): Reinhard Tartler
  • Date: 2008-03-21 11:24:59 UTC
  • mfrom: (1.1.8 upstream)
  • Revision ID: james.westby@ubuntu.com-20080321112459-igb0jy01nytpdrzt
Tags: 0.5.901-1ubuntu1
* merge debian changes for hardy PPA. Remaining changes:
  - debian/control: added Xb-Npp-xxx tags accordingly to "firefox distro
    add-on suport" spec,
    (https://blueprints.launchpad.net/ubuntu/+spec/firefox-distro-addon-support)
* Feature Freeze exception granted in LP: #204563
* New upstream release fixes playing DVDs. LP: #128864
* mime.default: add "x-content/video-dvd;x-content/video-vcd;x-content/video-svcd;"
  to get it listed as a player for dvd and video cds in nautilus. Thanks to
  Sebastien Bacher for the hint.

Show diffs side-by-side

added added

removed removed

Lines of Context:
1
1
/*
2
 
 * Copyright (C) 2001-2006 the xine project
 
2
 * Copyright (C) 2001-2007 the xine project
3
3
 *
4
4
 * This program is free software; you can redistribute it and/or modify
5
5
 * it under the terms of the GNU General Public License as published by
15
15
 * along with this program; if not, write to the Free Software
16
16
 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA  02110-1301 USA
17
17
 *
18
 
 * $Id: gtkvideo.c,v 1.115 2006/04/04 22:08:16 dsalt Exp $
19
 
 *
20
18
 * gtk xine video widget
21
19
 *
22
20
 * some code originating from totem's gtkxine widget
55
53
#include <X11/extensions/Xinerama.h>
56
54
#endif
57
55
 
 
56
#ifdef HAVE_XCB
 
57
#include <xcb/xcb.h>
 
58
#endif
 
59
 
58
60
#ifdef WITH_DBUS
59
61
#include <dbus/dbus-glib.h>
60
62
 
74
76
#include <gtk/gtkmain.h>
75
77
#include <gdk/gdkx.h>
76
78
#include <xine.h>
 
79
/* for get_capabilities() */
 
80
#include <xine/video_out.h>
77
81
 
78
82
#include "gtkvideo.h"
79
83
#include "globals.h"
102
106
                                     GtkAllocation  *allocation);
103
107
 
104
108
static gboolean gtv_unblank_screen (GtkVideo *);
 
109
static gboolean gtv_update_resize_factor (GtkVideo *);
105
110
 
106
111
static GtkWidgetClass *parent_class = NULL;
107
112
static pthread_mutex_t resize_lock = PTHREAD_MUTEX_INITIALIZER;
110
115
#define RESIZE_LOCK() pthread_mutex_lock (&resize_lock)
111
116
#define RESIZE_UNLOCK() pthread_mutex_unlock (&resize_lock)
112
117
 
113
 
#define RESIZE_ADD() \
 
118
#define RESIZE_ADD(resize) \
114
119
  do { \
115
120
    pthread_mutex_lock (&resize_add_lock); \
116
121
    if (!gtv->priv->resizing && GTK_WIDGET_REALIZED (&gtv->widget)) \
117
122
      gtv->priv->resizing = \
118
123
        g_idle_add_full (G_PRIORITY_HIGH_IDLE, \
119
 
                         (GSourceFunc) gtk_video_idle_resize, gtv, NULL); \
 
124
                         (GSourceFunc) ((resize) \
 
125
                           ? gtk_video_idle_resize : gtk_video_idle_no_resize), \
 
126
                         gtv, NULL); \
120
127
    pthread_mutex_unlock (&resize_add_lock); \
121
128
  } while (0)
122
129
 
124
131
 * private data
125
132
 */
126
133
 
 
134
typedef void (*frame_cb_t) (gpointer);
 
135
 
127
136
struct gtk_video_private_s {
128
137
 
129
138
  xine_t                  *xine;
177
186
#endif
178
187
 
179
188
  gboolean               playing_no_blank:8;
180
 
  /* visualization */
 
189
 
 
190
  /* visualisation & post-plugins*/
 
191
  gboolean                 have_tvtime:8;
 
192
 
181
193
  gboolean                 vis_active:8;
182
194
  xine_post_t             *vis_plugin;
183
195
  char                    *vis_plugin_id;
184
196
  xine_audio_port_t       *vis_audio;
185
197
 
186
 
  /* post-plugins */
187
198
  struct {
188
199
    GList       *list;
189
200
    gboolean     enable;
190
201
  }                        post_deinterlace, post_video, post_audio;
191
 
  gboolean                 have_tvtime;
 
202
 
 
203
  /* callbacks */
 
204
 
 
205
  guint                    frame_cb_id;
 
206
  frame_cb_t               frame_cb;
 
207
  gpointer                 frame_cb_data;
 
208
 
 
209
  guint                    end_time_id;
 
210
  gint                     end_time; /* for triggering early "playback finished" */
192
211
};
193
212
 
194
213
static int gtv_table_signals[LAST_SIGNAL] = { 0 };
229
248
 
230
249
static gboolean gtv_test_inhibit_blank (GtkVideo *gtv)
231
250
{
232
 
  /* (fullscreen || (deny blank && drawable && playing)) && !logo && !paused */
 
251
  /* (fullscreen || (deny blank && drawable && playing && !(shaded || hidden)))
 
252
   * && !logo && !paused
 
253
   */
233
254
  return (is_fullscreen (gtv->priv)
234
255
          || (gtv->priv->playing_no_blank && GTK_WIDGET_DRAWABLE (&gtv->widget)
235
 
              && xine_get_status (gtv->priv->stream) == XINE_STATUS_PLAY))
 
256
              && xine_get_status (gtv->priv->stream) == XINE_STATUS_PLAY
 
257
              && (gdk_window_get_state (gtk_widget_get_toplevel (&gtv->widget)->window) & 3) == 0))
236
258
         && !playlist_showing_logo ()
237
259
         && xine_get_param (gtv->priv->stream, XINE_PARAM_SPEED);
238
260
}
509
531
  gtk_widget_set_size_request (&gtv->widget, size->width, size->height);
510
532
  if (GTK_WIDGET_REALIZED(&gtv->widget) && gtv->widget.parent)
511
533
  {
 
534
    GdkGeometry geom;
 
535
    GtkWindow *toplevel = GTK_WINDOW (gtk_widget_get_toplevel (&gtv->widget));
 
536
    if (toplevel->bin.child == &gtv->widget)
 
537
    {
 
538
      geom.min_width = size->width;
 
539
      geom.min_height = size->height;
 
540
      gtk_window_set_geometry_hints (toplevel, &gtv->widget, &geom,
 
541
                                     GDK_HINT_MIN_SIZE);
 
542
    }
512
543
    gtk_window_resize ((GtkWindow *)gtk_widget_get_toplevel (&gtv->widget),
513
 
                       GTK_VIDEO_MIN_WIDTH, 1); /* note controlling geometry */
 
544
                       size->width, size->height); /* note controlling geometry */
 
545
    if (toplevel->bin.child == &gtv->widget)
 
546
    {
 
547
      geom.min_aspect = geom.max_aspect = (double)size->width / (double)size->height;
 
548
      gtk_window_set_geometry_hints (toplevel, &gtv->widget, &geom,
 
549
                                     GDK_HINT_ASPECT);
 
550
    }
514
551
    gtk_video_allow_shrink (gtv);
515
552
  }
516
553
}
561
598
  *dest_pixel_aspect = priv->display_ratio;
562
599
}
563
600
 
564
 
static gboolean gtk_video_idle_resize (GtkVideo *gtv)
 
601
static gboolean gtv_idle_resize (GtkVideo *gtv, gboolean resize)
565
602
{
566
603
  gdk_threads_enter ();
567
604
  RESIZE_LOCK ();
568
605
 
 
606
  gboolean send_signal = FALSE;
569
607
  gtk_video_private_t *priv = gtv->priv;
570
608
  double factor = DOUBLE_STD();
571
609
  priv->size = SCALE (factor);
580
618
  }
581
619
  else if (!priv->pending_resize)
582
620
  {
583
 
    gtv_do_resize (gtv, &priv->size);
 
621
    if (resize)
 
622
      gtv_do_resize (gtv, &priv->size);
 
623
    else
 
624
      send_signal = gtv_update_resize_factor (gtv);
584
625
    logprintf ("gtkvideo: idle signal done\n");
585
626
  }
586
627
  else
587
628
  {
588
 
    gtv_do_rescale (gtv);
 
629
    if (resize)
 
630
      gtv_do_rescale (gtv);
 
631
    else
 
632
      send_signal = gtv_update_resize_factor (gtv);
589
633
    logprintf ("gtkvideo: idle signal done, pending resize handled\n");
590
634
  }
591
635
 
 
636
  if (send_signal)
 
637
    g_signal_emit ((GObject *)gtv,
 
638
                   gtv_table_signals[GTK_VIDEO_SCALE_FACTOR], 0,
 
639
                   priv->resize_factor);
 
640
 
592
641
  priv->resizing = 0;
593
642
  priv->idle_resized = TRUE;
594
643
 
598
647
  return FALSE;
599
648
}
600
649
 
 
650
static gboolean gtk_video_idle_resize (GtkVideo *gtv)
 
651
{
 
652
  return gtv_idle_resize (gtv, TRUE);
 
653
}
 
654
 
 
655
static gboolean gtk_video_idle_no_resize (GtkVideo *gtv)
 
656
{
 
657
  return gtv_idle_resize (gtv, FALSE);
 
658
}
 
659
 
 
660
static gboolean end_time_check (gtk_video_private_t *priv)
 
661
{
 
662
  gint pos_stream, pos_time, length_time;
 
663
  priv->end_time_id = 0;
 
664
  if (!xine_get_pos_length (stream, &pos_stream, &pos_time, &length_time))
 
665
    pos_stream = pos_time = length_time = 0;
 
666
  if (priv->end_time && pos_time >= priv->end_time)
 
667
  {
 
668
    logprintf ("gtkvideo: end time passed, sending stop event\n");
 
669
    priv->end_time = 0;
 
670
    xine_stream_t *stream = priv->stream;
 
671
    xine_set_param (stream, XINE_PARAM_SPEED, XINE_SPEED_PAUSE);
 
672
    xine_event_t event = {
 
673
      .type = XINE_EVENT_UI_PLAYBACK_FINISHED,
 
674
      .stream = stream,
 
675
      .data = NULL
 
676
    };
 
677
    xine_event_send (stream, &event);
 
678
  }
 
679
  return FALSE;
 
680
}
 
681
 
601
682
static void frame_output_cb (void *gv_gen,
602
683
                             int video_width, int video_height,
603
684
                             double video_pixel_aspect,
624
705
  priv->video_size = (GtkRequisition){ video_width, video_height };
625
706
  *dest_y = *dest_x = 0;
626
707
 
627
 
  if (first || priv->auto_resize)
628
708
  {
629
709
    RESIZE_LOCK ();
630
710
    {
642
722
          priv->pending_resize = TRUE;
643
723
        }
644
724
        else
645
 
          RESIZE_ADD ();
 
725
          RESIZE_ADD (first || priv->auto_resize);
646
726
      }
647
727
    }
648
728
    RESIZE_UNLOCK ();
665
745
  }
666
746
 
667
747
  *dest_pixel_aspect = priv->display_ratio;
668
 
}
 
748
 
 
749
   if (priv->end_time && !priv->end_time_id)
 
750
     priv->end_time_id = g_idle_add ((GSourceFunc) end_time_check, priv);
 
751
 
 
752
  if (priv->frame_cb)
 
753
  {
 
754
    if (priv->frame_cb_id)
 
755
      g_source_remove (priv->frame_cb_id);
 
756
    priv->frame_cb_id = g_idle_add (priv->frame_cb, priv->frame_cb_data);
 
757
  }
 
758
}
 
759
 
 
760
#ifdef HAVE_XCB
 
761
# ifdef ENABLE_X11_VO
 
762
static xine_video_port_t *
 
763
gxine_open_video_driver (xine_t * self, const char *id, void *xcb, void *x11)
 
764
{
 
765
  return xine_open_video_driver (self, id, XINE_VISUAL_TYPE_XCB, xcb)
 
766
     ? : xine_open_video_driver (self, id, XINE_VISUAL_TYPE_X11, x11);
 
767
}
 
768
# else /* ! ENABLE_X11_VO */
 
769
#  define gxine_open_video_driver(SELF,ID,XCB,X11) \
 
770
  xine_open_video_driver ((SELF), (ID), XINE_VISUAL_TYPE_XCB, (XCB))
 
771
# endif
 
772
#else /* ! HAVE_XCB */
 
773
# define gxine_open_video_driver(SELF,ID,X11,UNUSED) \
 
774
  xine_open_video_driver ((SELF), (ID), XINE_VISUAL_TYPE_X11, (X11))
 
775
#endif
669
776
 
670
777
static xine_video_port_t *load_video_out_driver (GtkVideo *this)
671
778
{
672
779
  double                   res_h, res_v;
673
 
  x11_visual_t             vis;
 
780
  int                      mm_h, mm_v, mm;
674
781
  const char              *video_driver_id;
675
782
  xine_video_port_t       *video_port;
676
783
  gtk_video_private_t     *priv = this->priv;
677
784
 
 
785
#ifndef HAVE_XCB
 
786
  x11_visual_t vis;
 
787
 
678
788
  vis.display           = gtv_get_xdisplay (this);
679
789
  vis.screen            = gtv_get_xscreen_num (this);
680
790
  vis.d                 = priv->video_window;
681
 
  res_h                 = (DisplayWidth  (vis.display, vis.screen)*1000
682
 
                           / DisplayWidthMM (vis.display, vis.screen));
683
 
  res_v                 = (DisplayHeight (vis.display, vis.screen)*1000
684
 
                           / DisplayHeightMM (vis.display, vis.screen));
685
 
  priv->display_ratio   = res_v / res_h;
686
 
 
 
791
  mm_h                  = DisplayWidthMM (vis.display, vis.screen);
 
792
  res_h                 = DisplayWidth (vis.display, vis.screen);
 
793
  mm_v                  = DisplayHeightMM (vis.display, vis.screen);
 
794
  res_v                 = DisplayHeight (vis.display, vis.screen);
 
795
#else /* HAVE_XCB */
 
796
  xcb_visual_t vis;
 
797
  int screen_no = 0;
 
798
  xcb_connection_t *connection = xcb_connect(NULL, &screen_no);
 
799
  xcb_screen_iterator_t screen_it;
 
800
 
 
801
#ifdef ENABLE_X11_VO
 
802
  x11_visual_t x11vis;
 
803
#endif
 
804
 
 
805
  screen_it = xcb_setup_roots_iterator (xcb_get_setup (connection));
 
806
  while (screen_it.rem > 1 && screen_no > 0)
 
807
  {
 
808
    xcb_screen_next (&screen_it);
 
809
    --screen_no;
 
810
  }
 
811
 
 
812
  vis.connection        = connection;
 
813
  vis.screen            = screen_it.data;
 
814
  vis.window            = priv->video_window;
 
815
 
 
816
#ifdef ENABLE_X11_VO
 
817
  x11vis.display        = gtv_get_xdisplay (this);
 
818
  x11vis.screen         = gtv_get_xscreen_num (this);
 
819
  x11vis.d              = priv->video_window;
 
820
#endif
 
821
 
 
822
  /* why can't the 'Merkians spell "millimetre" correctly... */
 
823
  mm_h                  = screen_it.data->width_in_millimeters;
 
824
  res_h                 = screen_it.data->width_in_pixels;
 
825
  mm_v                  = screen_it.data->height_in_millimeters;
 
826
  res_v                 = screen_it.data->height_in_pixels;
 
827
#endif /* HAVE_XCB */
 
828
 
 
829
  char *desc = g_strdup_printf (_("The reported value is %dmm."), mm_h);
 
830
  mm = xine_config_register_range (priv->xine, "video.display_width",
 
831
                                   0, 0, 100000,
 
832
                                   N_("display width in mm\n(0 = autodetect)"), desc,
 
833
                                   10, NULL, NULL);
 
834
  res_h = res_h * 1000 / (mm ? mm : mm_h);
 
835
  free (desc);
 
836
 
 
837
  desc = g_strdup_printf (_("The reported value is %dmm."), mm_v);
 
838
  mm = xine_config_register_range (priv->xine, "video.display_height",
 
839
                                   0, -1, 100000,
 
840
                                   N_("display height in mm\n(0 = autodetect, -1 = assume square pixels)"), desc,
 
841
                                   10, NULL, NULL);
 
842
  res_v = mm < 0 ? res_h : (res_v * 1000 / (mm ? mm : mm_v));
 
843
  free (desc);
 
844
 
 
845
  priv->display_ratio   = (res_h <= 0.0 || res_v <= 0.0) ? 1 : res_v / res_h;
687
846
  if (fabs(priv->display_ratio - 1.0) < 0.01)
688
847
    priv->display_ratio   = 1.0;
689
848
 
691
850
  vis.frame_output_cb   = frame_output_cb;
692
851
  vis.user_data         = this;
693
852
 
694
 
  if (priv->video_driver_id)
695
 
    video_driver_id = priv->video_driver_id;
696
 
  else
697
 
  {
698
 
    char **choices = get_driver_ids (xine_list_video_output_plugins (priv->xine));
699
 
    /* try to init video with stored information */
700
 
    int i = xine_config_register_enum (priv->xine,
701
 
                                   "video.driver", 0,
702
 
                                   choices,
703
 
                                   N_("video driver to use"),
704
 
                                   NULL, 10, NULL, NULL);
705
 
    video_driver_id = choices[i];
706
 
  }
 
853
#ifdef ENABLE_X11_VO
 
854
  x11vis.dest_size_cb    = dest_size_cb;
 
855
  x11vis.frame_output_cb = frame_output_cb;
 
856
  x11vis.user_data       = this;
 
857
#endif
 
858
 
 
859
  char **choices = get_driver_ids (xine_list_video_output_plugins (priv->xine));
 
860
  /* try to init video with stored information */
 
861
  int i = xine_config_register_enum (priv->xine,
 
862
                                     "video.driver", 0, choices,
 
863
                                     N_("video driver to use"),
 
864
                                     NULL, 10, NULL, NULL);
 
865
  video_driver_id = priv->video_driver_id ? : choices[i];
 
866
 
707
867
  if (strcmp (video_driver_id, "auto"))
708
868
  {
709
 
    video_port=xine_open_video_driver (priv->xine,
710
 
                                      video_driver_id,
711
 
                                      XINE_VISUAL_TYPE_X11,
712
 
                                      (void *) &vis);
 
869
    video_port = gxine_open_video_driver (priv->xine, video_driver_id,
 
870
                                          (void *) &vis, (void *) &x11vis);
713
871
    if (video_port)
714
872
      return video_port;
715
 
    else
716
 
      g_printerr (_("gtkvideo: video driver %s failed.\n"),
 
873
 
 
874
    g_printerr (_("gtkvideo: video driver %s failed.\n"),
717
875
               video_driver_id); /* => auto-detect */
718
876
  }
719
877
 
720
 
  return xine_open_video_driver (priv->xine, NULL,
721
 
                                 XINE_VISUAL_TYPE_X11,
722
 
                                 (void *) &vis);
 
878
  video_port = gxine_open_video_driver (priv->xine, NULL,
 
879
                                        (void *) &vis, (void *) &x11vis);
 
880
 
 
881
  if (video_port)
 
882
    return video_port;
 
883
 
 
884
  g_printerr (_("gtkvideo: video driver %s failed.\n"), "auto");
 
885
  return gxine_open_video_driver (priv->xine, "none",
 
886
                                  (void *) &vis, (void *) &x11vis);
 
887
}
 
888
 
 
889
uint32_t gtk_video_get_capabilities (GtkVideo *this)
 
890
{
 
891
  gtk_video_private_t *priv = this->priv;
 
892
  return priv->video_port->get_capabilities (priv->video_port);
723
893
}
724
894
 
725
895
static void gtv_send_xine_mouse_event (gtk_video_private_t *priv,
761
931
  {
762
932
  case Expose:
763
933
    if (!xev->xexpose.count)
 
934
    {
 
935
#ifndef HAVE_XCB
764
936
      xine_port_send_gui_data (priv->video_port,
765
937
                               XINE_GUI_SEND_EXPOSE_EVENT, xev);
 
938
#else
 
939
      xcb_expose_event_t xcb_event;
 
940
      memset(&xcb_event, 0, sizeof(xcb_event));
 
941
 
 
942
      xcb_event.window = xev->xexpose.window;
 
943
      xcb_event.x      = xev->xexpose.x;
 
944
      xcb_event.y      = xev->xexpose.y;
 
945
      xcb_event.width  = xev->xexpose.width;
 
946
      xcb_event.height = xev->xexpose.height;
 
947
      xcb_event.count  = xev->xexpose.count;
 
948
 
 
949
      xine_port_send_gui_data (priv->video_port,
 
950
                               XINE_GUI_SEND_EXPOSE_EVENT, &xcb_event);
 
951
#endif
 
952
    }
766
953
    logprintf ("gtkvideo: expose event: %d,%d %dx%d %d\n",
767
954
               xev->xexpose.x, xev->xexpose.y,
768
955
               xev->xexpose.width, xev->xexpose.height, xev->xexpose.count);
1040
1227
                                            widget->allocation.height, 0,
1041
1228
                                            black_pixel.pixel, black_pixel.pixel);
1042
1229
 
 
1230
  /* not sure why this is needed in some situations... */
 
1231
  XEvent event;
 
1232
  XCheckWindowEvent (xdisplay, priv->video_window, -1, &event);
 
1233
      
1043
1234
  widget->window = gdk_window_foreign_new_for_display
1044
1235
                     (display, priv->video_window);
 
1236
  if (!widget->window)
 
1237
  {
 
1238
    g_printerr (_("gtkvideo: couldn't get a GDK handle for the video window!\n"));
 
1239
    return;
 
1240
  }
1045
1241
  gdk_window_set_user_data (widget->window, widget); /* allow GTK events */
1046
1242
  {
1047
1243
    /* enforce background colour */
1097
1293
   */
1098
1294
 
1099
1295
  priv->video_port = load_video_out_driver (this);
1100
 
 
1101
1296
  if (!priv->video_port)
1102
1297
  {
1103
 
    g_printerr (_("gtkvideo: couldn't open video driver\n"));
1104
 
    return;
 
1298
    display_error_modal (FROM_GXINE, _("Fatal error"),
 
1299
                         _("No video output driver could be loaded."));
 
1300
    exit (2);
1105
1301
  }
1106
1302
 
1107
1303
  /*
1199
1395
  priv->post_deinterlace.list = NULL;
1200
1396
  priv->post_video.list = NULL;
1201
1397
  priv->post_audio.list = NULL;
 
1398
  priv->frame_cb = NULL;
1202
1399
 
1203
1400
  if (video_driver_id)
1204
1401
    priv->video_driver_id = strdup (video_driver_id);
1210
1407
  return this;
1211
1408
}
1212
1409
 
 
1410
void gtk_video_set_frame_cb (GtkVideo *gtv, gtk_video_frame_cb_t cb,
 
1411
                             gpointer data)
 
1412
{
 
1413
   g_return_if_fail (GTK_IS_VIDEO(gtv));
 
1414
   gtv->priv->frame_cb = cb;
 
1415
   gtv->priv->frame_cb_data = data;
 
1416
}
 
1417
 
 
1418
void gtk_video_set_end_time (GtkVideo *gtv, gint end_time)
 
1419
{
 
1420
   g_return_if_fail (GTK_IS_VIDEO(gtv));
 
1421
   gtv->priv->end_time = end_time;
 
1422
}
 
1423
 
 
1424
static gboolean gtv_update_resize_factor (GtkVideo *this)
 
1425
{
 
1426
  gboolean send_signal = FALSE;
 
1427
  gtk_video_private_t *const priv = this->priv;
 
1428
  double new_factor;
 
1429
  if (priv->pending_resize)
 
1430
    new_factor = priv->resize_factor;
 
1431
  else
 
1432
  {
 
1433
    gboolean is_double =
 
1434
      IS_DOUBLE(priv->video_size.width, priv->video_size.height);
 
1435
    new_factor = this->widget.allocation.width * 100
 
1436
                 / (double)priv->video_size.width / (1 + is_double);
 
1437
    double new_factor_V = this->widget.allocation.height * 100
 
1438
                          / (double)priv->video_size.height
 
1439
                          / (1 + is_double);
 
1440
    if (new_factor > new_factor_V)
 
1441
      new_factor= new_factor_V;
 
1442
  }
 
1443
  /* tolerate rounding error when the video size has been changed... */
 
1444
  if (priv->pending_resize
 
1445
      || (round (priv->resize_factor * 64) != round (new_factor * 64)
 
1446
          && (fabs (new_factor - priv->resize_factor)
 
1447
                >= 25 / this->widget.allocation.height
 
1448
              || priv->old_video_size.height == priv->video_size.height)))
 
1449
  {
 
1450
    if (!priv->block_next_scale_change && GTK_WIDGET_VISIBLE (&this->widget))
 
1451
    {
 
1452
      priv->resize_factor = new_factor;
 
1453
      send_signal = TRUE;
 
1454
      /* stop frame_output_cb from scheduling a resize */
 
1455
      double factor = DOUBLE_STD();
 
1456
      priv->size = SCALE (factor);
 
1457
      logprintf ("gxine: video rescaled to %lf%%\n", new_factor);
 
1458
    }
 
1459
    else
 
1460
      logprintf ("blocked rescaling to %lf%%\n", new_factor);
 
1461
  }
 
1462
  return send_signal;
 
1463
}
 
1464
 
1213
1465
static void gtk_video_size_allocate (GtkWidget *widget,
1214
1466
                                     GtkAllocation *allocation)
1215
1467
{
1238
1490
        && GTK_WIDGET_VISIBLE (widget)
1239
1491
        && widget->allocation.width > GTK_VIDEO_MIN_WIDTH
1240
1492
        && widget->allocation.height > GTK_VIDEO_MIN_HEIGHT)
1241
 
    {
1242
 
      gtk_video_private_t *const priv = this->priv;
1243
 
      double new_factor;
1244
 
      if (priv->pending_resize)
1245
 
        new_factor = priv->resize_factor;
1246
 
      else
1247
 
      {
1248
 
        gboolean is_double =
1249
 
          IS_DOUBLE(priv->old_video_size.width, priv->old_video_size.height);
1250
 
        new_factor = this->widget.allocation.width * 100
1251
 
                     / (double)priv->old_video_size.width / (1 + is_double);
1252
 
        double new_factor_V = this->widget.allocation.height * 100
1253
 
                              / (double)priv->old_video_size.height
1254
 
                              / (1 + is_double);
1255
 
        if (new_factor > new_factor_V)
1256
 
          new_factor= new_factor_V;
1257
 
      }
1258
 
      /* tolerate rounding error when the video size has been changed... */
1259
 
      if (priv->pending_resize
1260
 
          || (round (priv->resize_factor * 64) != round (new_factor * 64)
1261
 
              && (fabs (new_factor - priv->resize_factor)
1262
 
                    >= 25 / this->widget.allocation.height
1263
 
                  || priv->old_video_size.height == priv->video_size.height)))
1264
 
      {
1265
 
        if (!priv->block_next_scale_change && GTK_WIDGET_VISIBLE (widget))
1266
 
        {
1267
 
          priv->resize_factor = new_factor;
1268
 
          send_signal = TRUE;
1269
 
          /* stop frame_output_cb from scheduling a resize */
1270
 
          double factor = DOUBLE_STD();
1271
 
          priv->size = SCALE (factor);
1272
 
          logprintf ("gxine: video rescaled to %lf%%\n", new_factor);
1273
 
        }
1274
 
        else
1275
 
          logprintf ("blocked rescaling to %lf%%\n", new_factor);
1276
 
      }
1277
 
    }
 
1493
      send_signal = gtv_update_resize_factor (this);
1278
1494
    if (!this->priv->resizing)
1279
1495
      this->priv->old_video_size = this->priv->video_size;
1280
1496
    this->priv->idle_resized = FALSE;
1955
2171
 
1956
2172
  priv->auto_rescale = set;
1957
2173
 
1958
 
  RESIZE_ADD ();
 
2174
  RESIZE_ADD (1);
1959
2175
}
1960
2176
 
1961
2177
gboolean gtk_video_get_auto_rescale (GtkVideo *gtv)
2044
2260
    {
2045
2261
      static const char *const argv[] = { GNOME_SCREENSAVER_COMMAND, "--poke", NULL };
2046
2262
      /* screensaver name is used in "can't poke <name>" */
2047
 
      gnome_screensaver = screensaver_poke (argv, _("gnome-screensaver"));
 
2263
      gnome_screensaver = screensaver_poke (argv, "gnome-screensaver");
2048
2264
    }
2049
2265
#endif
2050
2266
 
2056
2272
    if (!x_screensaver)
2057
2273
    {
2058
2274
      static const char *const argv[] = { X_SCREENSAVER_COMMAND, "--deactivate", NULL };
2059
 
      x_screensaver = screensaver_poke (argv, _("xscreensaver"));
 
2275
      x_screensaver = screensaver_poke (argv, "xscreensaver");
2060
2276
    }
2061
2277
#endif
2062
2278
  }