{
}
+static void
+gtk_media_stream_default_realize (GtkMediaStream *self,
+ GdkWindow *window)
+{
+}
+
+static void
+gtk_media_stream_default_unrealize (GtkMediaStream *self,
+ GdkWindow *window)
+{
+}
+
static void
gtk_media_stream_set_property (GObject *object,
guint prop_id,
class->pause = gtk_media_stream_default_pause;
class->seek = gtk_media_stream_default_seek;
class->update_audio = gtk_media_stream_default_update_audio;
+ class->realize = gtk_media_stream_default_realize;
+ class->unrealize = gtk_media_stream_default_unrealize;
gobject_class->set_property = gtk_media_stream_set_property;
gobject_class->get_property = gtk_media_stream_get_property;
g_object_notify_by_pspec (G_OBJECT (self), properties[PROP_VOLUME]);
}
+/**
+ * gtk_media_stream_realize:
+ * @self: a #GtkMediaStream
+ * @window: a #GdkWindow
+ *
+ * Called by users to attach the media stream to a #GdkWindow they manage.
+ * The stream can then access the resources of @window for its rendering
+ * purposes. In particular, media streams might want to create
+ * #GdkGLContexts or sync to the #GdkFrameClock.
+ *
+ * Whoever calls this function is responsible for calling
+ * gtk_media_stream_unrealize() before either the stream or @window get
+ * destroyed.
+ *
+ * Multiple calls to this function may happen from different users of the
+ * video, even with the same @window. Each of these calls must be followed
+ * by its own call to gtk_media_stream_unrealize().
+ *
+ * It is not required to call this function to make a media stream work.
+ **/
+void
+gtk_media_stream_realize (GtkMediaStream *self,
+ GdkWindow *window)
+{
+ g_return_if_fail (GTK_IS_MEDIA_STREAM (self));
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ g_object_ref (self);
+ g_object_ref (window);
+
+ GTK_MEDIA_STREAM_GET_CLASS (self)->realize (self, window);
+}
+
+/**
+ * gtk_media_stream_unrealize:
+ * @self: a #GtkMediaStream previously realized
+ * @window: the #GdkWindow the stream was realized with
+ *
+ * Undoes a previous call to gtk_media_stream_realize() and causes
+ * the stream to release all resources it had allocated from @window.
+ **/
+void
+gtk_media_stream_unrealize (GtkMediaStream *self,
+ GdkWindow *window)
+{
+ g_return_if_fail (GTK_IS_MEDIA_STREAM (self));
+ g_return_if_fail (GDK_IS_WINDOW (window));
+
+ GTK_MEDIA_STREAM_GET_CLASS (self)->unrealize (self, window);
+
+ g_object_unref (window);
+ g_object_unref (self);
+}
+
/**
* gtk_media_stream_prepared:
* @self: a #GtkMediaStream
void (* update_audio) (GtkMediaStream *self,
gboolean muted,
double volume);
+ void (* realize) (GtkMediaStream *self,
+ GdkWindow *window);
+ void (* unrealize) (GtkMediaStream *self,
+ GdkWindow *window);
+
/* Padding for future expansion */
void (*_gtk_reserved1) (void);
void (*_gtk_reserved2) (void);
GDK_AVAILABLE_IN_ALL
void gtk_media_stream_set_volume (GtkMediaStream *self,
double volume);
+GDK_AVAILABLE_IN_ALL
+void gtk_media_stream_realize (GtkMediaStream *self,
+ GdkWindow *window);
+GDK_AVAILABLE_IN_ALL
+void gtk_media_stream_unrealize (GtkMediaStream *self,
+ GdkWindow *window);
/* for implementations only */
GDK_AVAILABLE_IN_ALL
gtk_widget_size_allocate (self->box, allocation, baseline, out_clip);
}
+static void
+gtk_video_realize (GtkWidget *widget)
+{
+ GtkVideo *self = GTK_VIDEO (widget);
+
+ GTK_WIDGET_CLASS (gtk_video_parent_class)->realize (widget);
+
+ if (self->media_stream)
+ gtk_media_stream_realize (self->media_stream, gtk_widget_get_window (GTK_WIDGET (self)));
+
+ if (self->file)
+ gtk_media_file_set_file (GTK_MEDIA_FILE (self->media_stream), self->file);
+}
+
+static void
+gtk_video_unrealize (GtkWidget *widget)
+{
+ GtkVideo *self = GTK_VIDEO (widget);
+
+ if (self->media_stream)
+ gtk_media_stream_unrealize (self->media_stream, gtk_widget_get_window (GTK_WIDGET (self)));
+
+ GTK_WIDGET_CLASS (gtk_video_parent_class)->unrealize (widget);
+}
+
static void
gtk_video_unmap (GtkWidget *widget)
{
widget_class->measure = gtk_video_measure;
widget_class->size_allocate = gtk_video_size_allocate;
+ widget_class->realize = gtk_video_realize;
+ widget_class->unrealize = gtk_video_unrealize;
widget_class->unmap = gtk_video_unmap;
gobject_class->dispose = gtk_video_dispose;
g_signal_handlers_disconnect_by_func (self->media_stream,
gtk_video_notify_cb,
self);
+ if (gtk_widget_get_realized (GTK_WIDGET (self)))
+ gtk_media_stream_unrealize (self->media_stream, gtk_widget_get_window (GTK_WIDGET (self)));
g_object_unref (self->media_stream);
self->media_stream = NULL;
}
if (stream)
{
self->media_stream = g_object_ref (stream);
+ if (gtk_widget_get_realized (GTK_WIDGET (self)))
+ gtk_media_stream_realize (stream, gtk_widget_get_window (GTK_WIDGET (self)));
g_signal_connect (self->media_stream,
"notify",
G_CALLBACK (gtk_video_notify_cb),
gtk_video_set_file (GtkVideo *self,
GFile *file)
{
- GtkMediaStream *stream;
-
g_return_if_fail (GTK_IS_VIDEO (self));
g_return_if_fail (file == NULL || G_IS_FILE (file));
g_object_freeze_notify (G_OBJECT (self));
if (file)
- stream = gtk_media_file_new_for_file (file);
- else
- stream = NULL;
+ {
+ GtkMediaStream *stream;
- gtk_video_set_media_stream (self, stream);
+ stream = gtk_media_file_new ();
- if (stream)
- g_object_unref (stream);
+ gtk_video_set_media_stream (self, stream);
+ if (gtk_widget_get_realized (GTK_WIDGET (self)))
+ gtk_media_file_set_file (GTK_MEDIA_FILE (stream), file);
+
+ g_object_unref (stream);
+ }
+ else
+ {
+ gtk_video_set_media_stream (self, NULL);
+ }
g_object_thaw_notify (G_OBJECT (self));
}