[Xfce4-commits] <parole:master> Make the gstreamer back end common to use it in the media plugin and avoid duplicating code.

Ali Abdallah noreply at xfce.org
Thu Nov 19 11:20:02 CET 2009


Updating branch refs/heads/master
         to 061f3158492e4e27caa27e0b44826f1d1caff879 (commit)
       from 6ddf2e9926c6f5618aa6f720dbf0099160a57e66 (commit)

commit 061f3158492e4e27caa27e0b44826f1d1caff879
Author: Ali Abdallah <ali at ali-xfce.org>
Date:   Thu Nov 19 09:47:06 2009 +0100

    Make the gstreamer back end common to use it in the media plugin
    and avoid duplicating code.

 Makefile.am                                        |    2 +
 browser-plugin/media-plugin/Makefile.am            |   16 +-
 browser-plugin/media-plugin/main.c                 |   58 +-
 .../media-plugin/org.parole.media.plugin.xml       |    2 +-
 browser-plugin/media-plugin/parole-gst.c           |  795 --------------------
 browser-plugin/media-plugin/parole-plugin-player.c |  387 ++++++++++
 .../{parole-gst.h => parole-plugin-player.h}       |   36 +-
 common/Makefile.am                                 |   12 +-
 common/parole-common.c                             |   75 ++
 parole/parole-about.h => common/parole-common.h    |   10 +-
 configure.ac.in                                    |    2 +
 {common => dbus}/Makefile.am                       |    0
 {common => dbus}/parole-dbus.c                     |    0
 {common => dbus}/parole-dbus.h                     |    0
 gst/Makefile.am                                    |   84 ++
 gst/gstmarshal.list                                |    4 +
 {parole => gst}/parole-gst.c                       |  188 ++++-
 {parole => gst}/parole-gst.h                       |   23 +-
 {parole => gst}/parole-stream.c                    |   30 +-
 {parole => gst}/parole-stream.h                    |    0
 parole/Makefile.am                                 |   18 +-
 parole/gmarshal.list                               |    3 -
 parole/parole-conf-dialog.c                        |    2 +-
 parole/parole-conf.c                               |    9 +-
 parole/parole-conf.h                               |   12 +-
 parole/parole-disc-menu.c                          |    2 +-
 parole/parole-mediachooser.c                       |    2 +
 parole/parole-medialist.c                          |    2 +
 parole/parole-player.c                             |   27 +-
 parole/parole-plugin.c                             |    4 +-
 parole/parole-utils.c                              |   44 --
 parole/parole-utils.h                              |    4 -
 32 files changed, 853 insertions(+), 1000 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index 8ab26c5..d6d9f46 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -5,6 +5,8 @@ endif
 SUBDIRS =  			\
 	data			\
 	common			\
+	gst			\
+	dbus			\
 	parole 			\
 	plugins			\
 	$(browser_plugin_dir)  	\
diff --git a/browser-plugin/media-plugin/Makefile.am b/browser-plugin/media-plugin/Makefile.am
index 513d437..f9a2421 100644
--- a/browser-plugin/media-plugin/Makefile.am
+++ b/browser-plugin/media-plugin/Makefile.am
@@ -2,30 +2,34 @@ libexec_PROGRAMS = parole-media-plugin
 
 parole_media_plugin_SOURCES =			\
 	main.c					\
-	parole-gst.c				\
-	parole-gst.h				\
+	parole-plugin-player.c			\
+	parole-plugin-player.h			\
 	org.parole.media.plugin.h
 
 parole_media_plugin_CFLAGS =			\
 	-I$(top_srcdir)                         \
         -I$(top_srcdir)/data                    \
         -I$(top_srcdir)/data/mime               \
-	-I$(top_srcdir)/common               	\
+	-I$(top_srcdir)/dbus               	\
+	-I$(top_srcdir)/gst               	\
         -DLOCALEDIR=\"$(localedir)\"            \
         -DG_LOG_DOMAIN=\"parole-media-plugin\"  \
 	$(GTHREAD_CFLAGS)                       \
 	$(GTK_CFLAGS)				\
 	$(GST_VIDEO_CFLAGS)                     \
         $(GST_INTERFACES_CFLAGS)		\
-	$(DBUS_GLIB_CFLAGS)
+	$(DBUS_GLIB_CFLAGS)			\
+	$(LIBXFCE4GUI_CFLAGS)
 
 parole_media_plugin_LDADD =			\
-	$(top_builddir)/common/libparoledbus.la \
+	$(top_builddir)/dbus/libparoledbus.la 	\
+	$(top_builddir)/gst/libparolegst.la 	\
 	$(GTHREAD_LIBS)                       	\
 	$(GTK_LIBS)				\
 	$(GST_VIDEO_LIBS)                     	\
         $(GST_INTERFACES_LIBS)			\
-	$(DBUS_GLIB_LIBS)
+	$(DBUS_GLIB_LIBS)			\
+	$(LIBXFCE4GUI_LIBS)
 
 if MAINTAINER_MODE
 
diff --git a/browser-plugin/media-plugin/main.c b/browser-plugin/media-plugin/main.c
index dad22c9..3508868 100644
--- a/browser-plugin/media-plugin/main.c
+++ b/browser-plugin/media-plugin/main.c
@@ -34,26 +34,20 @@
 
 #include <gst/gst.h>
 
-#include "parole-gst.h"
+#include "parole-plugin-player.h"
 
-#include "common/parole-dbus.h"
-
-static gboolean 
-parole_terminate (GtkWidget *widget, GdkEvent *ev, ParoleGst *gst)
-{
-    parole_gst_terminate (gst);
-    g_debug ("Terminating");
-    return TRUE;
-}
+#include "dbus/parole-dbus.h"
 
 int main (int argc, char **argv)
 {
+    ParolePluginPlayer *player;
     GdkNativeWindow socket_id = 0;
     gchar *url = NULL;
     GOptionContext *ctx;
     GOptionGroup *gst_option_group;
     GError *error = NULL;
     gchar *dbus_name;
+    GtkWidget *plug;
     
     GOptionEntry option_entries[] = 
     {
@@ -94,41 +88,21 @@ int main (int argc, char **argv)
     }
     g_option_context_free (ctx);
     
-    {
-	dbus_name = g_strdup_printf ("org.Parole.Media.Plugin%d", socket_id);
-	parole_dbus_register_name (dbus_name);
-    }
+    dbus_name = g_strdup_printf ("org.Parole.Media.Plugin%d", socket_id);
+    parole_dbus_register_name (dbus_name);
     
-    {
-	GtkWidget *box;
-	GtkWidget *plug;
-	GtkWidget *gst;
-	
-	gulong sig_id;
-	plug = gtk_plug_new (socket_id);
-	
-	box = gtk_vbox_new (FALSE, 0);
-	
-	gst = parole_gst_new ();
-	
-	gtk_box_pack_start (GTK_BOX (box), gst, TRUE, TRUE, 0);
-	gtk_box_pack_start (GTK_BOX (box), parole_gst_get_controls (PAROLE_GST (gst)), 
-			    FALSE, FALSE, 0);
-	
-	gtk_container_add (GTK_CONTAINER (plug), box);
+    g_assert (url != NULL);
+    
+    plug = gtk_plug_new (socket_id);
 	
-	sig_id = g_signal_connect (plug, "delete-event",
-				   G_CALLBACK (parole_terminate), gst);
-				   
-	gtk_widget_show_all (plug);
-	parole_gst_play_url (PAROLE_GST (gst), url);
+    player = parole_plugin_player_new (plug, url);
 	
-	gtk_main ();
-	g_signal_handler_disconnect (plug, sig_id);
-	gtk_widget_destroy (plug);
-	parole_dbus_release_name (dbus_name);
-	g_free (dbus_name);
-    }
+    gtk_widget_show_all (plug);
+    
+    gtk_main ();
+    gtk_widget_destroy (plug);
+    parole_dbus_release_name (dbus_name);
+    g_free (dbus_name);
 
     gst_deinit ();
 
diff --git a/browser-plugin/media-plugin/org.parole.media.plugin.xml b/browser-plugin/media-plugin/org.parole.media.plugin.xml
index 2da359c..a83d6bf 100644
--- a/browser-plugin/media-plugin/org.parole.media.plugin.xml
+++ b/browser-plugin/media-plugin/org.parole.media.plugin.xml
@@ -3,7 +3,7 @@
 <node name="/">
     <interface name="org.Parole.Media.Plugin">
         <annotation name="org.freedesktop.DBus.GLib.CSymbol"
-                    value="parole_gst_dbus"/>
+                    value="parole_plugin_player_dbus"/>
 
     <method name="Quit">
     </method>
diff --git a/browser-plugin/media-plugin/parole-gst.c b/browser-plugin/media-plugin/parole-gst.c
deleted file mode 100644
index 8ba5c06..0000000
--- a/browser-plugin/media-plugin/parole-gst.c
+++ /dev/null
@@ -1,795 +0,0 @@
-/*
- * * Copyright (C) 2009 Ali <aliov at xfce.org>
- *
- * Licensed under the GNU General Public License Version 2
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License as published by
- * the Free Software Foundation; either version 2 of the License, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
- */
-
-#ifdef HAVE_CONFIG_H
-#include <config.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-
-#include <gst/interfaces/xoverlay.h>
-#include <gst/interfaces/navigation.h>
-
-#include <gst/video/video.h>
-
-#include <gdk/gdkx.h>
-
-#include <dbus/dbus-glib.h>
-
-#include "parole-gst.h"
-
-#include "interfaces/browser-plugin-control_ui.h"
-#include "common/parole-dbus.h"
-
-/*
- * DBus Glib init
- */
-static void parole_gst_dbus_class_init (ParoleGstClass *klass);
-static void parole_gst_dbus_init       (ParoleGst *gst);
-
-static void parole_gst_finalize   (GObject *object);
-
-#define PAROLE_GST_GET_PRIVATE(o) \
-(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_GST, ParoleGstPrivate))
-
-struct ParoleGstPrivate
-{
-    GstElement	 *playbin;
-    GstElement   *video_sink;
-    GstBus       *bus;
-    
-    GstState      state;
-    GstState      target;
-    
-    GtkWidget	 *controls;
-    GtkWidget	 *play;
-    GtkWidget	 *range;
-    
-    gulong	  sig1;
-    gulong	  sig2;
-    gulong	  tick_id;
-    
-    gboolean	  terminate;
-    gboolean      internal_range_change;
-    gboolean      user_seeking;
-
-    /* Stream properties*/
-    gboolean	  has_video;
-    gboolean      has_audio;
-    gboolean	  buffering;
-    gboolean      live;
-    gboolean      seekable;
-    gdouble   	  duration;
-    gint64  	  absolute_duration;
-    
-};
-
-G_DEFINE_TYPE (ParoleGst, parole_gst, GTK_TYPE_WIDGET)
-
-static void parole_gst_seek (ParoleGst *gst, gdouble pos)
-{
-    gint64 seek;
-    
-    seek = (gint64) (pos * gst->priv->absolute_duration) / gst->priv->duration;
-    
-    g_debug ("seeking %lld", seek);
-    
-    g_warn_if_fail ( gst_element_seek (gst->priv->playbin,
-				       1.0,
-				       GST_FORMAT_TIME,
-				       GST_SEEK_FLAG_FLUSH | GST_SEEK_FLAG_KEY_UNIT,
-				       GST_SEEK_TYPE_SET, seek,
-				       GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE));
-				       
-    gst_element_get_state (gst->priv->playbin, NULL, NULL, 100 * GST_MSECOND);
-}
-
-static void
-parole_gst_range_value_changed (GtkRange *range, ParoleGst *gst)
-{
-    gdouble value;
-    
-    if ( !gst->priv->internal_range_change )
-    {
-	value = gtk_range_get_value (GTK_RANGE (range));
-	gst->priv->user_seeking = TRUE;
-	parole_gst_seek (gst, value);
-	gst->priv->user_seeking = FALSE;
-    }
-}
-
-static gboolean
-parole_gst_range_button_release (GtkWidget *widget, GdkEventButton *ev, ParoleGst *gst)
-{
-    ev->button = 2;
-    
-    gst->priv->user_seeking = FALSE;
-    
-    return FALSE;
-}
-
-static gboolean
-parole_gst_range_button_press (GtkWidget *widget, GdkEventButton *ev, ParoleGst *gst)
-{
-    ev->button = 2;
-    
-    gst->priv->user_seeking = TRUE;
-    
-    return FALSE;
-}
-
-static void
-parole_gst_change_range_value (ParoleGst *gst, gdouble value)
-{
-    if ( !gst->priv->user_seeking )
-    {
-	gst->priv->internal_range_change = TRUE;
-    
-	gtk_range_set_value (GTK_RANGE (gst->priv->range), value);
-
-	gst->priv->internal_range_change = FALSE;
-    }
-}
-
-static void
-parole_gst_init_stream_properties (ParoleGst *gst)
-{
-    gst->priv->has_video = FALSE;
-    gst->priv->has_audio = FALSE;
-    gst->priv->buffering = FALSE;
-    gst->priv->duration  = 0;
-    gst->priv->absolute_duration = 0;
-    gst->priv->seekable = FALSE;
-    gst->priv->live = FALSE;
-    
-    gst->priv->user_seeking = FALSE;
-    
-    parole_gst_change_range_value (gst, 0);
-    gtk_widget_set_sensitive (gst->priv->range, FALSE);
-    gst->priv->internal_range_change = FALSE;
-}
-
-static gboolean
-parole_gst_tick_timeout (gpointer data)
-{
-    ParoleGst *gst;
-    
-    gint64 pos;
-    GstFormat format = GST_FORMAT_TIME;
-    gdouble value;
-    
-    gst = PAROLE_GST (data);
-    
-    gst_element_query_position (gst->priv->playbin, &format, &pos);
-    
-    if ( G_UNLIKELY (format != GST_FORMAT_TIME ) )
-	goto out;
-
-    if ( gst->priv->live )
-    {
-	gst->priv->tick_id = 0;
-	return FALSE;
-    }
-
-    if ( gst->priv->state == GST_STATE_PLAYING )
-    {
-	value = ( pos / ((gdouble) 60 * 1000 * 1000 * 1000 ));
-	parole_gst_change_range_value (gst, value);
-    }
-
-out:
-    return TRUE;
-}
-
-static void
-parole_gst_tick (ParoleGst *gst)
-{
-    if ( gst->priv->state >= GST_STATE_PAUSED )
-    {
-	if ( gst->priv->tick_id != 0 )
-	{
-	    return;
-	}
-	gst->priv->tick_id = g_timeout_add (1000, (GSourceFunc) parole_gst_tick_timeout, gst);
-    }
-    else if ( gst->priv->tick_id != 0)
-    {
-        g_source_remove (gst->priv->tick_id);
-	gst->priv->tick_id = 0;
-    }
-}
-
-static void
-parole_gst_set_play_button_image (ParoleGst *gst)
-{
-    GtkWidget *img;
-    
-    g_object_get (G_OBJECT (gst->priv->play),
-                  "image", &img,
-                  NULL);
-
-    if ( gst->priv->state == GST_STATE_PLAYING )
-    {
-        g_object_set (G_OBJECT (img),
-                      "stock", GTK_STOCK_MEDIA_PAUSE,
-                      NULL);
-    }
-    else
-    {
-        g_object_set (G_OBJECT (img),
-                      "stock", GTK_STOCK_MEDIA_PLAY,
-                      NULL);
-                      
-    }
-    g_object_unref (img);
-}
-
-static void
-parole_gst_query_capabilities (ParoleGst *gst)
-{
-    GstQuery *query;
-    
-    query = gst_query_new_seeking (GST_FORMAT_TIME);
-    
-    if ( gst_element_query (gst->priv->playbin, query) )
-    {
-	gst_query_parse_seeking (query,
-				 NULL,
-				 &gst->priv->seekable,
-				 NULL,
-				 NULL);
-				 
-	gtk_widget_set_sensitive (gst->priv->range, gst->priv->seekable);
-    }
-    gst_query_unref (query);
-}
-
-static void
-parole_gst_query_info (ParoleGst *gst)
-{
-    const GList *info = NULL;
-    GObject *obj;
-    GEnumValue *val;
-    GParamSpec *pspec;
-    gint type;
-    
-    g_object_get (G_OBJECT (gst->priv->playbin),
-		  "stream-info", &info,
-		  NULL);
-		  
-    for ( ; info != NULL; info = info->next )
-    {
-	obj = info->data;
-	
-	g_object_get (obj,
-		      "type", &type,
-		      NULL);
-	
-	pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (obj), "type");
-	val = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
-	
-	if ( g_ascii_strcasecmp (val->value_name, "video") == 0 ||
-	     g_ascii_strcasecmp (val->value_nick, "video") == 0)
-	{
-	    gst->priv->has_video = TRUE;
-	}
-	if ( g_ascii_strcasecmp (val->value_name, "audio") == 0 ||
-	     g_ascii_strcasecmp (val->value_nick, "audio") == 0)
-	{
-	    gst->priv->has_video = TRUE;
-	}
-    }
-}
-
-static void
-parole_gst_query_duration (ParoleGst *gst)
-{
-    GstFormat gst_time;
-    
-    gst_time = GST_FORMAT_TIME;
-    
-    gst_element_query_duration (gst->priv->playbin, 
-				&gst_time,
-				&gst->priv->absolute_duration);
-    
-    if (gst_time == GST_FORMAT_TIME)
-    {
-	gst->priv->duration =  gst->priv->absolute_duration / ((gdouble) 60 * 1000 * 1000 * 1000);
-	gst->priv->live = ( gst->priv->absolute_duration == 0 );
-	
-	g_debug ("Stream duration=%f absolution_duration=%lld",  
-		 gst->priv->duration ,  gst->priv->absolute_duration);
-		 
-	if ( !gst->priv->live )
-	{
-	    gst->priv->internal_range_change = TRUE;
-	    gtk_range_set_range (GTK_RANGE (gst->priv->range), 0, gst->priv->duration);
-	    gst->priv->internal_range_change = FALSE;
-	}
-    }
-}
-
-static void
-parole_gst_evaluate_state (ParoleGst *gst, GstState old, GstState new, GstState pending)
-{
-    gst->priv->state = new;
-    
-    parole_gst_set_play_button_image (gst);
-    parole_gst_tick (gst);
-
-    switch (gst->priv->state)
-    {
-	case GST_STATE_PLAYING:
-	    break;
-	case GST_STATE_PAUSED:
-	    if ( old == GST_STATE_READY )
-	    {
-		parole_gst_query_duration (gst);
-		parole_gst_query_capabilities (gst);
-		parole_gst_query_info (gst);
-	    }
-	    break;
-	case GST_STATE_READY:
-	    gst->priv->buffering = FALSE;
-	    break;
-	case GST_STATE_NULL:
-	    gst->priv->buffering = FALSE;
-	    if ( gst->priv->terminate )
-	    {
-		g_debug ("Exiting");
-		gtk_main_quit ();
-	    }
-	    break;
-	default:
-	    break;
-    }
-}
-
-static void
-parole_gst_change_state (ParoleGst *gst, GstState new)
-{
-    GstStateChangeReturn ret;
-
-    ret = gst_element_set_state (GST_ELEMENT (gst->priv->playbin), new);
-    
-    if ( ret == GST_STATE_CHANGE_SUCCESS )
-    {
-	parole_gst_evaluate_state (gst, 
-				   GST_STATE_RETURN (gst->priv->playbin),
-				   GST_STATE (gst->priv->playbin),
-				   GST_STATE_PENDING (gst->priv->playbin));
-    }
-}
-
-static void
-parole_gst_set_x_overlay (ParoleGst *gst)
-{
-    GstElement *video_sink;
-    
-    g_object_get (G_OBJECT (gst->priv->playbin),
-		  "video-sink", &video_sink,
-		  NULL);
-		  
-    g_assert (video_sink != NULL);
-    
-    gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (video_sink),
-				  GDK_WINDOW_XWINDOW (GTK_WIDGET (gst)->window));
-    
-    gst_object_unref (video_sink);
-}
-
-static void
-parole_gst_element_message_sync (GstBus *bus, GstMessage *message, ParoleGst *gst)
-{
-    if ( !message->structure )
-	goto out;
-	
-    if ( gst_structure_has_name (message->structure, "prepare-xwindow-id") )
-	parole_gst_set_x_overlay (gst);
-out:
-    ;
-}
-
-static void
-parole_gst_stream_info_notify_cb (GObject * obj, GParamSpec * pspec, ParoleGst *gst)
-{
-    GstMessage *msg;
-    msg = gst_message_new_application (GST_OBJECT (gst->priv->playbin),
-				       gst_structure_new ("notify-streaminfo", NULL));
-    gst_element_post_message (gst->priv->playbin, msg);
-}
-
-static gboolean
-parole_gst_bus_event (GstBus *bus, GstMessage *msg, gpointer data)
-{
-    ParoleGst *gst;
-    
-    gst = PAROLE_GST (data);
-
-    switch (GST_MESSAGE_TYPE (msg))
-    {
-        case GST_MESSAGE_EOS:
-	{
-	    break;
-	}
-	case GST_MESSAGE_ERROR:
-	{
-	    GError *error = NULL;
-	    gchar *debug;
-	    
-	    gst->priv->target = GST_STATE_NULL;
-	    gst->priv->buffering = FALSE;
-	    parole_gst_change_state (gst, GST_STATE_NULL);
-	    gst_message_parse_error (msg, &error, &debug);
-	    g_critical ("*** ERROR %s : %s ***", error->message, debug);
-	    g_error_free (error);
-	    g_free (debug);
-	    gtk_widget_queue_draw (GTK_WIDGET (gst));
-	    break;
-	}
-	case GST_MESSAGE_BUFFERING:
-	{
-	    gint per = 0;
-	    gst_message_parse_buffering (msg, &per);
-	    gst->priv->buffering = per != 100;
-	    if ( per != 100 && gst->priv->state != GST_STATE_PAUSED)
-		parole_gst_change_state (gst, GST_STATE_PAUSED);
-	    else if ( gst->priv->state != GST_STATE_PLAYING)
-		parole_gst_change_state (gst, GST_STATE_PLAYING);
-		
-	    break;
-	}
-	case GST_MESSAGE_STATE_CHANGED:
-	{
-	    GstState old, new, pending;
-	    gst_message_parse_state_changed (msg, &old, &new, &pending);
-	    
-	    if ( GST_MESSAGE_SRC (msg) == GST_OBJECT (gst->priv->playbin) )
-		parole_gst_evaluate_state (gst, old, new, pending);
-	    break;
-	}
-	case GST_MESSAGE_APPLICATION:
-	   // parole_gst_application_message (gst, msg);
-	    break;
-	case GST_MESSAGE_DURATION:
-	    //parole_gst_query_duration (gst);
-	    break;
-	default:
-	    break;
-    }
-    return TRUE;
-}
-
-static void
-parole_gst_play_clicked_cb (ParoleGst *gst)
-{
-    if ( gst->priv->state == GST_STATE_PLAYING )
-	parole_gst_change_state (gst, GST_STATE_PAUSED);
-    else
-	parole_gst_change_state (gst, GST_STATE_PLAYING);
-}
-
-static void
-parole_gst_construct (GObject *object)
-{
-    ParoleGst *gst;
-    
-    gst = PAROLE_GST (object);
-    
-    gst->priv->playbin = gst_element_factory_make ("playbin", "player");
- 
-    if ( G_UNLIKELY (gst->priv->playbin == NULL) )
-    {
-	g_critical ("playbin load failed");
-	return;
-    }
-    
-    gst->priv->video_sink = gst_element_factory_make ("xvimagesink", "video");
-
-    if ( G_UNLIKELY (gst->priv->video_sink == NULL) )
-    {
-	g_debug ("xvimagesink not found, trying to load ximagesink"); 
-	gst->priv->video_sink = gst_element_factory_make ("ximagesink", "video");
-	
-	if ( G_UNLIKELY (gst->priv->video_sink == NULL) )
-	{
-	    g_critical ("ximagesink load failed");
-	    return;
-	}
-    }
-    
-    g_object_set (G_OBJECT (gst->priv->playbin),
-		  "video-sink", gst->priv->video_sink,
-		  NULL);
-    
-    /*
-     * Listen to the bus events.
-     */
-    gst->priv->bus = gst_element_get_bus (gst->priv->playbin);
-    gst_bus_add_signal_watch (gst->priv->bus);
-    
-    gst->priv->sig1 =
-	g_signal_connect (gst->priv->bus, "message",
-			  G_CALLBACK (parole_gst_bus_event), gst);
-		      
-    /* 
-     * Handling 'prepare-xwindow-id' message async causes XSync 
-     * error in some occasions So we handle this message synchronously
-     */
-    gst_bus_set_sync_handler (gst->priv->bus, gst_bus_sync_signal_handler, gst);
-    gst->priv->sig2 =
-	g_signal_connect (gst->priv->bus, "sync-message::element",
-			  G_CALLBACK (parole_gst_element_message_sync), gst);
-
-    /*
-     * Handle stream info changes, this can happen on live/radio stream.
-     */
-    g_signal_connect (gst->priv->playbin, "notify::stream-info",
-		      G_CALLBACK (parole_gst_stream_info_notify_cb), gst);
-}
-
-static gboolean
-parole_gst_expose_event (GtkWidget *widget, GdkEventExpose *ev)
-{
-    ParoleGst *gst;
-    
-    if ( ev && ev->count > 0 )
-	return TRUE;
-
-    gst = PAROLE_GST (widget);
-
-    parole_gst_set_x_overlay (gst);
-
-    if ( gst->priv->has_video )
-    {
-	gst_x_overlay_expose (GST_X_OVERLAY (gst->priv->video_sink));
-    }
-	
-    return TRUE;
-}
-
-static void
-parole_gst_show (GtkWidget *widget)
-{
-    ParoleGst *gst;
-    
-    gst = PAROLE_GST (widget);
-    
-    if ( widget->window )
-	gdk_window_show (widget->window);
-    
-    if ( GTK_WIDGET_CLASS (parole_gst_parent_class)->show )
-	GTK_WIDGET_CLASS (parole_gst_parent_class)->show (widget);
-}
-
-static void
-parole_gst_realize (GtkWidget *widget)
-{
-    ParoleGst *gst;
-    GdkWindowAttr attr;
-    GdkColor color;
-    gint mask;
-    
-    GTK_WIDGET_SET_FLAGS (widget, GTK_REALIZED);
-    gst = PAROLE_GST (widget);
-    
-    attr.x = widget->allocation.x;
-    attr.y = widget->allocation.y;
-    attr.width = widget->allocation.width;
-    attr.height = widget->allocation.height;
-    attr.visual = gtk_widget_get_visual (widget);
-    attr.colormap = gtk_widget_get_colormap (widget);
-    attr.wclass = GDK_INPUT_OUTPUT;
-    attr.window_type = GDK_WINDOW_CHILD;
-    attr.event_mask = gtk_widget_get_events (widget) | 
-                      GDK_EXPOSURE_MASK |
-	              GDK_BUTTON_PRESS_MASK | 
-                      GDK_BUTTON_RELEASE_MASK | 
-		      GDK_POINTER_MOTION_MASK |
-		      GDK_KEY_PRESS_MASK;
-		      
-    mask = GDK_WA_X | GDK_WA_Y | GDK_WA_VISUAL | GDK_WA_COLORMAP;
-	
-    widget->window = gdk_window_new (gtk_widget_get_parent_window (widget),
-				     &attr, mask);
-				     
-    gdk_window_set_user_data (widget->window, widget);
-    gdk_color_parse ("black", &color);
-    gdk_colormap_alloc_color (gtk_widget_get_colormap (widget), &color,
-			      TRUE, TRUE);
-    
-    gdk_window_set_background (widget->window, &color);
-    widget->style = gtk_style_attach (widget->style, widget->window);
-}
-
-static void
-parole_gst_class_init (ParoleGstClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS (klass);
-    GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
-
-    object_class->finalize = parole_gst_finalize;
-    object_class->constructed = parole_gst_construct;
-    
-    widget_class->realize = parole_gst_realize;
-    widget_class->show = parole_gst_show;
-    widget_class->expose_event = parole_gst_expose_event;
-
-    g_type_class_add_private (klass, sizeof (ParoleGstPrivate));
-    
-    parole_gst_dbus_class_init (klass);
-}
-
-static void
-parole_gst_init (ParoleGst *gst)
-{
-    GtkBuilder *builder;
-    GError *error = NULL;
-    
-    gst->priv = PAROLE_GST_GET_PRIVATE (gst);
-    
-    gst->priv->state = GST_STATE_VOID_PENDING;
-    gst->priv->target = GST_STATE_VOID_PENDING;
-    
-    gst->priv->tick_id = 0;
-    
-    gst->priv->terminate = FALSE;
-    
-    builder = gtk_builder_new ();
-    gtk_builder_add_from_string (builder, 
-				 browser_plugin_control_ui, 
-				 browser_plugin_control_ui_length,
-				 &error);
-				 
-    if ( error )
-    {
-	g_error ("%s", error->message);
-    }
-    
-    gst->priv->controls = GTK_WIDGET (gtk_builder_get_object (builder, "controls"));
-    
-    gst->priv->range = GTK_WIDGET (gtk_builder_get_object (builder, "scale"));
-    
-    gst->priv->play = GTK_WIDGET (gtk_builder_get_object (builder, "play"));
-    
-    g_signal_connect_swapped (gst->priv->play, "clicked",
-			      G_CALLBACK (parole_gst_play_clicked_cb), gst);
-
-    g_signal_connect (gst->priv->range, "button-press-event",
-		      G_CALLBACK (parole_gst_range_button_press), gst);
-
-    g_signal_connect (gst->priv->range, "button-release-event",
-		      G_CALLBACK (parole_gst_range_button_release), gst);
-		      
-    g_signal_connect (gst->priv->range, "value-changed",
-		      G_CALLBACK (parole_gst_range_value_changed), gst);
-
-    parole_gst_init_stream_properties (gst);
-    
-    GTK_WIDGET_SET_FLAGS (GTK_WIDGET (gst), GTK_CAN_FOCUS);
-    
-    /*
-     * Disable double buffering on the video output to avoid
-     * flickering when resizing the window.
-     */
-    GTK_WIDGET_UNSET_FLAGS (GTK_WIDGET (gst), GTK_DOUBLE_BUFFERED);
-    
-    parole_gst_dbus_init (gst);
-}
-
-static void
-parole_gst_finalize (GObject *object)
-{
-    ParoleGst *gst;
-
-    gst = PAROLE_GST (object);
-    
-    g_object_unref (gst->priv->playbin);
-    
-    if ( gst->priv->tick_id != 0)
-	g_source_remove (gst->priv->tick_id);
-
-    G_OBJECT_CLASS (parole_gst_parent_class)->finalize (object);
-}
-
-GtkWidget *
-parole_gst_new (void)
-{
-    GtkWidget *gst = NULL;
-    gst = g_object_new (PAROLE_TYPE_GST, NULL);
-    return gst;
-}
-
-void parole_gst_play_url (ParoleGst *gst, const gchar *url)
-{
-    g_return_if_fail (gst->priv->playbin != NULL);
-    
-    g_object_set (G_OBJECT (gst->priv->playbin),
-		  "uri", url,
-		  NULL);
-    gst->priv->target = GST_STATE_PLAYING;
-    parole_gst_change_state (gst, GST_STATE_PLAYING);
-}
-
-void parole_gst_terminate (ParoleGst *gst)
-{
-    g_return_if_fail (gst->priv->playbin != NULL);
-    
-    gst->priv->terminate = TRUE;
-    gst->priv->target = GST_STATE_NULL;
-    parole_gst_change_state (gst, GST_STATE_NULL);
-}
-
-GtkWidget *parole_gst_get_controls (ParoleGst *gst)
-{
-    g_return_val_if_fail (gst->priv->playbin != NULL, NULL);
-    
-    return gst->priv->controls;
-}
-
-static gboolean parole_gst_dbus_quit (ParoleGst *gst,
-				      GError **error);
-
-
-static gboolean parole_gst_dbus_terminate (ParoleGst *gst,
-					   GError **error);
-
-#include "org.parole.media.plugin.h"
-
-/*
- * DBus server implementation
- */
-static void 
-parole_gst_dbus_class_init (ParoleGstClass *klass)
-{
-    
-    dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
-                                     &dbus_glib_parole_gst_object_info);
-                                     
-}
-
-static void
-parole_gst_dbus_init (ParoleGst *gst)
-{
-    dbus_g_connection_register_g_object (parole_g_session_bus_get (),
-                                         "/org/Parole/Media/Plugin",
-                                         G_OBJECT (gst));
-}
-
-static gboolean
-parole_gst_dbus_quit (ParoleGst *gst,
-		      GError **error)
-{
-    g_debug ("Quit message received");
-    
-    parole_gst_terminate (gst);
-    
-    return TRUE;
-}
-
-static gboolean 
-parole_gst_dbus_terminate (ParoleGst *gst, GError **error)
-{
-    g_debug ("Terminate message received");
-    parole_gst_change_state (gst, GST_STATE_NULL);
-    return TRUE;
-}
diff --git a/browser-plugin/media-plugin/parole-plugin-player.c b/browser-plugin/media-plugin/parole-plugin-player.c
new file mode 100644
index 0000000..2bde37e
--- /dev/null
+++ b/browser-plugin/media-plugin/parole-plugin-player.c
@@ -0,0 +1,387 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include "parole-plugin-player.h"
+
+#include "gst/parole-gst.h"
+#include "dbus/parole-dbus.h"
+#include "interfaces/browser-plugin-control_ui.h"
+
+/*
+ * DBus Glib init
+ */
+static void parole_plugin_player_dbus_class_init (ParolePluginPlayerClass *klass);
+static void parole_plugin_player_dbus_init       (ParolePluginPlayer *player);
+
+static void parole_plugin_player_finalize     (GObject *object);
+
+static void parole_plugin_player_set_property (GObject *object,
+					       guint prop_id,
+					       const GValue *value,
+					       GParamSpec *pspec);
+static void parole_plugin_player_get_property (GObject *object,
+					       guint prop_id,
+					       GValue *value,
+					       GParamSpec *pspec);
+
+#define PAROLE_PLUGIN_PLAYER_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_PLUGINPLAYER, ParolePluginPlayerPrivate))
+
+struct ParolePluginPlayerPrivate
+{
+    ParoleGst    *gst;
+    GtkWidget    *plug;
+    GtkWidget	 *controls;
+    GtkWidget	 *play;
+    GtkWidget	 *range;
+    
+    gboolean      internal_range_change;
+    gboolean      user_seeking;
+    gboolean      terminate;
+    gchar        *url;
+    gulong        sig;
+};
+
+enum
+{
+    PROP_0,
+    PROP_PLUG,
+    PROP_URL
+};
+
+G_DEFINE_TYPE (ParolePluginPlayer, parole_plugin_player, G_TYPE_OBJECT)
+
+static void
+parole_plugin_player_play_clicked_cb (ParoleGst *gst)
+{
+}
+
+static void
+parole_plugin_player_media_state_cb (ParoleGst *gst, const ParoleStream *stream, 
+				     ParoleMediaState state, ParolePluginPlayer *player)
+{
+    if ( state == PAROLE_MEDIA_STATE_PLAYING )
+    {
+	//parole_player_playing (player, stream);
+    }
+    else if ( state == PAROLE_MEDIA_STATE_PAUSED )
+    {
+	//parole_player_paused (player);
+    }
+    else if ( state == PAROLE_MEDIA_STATE_STOPPED )
+    {
+	if ( player->priv->terminate )
+	{
+	    g_object_unref (player);
+	    gtk_main_quit ();
+	}
+	//parole_player_stopped (player);
+    }
+    else if ( state == PAROLE_MEDIA_STATE_FINISHED )
+    {
+	//
+    }
+}
+
+static gboolean 
+parole_plugin_player_terminate (GtkWidget *widget, GdkEvent *ev, ParolePluginPlayer *player)
+{
+    parole_gst_terminate (player->priv->gst);
+    g_signal_handler_disconnect (player->priv->plug, player->priv->sig);
+    player->priv->terminate = TRUE;
+    return TRUE;
+}
+
+static void
+parole_plugin_player_range_value_changed (GtkRange *range, ParolePluginPlayer *player)
+{
+    gdouble value;
+    
+    if ( !player->priv->internal_range_change )
+    {
+	value = gtk_range_get_value (GTK_RANGE (range));
+	player->priv->user_seeking = TRUE;
+	parole_gst_seek (player->priv->gst, value);
+	player->priv->user_seeking = FALSE;
+    }
+}
+
+static gboolean
+parole_plugin_player_range_button_release (GtkWidget *widget, GdkEventButton *ev, ParolePluginPlayer *player)
+{
+    ev->button = 2;
+    
+    player->priv->user_seeking = FALSE;
+    
+    return FALSE;
+}
+
+static gboolean
+parole_plugin_player_range_button_press (GtkWidget *widget, GdkEventButton *ev, ParolePluginPlayer *player)
+{
+    ev->button = 2;
+    
+    player->priv->user_seeking = TRUE;
+    
+    return FALSE;
+}
+
+static void
+parole_plugin_player_change_range_value (ParolePluginPlayer *player, gdouble value)
+{
+    if ( !player->priv->user_seeking )
+    {
+	player->priv->internal_range_change = TRUE;
+    
+	gtk_range_set_value (GTK_RANGE (player->priv->range), value);
+
+	player->priv->internal_range_change = FALSE;
+    }
+}
+
+static void
+parole_plugin_player_construct (GObject *object)
+{
+    ParolePluginPlayer *player;
+    GtkBuilder *builder;
+    GError *error = NULL;
+    GtkWidget *box;
+    
+    builder = gtk_builder_new ();
+    gtk_builder_add_from_string (builder, 
+				 browser_plugin_control_ui, 
+				 browser_plugin_control_ui_length,
+				 &error);
+				 
+    if ( error )
+    {
+	g_error ("%s", error->message);
+    }
+    
+    player = PAROLE_PLUGIN_PLAYER (object);
+    
+    player->priv->controls = GTK_WIDGET (gtk_builder_get_object (builder, "controls"));
+    
+    player->priv->range = GTK_WIDGET (gtk_builder_get_object (builder, "scale"));
+    
+    player->priv->play = GTK_WIDGET (gtk_builder_get_object (builder, "play"));
+    
+    g_signal_connect_swapped (player->priv->play, "clicked",
+			      G_CALLBACK (parole_plugin_player_play_clicked_cb), player);
+
+    g_signal_connect (player->priv->range, "button-press-event",
+		      G_CALLBACK (parole_plugin_player_range_button_press), player);
+
+    g_signal_connect (player->priv->range, "button-release-event",
+		      G_CALLBACK (parole_plugin_player_range_button_release), player);
+		      
+    g_signal_connect (player->priv->range, "value-changed",
+		      G_CALLBACK (parole_plugin_player_range_value_changed), player);
+    
+    box = gtk_vbox_new (FALSE, 0);
+    
+    player->priv->gst = PAROLE_GST (parole_gst_new (TRUE, NULL));
+    
+    g_signal_connect (G_OBJECT (player->priv->gst), "media-state",
+		      G_CALLBACK (parole_plugin_player_media_state_cb), player);
+    
+    gtk_box_pack_start (GTK_BOX (box), GTK_WIDGET (player->priv->gst), TRUE, TRUE, 0);
+    gtk_box_pack_start (GTK_BOX (box), player->priv->controls, 
+			FALSE, FALSE, 0);
+    
+    gtk_container_add (GTK_CONTAINER (player->priv->plug), box);
+    
+    player->priv->sig = g_signal_connect (player->priv->plug, "delete-event",
+					  G_CALLBACK (parole_plugin_player_terminate), player);
+					     
+    parole_plugin_player_change_range_value (player, 0);
+    gtk_widget_set_sensitive (player->priv->range, FALSE);
+    
+    parole_gst_play_uri (player->priv->gst, player->priv->url, NULL);
+}
+
+static void
+parole_plugin_player_class_init (ParolePluginPlayerClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->finalize = parole_plugin_player_finalize;
+
+    object_class->get_property = parole_plugin_player_get_property;
+    object_class->set_property = parole_plugin_player_set_property;
+
+    object_class->constructed = parole_plugin_player_construct;
+    
+    
+    g_object_class_install_property (object_class,
+                                     PROP_PLUG,
+                                     g_param_spec_object ("plug",
+                                                          NULL, NULL,
+                                                          GTK_TYPE_PLUG,
+                                                          G_PARAM_CONSTRUCT_ONLY | 
+							  G_PARAM_READWRITE));
+
+    g_object_class_install_property (object_class,
+                                     PROP_URL,
+                                     g_param_spec_string ("url",
+                                                          NULL, NULL,
+                                                          NULL,
+                                                          G_PARAM_CONSTRUCT_ONLY | 
+							  G_PARAM_READWRITE));
+
+    g_type_class_add_private (klass, sizeof (ParolePluginPlayerPrivate));
+    
+    parole_plugin_player_dbus_class_init (klass);
+}
+
+static void
+parole_plugin_player_init (ParolePluginPlayer *player)
+{
+    player->priv = PAROLE_PLUGIN_PLAYER_GET_PRIVATE (player);
+    
+    player->priv->gst  = NULL;
+    player->priv->plug = NULL;
+    
+    player->priv->terminate = FALSE;
+    player->priv->user_seeking = FALSE;
+    player->priv->internal_range_change = FALSE;
+    
+    parole_plugin_player_dbus_init (player);
+}
+
+static void parole_plugin_player_set_property (GObject *object,
+					       guint prop_id,
+					       const GValue *value,
+					       GParamSpec *pspec)
+{
+    ParolePluginPlayer *player;
+    player = PAROLE_PLUGIN_PLAYER (object);
+
+    switch (prop_id)
+    {
+	case PROP_PLUG:
+	    player->priv->plug = GTK_WIDGET (g_value_get_object (value));
+	    break;
+	case PROP_URL:
+	    player->priv->url = g_value_dup_string (value);
+	    break;
+        default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+static void parole_plugin_player_get_property (GObject *object,
+					       guint prop_id,
+					       GValue *value,
+					       GParamSpec *pspec)
+{
+    ParolePluginPlayer *player;
+    player = PAROLE_PLUGIN_PLAYER (object);
+
+    switch (prop_id)
+    {
+         default:
+            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+            break;
+    }
+}
+
+static void
+parole_plugin_player_finalize (GObject *object)
+{
+    ParolePluginPlayer *player;
+
+    player = PAROLE_PLUGIN_PLAYER (object);
+
+    G_OBJECT_CLASS (parole_plugin_player_parent_class)->finalize (object);
+}
+
+ParolePluginPlayer *
+parole_plugin_player_new (GtkWidget *plug, gchar *url)
+{
+    ParolePluginPlayer *player = NULL;
+    
+    player = g_object_new (PAROLE_TYPE_PLUGINPLAYER, 
+			   "plug", plug, 
+			   "url", url, 
+			   NULL);
+
+    return player;
+}
+
+static gboolean parole_plugin_player_dbus_quit (ParolePluginPlayer *player,
+						GError **error);
+
+
+static gboolean parole_plugin_player_dbus_terminate (ParolePluginPlayer *player,
+						     GError **error);
+
+#include "org.parole.media.plugin.h"
+
+/*
+ * DBus server implementation
+ */
+static void 
+parole_plugin_player_dbus_class_init (ParolePluginPlayerClass *klass)
+{
+    
+    dbus_g_object_type_install_info (G_TYPE_FROM_CLASS (klass),
+                                     &dbus_glib_parole_gst_object_info);
+                                     
+}
+
+static void
+parole_plugin_player_dbus_init (ParolePluginPlayer *player)
+{
+    dbus_g_connection_register_g_object (parole_g_session_bus_get (),
+                                         "/org/Parole/Media/Plugin",
+                                         G_OBJECT (player));
+}
+
+static gboolean
+parole_plugin_player_dbus_quit (ParolePluginPlayer *player,
+				GError **error)
+{
+    g_debug ("Quit message received");
+    
+    player->priv->terminate = TRUE;
+    parole_gst_terminate (player->priv->gst);
+    gtk_main_quit ();
+    
+    return TRUE;
+}
+
+static gboolean 
+parole_plugin_player_dbus_terminate (ParolePluginPlayer *player, GError **error)
+{
+    g_debug ("Terminate message received");
+    player->priv->terminate = TRUE;
+    parole_gst_terminate (player->priv->gst);
+    return TRUE;
+}
diff --git a/browser-plugin/media-plugin/parole-gst.h b/browser-plugin/media-plugin/parole-plugin-player.h
similarity index 53%
rename from browser-plugin/media-plugin/parole-gst.h
rename to browser-plugin/media-plugin/parole-plugin-player.h
index c37ea2b..aa5e050 100644
--- a/browser-plugin/media-plugin/parole-gst.h
+++ b/browser-plugin/media-plugin/parole-plugin-player.h
@@ -18,44 +18,38 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef __PAROLE_GST_H
-#define __PAROLE_GST_H
+#ifndef __PAROLE_PLUGIN_PLAYER_H
+#define __PAROLE_PLUGIN_PLAYER_H
 
 #include <gtk/gtk.h>
 
 G_BEGIN_DECLS
 
-#define PAROLE_TYPE_GST        (parole_gst_get_type () )
-#define PAROLE_GST(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_GST, ParoleGst))
-#define PAROLE_IS_GST(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_GST))
+#define PAROLE_TYPE_PLUGINPLAYER        (parole_plugin_player_get_type () )
+#define PAROLE_PLUGIN_PLAYER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PLUGINPLAYER, ParolePluginPlayer))
+#define PAROLE_IS_PLUGINPLAYER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PLUGINPLAYER))
 
-typedef struct ParoleGstPrivate ParoleGstPrivate;
+typedef struct ParolePluginPlayerPrivate ParolePluginPlayerPrivate;
 
 typedef struct
 {
-    GtkWidget         		parent;
+    GObject         			 parent;
     
-    ParoleGstPrivate           *priv;
+    ParolePluginPlayerPrivate     	*priv;
     
-} ParoleGst;
+} ParolePluginPlayer;
 
 typedef struct
 {
-    GtkWidgetClass 		parent_class;
+    GObjectClass 			 parent_class;
     
-} ParoleGstClass;
+} ParolePluginPlayerClass;
 
-GType        			parole_gst_get_type        (void) G_GNUC_CONST;
+GType        				 parole_plugin_player_get_type        (void) G_GNUC_CONST;
 
-GtkWidget       	       *parole_gst_new             (void);
-
-void				parole_gst_play_url	   (ParoleGst *gst,
-							    const gchar *url);
-							    
-void				parole_gst_terminate	   (ParoleGst *gst);
-
-GtkWidget		       *parole_gst_get_controls    (ParoleGst *gst);
+ParolePluginPlayer       		*parole_plugin_player_new             (GtkWidget *plug,
+									       gchar *url);
 
 G_END_DECLS
 
-#endif /* __PAROLE_GST_H */
+#endif /* __PAROLE_PLUGIN_PLAYER_H */
diff --git a/common/Makefile.am b/common/Makefile.am
index d04e3b1..636d6f6 100644
--- a/common/Makefile.am
+++ b/common/Makefile.am
@@ -1,9 +1,9 @@
 noinst_LTLIBRARIES = 			\
-	libparoledbus.la
+	libparolecommon.la
 
-libparoledbus_la_SOURCES =		\
-	parole-dbus.c			\
-	parole-dbus.h
+libparolecommon_la_SOURCES =		\
+	parole-common.c			\
+	parole-common.h
 	
-libparoledbus_la_CFLAGS =		\
-	$(DBUS_GLIB_CFLAGS)
+libparolecommon_la_CFLAGS =		\
+	$(GTK_CFLAGS)
\ No newline at end of file
diff --git a/common/parole-common.c b/common/parole-common.c
new file mode 100644
index 0000000..695e919
--- /dev/null
+++ b/common/parole-common.c
@@ -0,0 +1,75 @@
+/*
+ * * Copyright (C) 2009 Ali <aliov at xfce.org>
+ *
+ * Licensed under the GNU General Public License Version 2
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
+ */
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <glib.h>
+
+#include "parole-common.h"
+
+void parole_window_busy_cursor		(GdkWindow *window)
+{
+    GdkCursor *cursor;
+    
+    if ( G_UNLIKELY (window == NULL) )
+	return;
+	
+    cursor = gdk_cursor_new (GDK_WATCH);
+    gdk_window_set_cursor (window, cursor);
+    gdk_cursor_unref (cursor);
+
+    gdk_flush ();
+}
+
+void parole_window_invisible_cursor		(GdkWindow *window)
+{
+    GdkBitmap *empty_bitmap;
+    GdkCursor *cursor;
+    GdkColor  color;
+
+    char cursor_bits[] = { 0x0 }; 
+    
+    if ( G_UNLIKELY (window == NULL) )
+	return;
+	
+    color.red = color.green = color.blue = 0;
+    color.pixel = 0;
+
+    empty_bitmap = gdk_bitmap_create_from_data (window,
+		   cursor_bits,
+		   1, 1);
+
+    cursor = gdk_cursor_new_from_pixmap (empty_bitmap,
+					 empty_bitmap,
+					 &color,
+					 &color, 0, 0);
+
+    gdk_window_set_cursor (window, cursor);
+
+    gdk_cursor_unref (cursor);
+
+    g_object_unref (empty_bitmap);
+}
diff --git a/parole/parole-about.h b/common/parole-common.h
similarity index 79%
copy from parole/parole-about.h
copy to common/parole-common.h
index cb89c42..1cae844 100644
--- a/parole/parole-about.h
+++ b/common/parole-common.h
@@ -18,12 +18,14 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef __PAROLE_ABOUT_H
-#define __PAROLE_ABOUT_H
+#ifndef __PAROLE_COMMON_H_
+#define __PAROLE_COMMON_H_
 
 #include <gtk/gtk.h>
+#include <gdk/gdk.h>
 
-void 		parole_about	(void);
+void		parole_window_busy_cursor		(GdkWindow *window);
 
+void		parole_window_invisible_cursor		(GdkWindow *window);
 
-#endif /* __PAROLE_ABOUT_H */
+#endif /* __PAROLE_COMMON_ */
diff --git a/configure.ac.in b/configure.ac.in
index 10727b0..446d7ea 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -239,6 +239,8 @@ data/icons/scalable/status/Makefile
 data/mime/Makefile
 data/desktop/Makefile
 common/Makefile
+gst/Makefile
+dbus/Makefile
 parole/Makefile
 plugins/Makefile
 plugins/properties/Makefile
diff --git a/common/Makefile.am b/dbus/Makefile.am
similarity index 100%
copy from common/Makefile.am
copy to dbus/Makefile.am
diff --git a/common/parole-dbus.c b/dbus/parole-dbus.c
similarity index 100%
rename from common/parole-dbus.c
rename to dbus/parole-dbus.c
diff --git a/common/parole-dbus.h b/dbus/parole-dbus.h
similarity index 100%
rename from common/parole-dbus.h
rename to dbus/parole-dbus.h
diff --git a/gst/Makefile.am b/gst/Makefile.am
new file mode 100644
index 0000000..2f5d4fc
--- /dev/null
+++ b/gst/Makefile.am
@@ -0,0 +1,84 @@
+noinst_LTLIBRARIES = 			\
+	libparolegst.la
+
+INCLUDES =                              \
+        -I$(top_srcdir)                 \
+        -I$(top_srcdir)/common          \
+        -DLOCALEDIR=\"$(localedir)\"    \
+        -DG_LOG_DOMAIN=\"parole-gst\"
+
+GENERATED_FILES =			\
+	gstmarshal.c			\
+	gstmarshal.h			\
+	gst-enum-types.c		\
+	gst-enum-types.h
+
+libparolegst_la_SOURCES =		\
+	$(GENERATED_FILES)		\
+	parole-gst.c			\
+	parole-gst.h			\
+	parole-stream.c			\
+	parole-stream.h
+	
+libparolegst_la_CFLAGS =		\
+	$(GST_VIDEO_CFLAGS)             \
+        $(GST_INTERFACES_CFLAGS)	\
+	$(GTHREAD_CFLAGS)               \
+	$(LIBXFCE4GUI_CFLAGS)
+
+libparolegst_la_LIBADD =		\
+	$(top_builddir)/common/libparolecommon.la
+
+libparolegst_header = 			\
+	parole-stream.h
+
+parole_glib_enum_headers =		\
+	parole-gst.h			\
+	parole-stream.h
+
+if MAINTAINER_MODE
+
+BUILT_SOURCES = 			\
+	$(GENERATED_FILES)
+
+gstmarshal.c: gstmarshal.list
+	echo "#include \"gstmarshal.h\"" > $@ && \
+	glib-genmarshal $< --prefix=_gmarshal --body >> $@
+
+gstmarshal.h: gstmarshal.list
+	glib-genmarshal $< --prefix=_gmarshal --header > $@
+
+gst-enum-types.h: stamp-enum-types.h
+	@true
+stamp-enum-types.h: $(parole_glib_enum_headers) Makefile
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#ifndef __GST_ENUM_TYPE_H__\n#define __GST_ENUM_TYPE_H__\n#include <glib-object.h>\nG_BEGIN_DECLS\n" \
+		--fprod "/* enumerations from \"@filename@\" */\n" \
+		--vhead "GType @enum_name at _get_type (void);\n#define GST_ENUM_TYPE_ at ENUMSHORT@ (@enum_name at _get_type())\n" \
+		--ftail "G_END_DECLS\n\n#endif /* __GST_ENUM_TYPE_H__ */" \
+		$(parole_glib_enum_headers) ) > xgen-enum.h \
+	&& (cmp -s xgen-enum.h gst-enum-types.h || cp xgen-enum.h gst-enum-types.h) \
+	&& rm -f xgen-enum.h \
+	&& echo timestamp > $(@F)
+
+gst-enum-types.c: $(parole_glib_enum_headers) Makefile
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#include \"gst-enum-types.h\"\n\n" \
+		--fhead "#include \"parole-gst.h\"\n\n" \
+		--fhead "#include \"parole-stream.h\"\n\n" \
+		--fprod "\n/* enumerations from \"@filename@\" */" \
+		--vhead "GType\n at enum_name@_get_type (void)\n{\n  static GType etype = 0;\n  if (etype == 0) {\n    static const G at Type@Value values[] = {" \
+		--vprod "      { @VALUENAME@, \"@VALUENAME@\", \"@valuenick@\" }," \
+		--vtail "      { 0, NULL, NULL }\n    };\n    etype = g_ at type@_register_static (\"@EnumName@\", values);\n  }\n  return etype;\n}\n" \
+		$(parole_glib_enum_headers) ) >> xgen-enum.c \
+	&& cp xgen-enum.c gst-enum-types.c \
+	&& rm -f xgen-enum.c
+
+endif
+
+EXTRA_DIST =					\
+	gmarshal.list
+
+DISTCLEANFILES =				\
+	$(BUILT_SOURCES)			\
+	stamp-enum-types.h
diff --git a/gst/gstmarshal.list b/gst/gstmarshal.list
new file mode 100644
index 0000000..61cba6f
--- /dev/null
+++ b/gst/gstmarshal.list
@@ -0,0 +1,4 @@
+VOID:OBJECT,ENUM
+VOID:OBJECT,DOUBLE
+VOID:OBJECT,INT
+
diff --git a/parole/parole-gst.c b/gst/parole-gst.c
similarity index 92%
rename from parole/parole-gst.c
rename to gst/parole-gst.c
index bc418c4..eb40029 100644
--- a/parole/parole-gst.c
+++ b/gst/parole-gst.c
@@ -39,11 +39,11 @@
 #include <gdk/gdkx.h>
 
 #include "parole-gst.h"
-#include "parole-utils.h"
-#include "parole-conf.h"
-#include "parole-debug.h"
-#include "enum-gtypes.h"
-#include "gmarshal.h"
+
+#include "common/parole-common.h"
+
+#include "gst-enum-types.h"
+#include "gstmarshal.h"
 
 #define HIDE_WINDOW_CURSOR_TIMEOUT 3.0f
 
@@ -79,7 +79,12 @@ struct ParoleGstPrivate
     gchar        *device;
     GTimer	 *hidecursor_timer;
     
-    ParoleConf   *conf;
+    gpointer      conf; /* Specific for ParoleMediaPlayer*/
+    
+    
+    gboolean	  embedded;
+    gboolean      enable_tags;
+    
     gboolean	  update_vis;
     gboolean      with_vis;
     gboolean      buffering;
@@ -107,6 +112,16 @@ enum
     LAST_SIGNAL
 };
 
+enum
+{
+    PROP_0,
+    PROP_EMBEDDED,
+    PROP_CONF_OBJ,
+    PROP_ENABLE_TAGS
+};
+
+static gpointer parole_gst_object = NULL;
+
 static guint signals [LAST_SIGNAL] = { 0 };
 
 G_DEFINE_TYPE (ParoleGst, parole_gst, GTK_TYPE_WIDGET)
@@ -126,7 +141,6 @@ parole_gst_finalize (GObject *object)
     parole_stream_init_properties (gst->priv->stream);
     
     g_object_unref (gst->priv->stream);
-    g_object_unref (gst->priv->conf);
     g_object_unref (gst->priv->logo);
     
     if ( gst->priv->device )
@@ -232,7 +246,8 @@ parole_gst_show (GtkWidget *widget)
     
     gst = PAROLE_GST (widget);
     
-    gdk_window_show (widget->window);
+    if ( widget->window )
+	gdk_window_show (widget->window);
     
     if ( GTK_WIDGET_CLASS (parole_gst_parent_class)->show )
 	GTK_WIDGET_CLASS (parole_gst_parent_class)->show (widget);
@@ -327,7 +342,7 @@ parole_gst_size_allocate (GtkWidget *widget, GtkAllocation *allocation)
     
     widget->allocation = *allocation;
 
-    if ( GTK_WIDGET_REALIZED (widget) )
+    if ( GTK_WIDGET_REALIZED (widget) && !PAROLE_GST (widget)->priv->embedded )
     {
 	gint w, h;
 	gdouble ratio, width, height;
@@ -415,7 +430,7 @@ parole_gst_set_video_color_balance (ParoleGst *gst)
     gint hue_value;
     gint saturation_value;
 	
-    if ( !gst->priv->xvimage_sink )
+    if ( !gst->priv->xvimage_sink || gst->priv->conf == NULL)
 	return;
 	
     g_object_get (G_OBJECT (gst->priv->playbin),
@@ -613,6 +628,9 @@ parole_gst_set_subtitle_font (ParoleGst *gst)
 {
     gchar *font;
     
+    if ( !gst->priv->conf )
+	return;
+    
     g_object_get (G_OBJECT (gst->priv->conf),
 		  "subtitle-font", &font,
 		  NULL);
@@ -630,6 +648,9 @@ parole_gst_set_subtitle_encoding (ParoleGst *gst)
 {
     gchar *encoding;
     
+    if ( !gst->priv->conf )
+	return;
+    
     g_object_get (G_OBJECT (gst->priv->conf),
 		  "subtitle-encoding", &encoding,
 		  NULL);
@@ -650,6 +671,9 @@ parole_gst_load_subtitle (ParoleGst *gst)
     gchar *sub_uri;
     gboolean sub_enabled;
     
+    if ( !gst->priv->conf )
+	return;
+    
     g_object_get (G_OBJECT (gst->priv->stream),
 		  "media-type", &type,
 		  NULL);
@@ -666,11 +690,9 @@ parole_gst_load_subtitle (ParoleGst *gst)
 	
     g_object_get (G_OBJECT (gst->priv->stream),
 		  "uri", &uri,
+		  "subtitles", &sub,
 		  NULL);
 	
-    
-    sub = parole_get_subtitle_path (uri);
-
     if ( sub )
     {
 	TRACE ("Found subtitle with path %s", sub);
@@ -809,6 +831,10 @@ parole_gst_update_vis (ParoleGst *gst)
     gchar *vis_name;
     
     TRACE ("start");
+    
+    if ( !gst->priv->conf )
+	return;
+    
     g_object_get (G_OBJECT (gst->priv->conf),
 		  "vis-enabled", &gst->priv->with_vis,
 		  "vis-name", &vis_name,
@@ -1128,12 +1154,14 @@ parole_gst_bus_event (GstBus *bus, GstMessage *msg, gpointer data)
 	
 	case GST_MESSAGE_TAG:
 	{
-	    GstTagList *tag_list;
-	    
-	    TRACE ("Tag message:");
-	    gst_message_parse_tag (msg, &tag_list);
-	    parole_gst_get_meta_data (gst, tag_list);
-	    gst_tag_list_free (tag_list);
+	    if ( gst->priv->enable_tags )
+	    {
+		GstTagList *tag_list;
+		TRACE ("Tag message:");
+		gst_message_parse_tag (msg, &tag_list);
+		parole_gst_get_meta_data (gst, tag_list);
+		gst_tag_list_free (tag_list);
+	    }
 	    break;
 	}
 	case GST_MESSAGE_APPLICATION:
@@ -1579,6 +1607,67 @@ parole_gst_conf_notify_cb (GObject *object, GParamSpec *spec, ParoleGst *gst)
     }
 }
 
+static void parole_gst_get_property (GObject *object,
+				     guint prop_id,
+				     GValue *value,
+				     GParamSpec *pspec)
+{
+    ParoleGst *gst;
+    gst = PAROLE_GST (object);
+    
+    switch (prop_id)
+    {
+	case PROP_EMBEDDED:
+	    g_value_set_boolean (value, gst->priv->embedded);
+	    break;
+	case PROP_CONF_OBJ:
+	    g_value_set_pointer (value, gst->priv->conf);
+	    break;
+	case PROP_ENABLE_TAGS:
+	    g_value_set_boolean (value, gst->priv->enable_tags);
+	    break;
+	default:
+           G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+           break;
+    }
+}
+
+
+static void parole_gst_set_property (GObject *object,
+				     guint prop_id,
+				     const GValue *value,
+				     GParamSpec *pspec)
+{
+    ParoleGst *gst;
+    gst = PAROLE_GST (object);
+    
+    switch (prop_id)
+    {
+	case PROP_EMBEDDED:
+	    gst->priv->embedded = g_value_get_boolean (value);
+	    break;
+	case PROP_ENABLE_TAGS:
+	    gst->priv->enable_tags = g_value_get_boolean (value);
+	    break;
+	case PROP_CONF_OBJ:
+	    gst->priv->conf = g_value_get_pointer (value);
+	    
+	    if (gst->priv->conf)
+	    {
+		g_object_get (G_OBJECT (gst->priv->conf),
+			      "aspect-ratio", &gst->priv->aspect_ratio,
+			      NULL);
+    
+		g_signal_connect (G_OBJECT (gst->priv->conf), "notify",
+				  G_CALLBACK (parole_gst_conf_notify_cb), gst);
+	    }
+	    break;
+	default:
+           G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
+           break;
+    }
+}
+
 static void
 parole_gst_class_init (ParoleGstClass *klass)
 {
@@ -1587,6 +1676,8 @@ parole_gst_class_init (ParoleGstClass *klass)
 
     object_class->finalize = parole_gst_finalize;
     object_class->constructed = parole_gst_construct;
+    object_class->set_property = parole_gst_set_property;
+    object_class->get_property = parole_gst_get_property;
 
     widget_class->realize = parole_gst_realize;
     widget_class->show = parole_gst_show;
@@ -1604,7 +1695,7 @@ parole_gst_class_init (ParoleGstClass *klass)
                       NULL, NULL,
                       _gmarshal_VOID__OBJECT_ENUM,
                       G_TYPE_NONE, 2, 
-		      PAROLE_TYPE_STREAM, ENUM_GTYPE_MEDIA_STATE);
+		      PAROLE_TYPE_STREAM, GST_ENUM_TYPE_MEDIA_STATE);
 
     signals[MEDIA_PROGRESSED] = 
         g_signal_new ("media-progressed",
@@ -1645,6 +1736,28 @@ parole_gst_class_init (ParoleGstClass *klass)
                       g_cclosure_marshal_VOID__STRING,
                       G_TYPE_NONE, 1, 
 		      G_TYPE_STRING);
+
+    g_object_class_install_property (object_class,
+				     PROP_EMBEDDED,
+				     g_param_spec_boolean ("embedded",
+							   NULL, NULL,
+							   FALSE,
+							   G_PARAM_CONSTRUCT_ONLY|
+							   G_PARAM_READWRITE));
+    
+    g_object_class_install_property (object_class,
+				     PROP_CONF_OBJ,
+				     g_param_spec_pointer ("conf-object",
+							   NULL, NULL,
+							   G_PARAM_CONSTRUCT_ONLY|
+							   G_PARAM_READWRITE));
+    
+    g_object_class_install_property (object_class,
+				     PROP_ENABLE_TAGS,
+				     g_param_spec_boolean ("tags",
+							   NULL, NULL,
+							   TRUE,
+							   G_PARAM_READWRITE));
     
     g_type_class_add_private (klass, sizeof (ParoleGstPrivate));
 }
@@ -1657,6 +1770,7 @@ parole_gst_init (ParoleGst *gst)
     gst->priv->state = GST_STATE_VOID_PENDING;
     gst->priv->target = GST_STATE_VOID_PENDING;
     gst->priv->media_state = PAROLE_MEDIA_STATE_STOPPED;
+    gst->priv->aspect_ratio = PAROLE_ASPECT_RATIO_NONE;
     gst->priv->lock = g_mutex_new ();
     gst->priv->stream = parole_stream_new ();
     gst->priv->tick_id = 0;
@@ -1667,15 +1781,9 @@ parole_gst_init (ParoleGst *gst)
     gst->priv->update_color_balance = TRUE;
     gst->priv->state_change_id = 0;
     gst->priv->device = NULL;
+    gst->priv->enable_tags = TRUE;
     
-    gst->priv->conf = parole_conf_new ();
-    
-    g_object_get (G_OBJECT (gst->priv->conf),
-		  "aspect-ratio", &gst->priv->aspect_ratio,
-		  NULL);
-    
-    g_signal_connect (G_OBJECT (gst->priv->conf), "notify",
-		      G_CALLBACK (parole_gst_conf_notify_cb), gst);
+    gst->priv->conf = NULL;
     
     GTK_WIDGET_SET_FLAGS (GTK_WIDGET (gst), GTK_CAN_FOCUS);
     
@@ -1687,10 +1795,20 @@ parole_gst_init (ParoleGst *gst)
 }
 
 GtkWidget *
-parole_gst_new (void)
+parole_gst_new (gboolean embedded, gpointer conf_obj)
 {
-    static gpointer parole_gst_object = NULL;
+    parole_gst_object = g_object_new (PAROLE_TYPE_GST, 
+				      "embedded", embedded,
+				      "conf-object", conf_obj,
+				      NULL);
+				      
+    g_object_add_weak_pointer (parole_gst_object, &parole_gst_object);
     
+    return GTK_WIDGET (parole_gst_object);
+}
+
+GtkWidget *parole_gst_get (void)
+{
     if ( G_LIKELY (parole_gst_object != NULL ) )
     {
 	/* 
@@ -1702,11 +1820,13 @@ parole_gst_new (void)
     }
     else
     {
-	parole_gst_object = g_object_new (PAROLE_TYPE_GST, NULL);
+	parole_gst_object = g_object_new (PAROLE_TYPE_GST, 
+					  NULL);
 	g_object_add_weak_pointer (parole_gst_object, &parole_gst_object);
     }
     
     return GTK_WIDGET (parole_gst_object);
+    
 }
 
 static gboolean
@@ -1724,14 +1844,16 @@ parole_gst_play_idle (gpointer data)
     return FALSE;
 }
 
-void parole_gst_play_uri (ParoleGst *gst, const gchar *uri)
+void parole_gst_play_uri (ParoleGst *gst, const gchar *uri, const gchar *subtitles)
 {
     g_mutex_lock (gst->priv->lock);
     
     gst->priv->target = GST_STATE_PLAYING;
     parole_stream_init_properties (gst->priv->stream);
+    
     g_object_set (G_OBJECT (gst->priv->stream),
 	          "uri", uri,
+		  "subtitles", subtitles,
 		  NULL);
 
     g_mutex_unlock (gst->priv->lock);
@@ -1758,7 +1880,7 @@ void parole_gst_play_device_uri (ParoleGst *gst, const gchar *uri, const gchar *
     
     gst->priv->device = g_strdup (device);
     
-    parole_gst_play_uri (gst, uri);
+    parole_gst_play_uri (gst, uri, NULL);
 }
 
 void parole_gst_pause (ParoleGst *gst)
diff --git a/parole/parole-gst.h b/gst/parole-gst.h
similarity index 87%
rename from parole/parole-gst.h
rename to gst/parole-gst.h
index 08265d6..d6e337a 100644
--- a/parole/parole-gst.h
+++ b/gst/parole-gst.h
@@ -34,8 +34,8 @@ G_BEGIN_DECLS
 #define PAROLE_IS_GST(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_GST))
 
 /*
- * Keep this order to be compatible with the ParoleState enum
- * used by the plugin interface.
+ * Keep this order to be compatible with the 
+ * ParoleState enum used by the plugin interface.
  */
 typedef enum /*< prefix=PAROLE_MEDIA_STATE_ >*/
 {
@@ -46,6 +46,17 @@ typedef enum /*< prefix=PAROLE_MEDIA_STATE_ >*/
     
 } ParoleMediaState;
 
+typedef enum
+{
+    PAROLE_ASPECT_RATIO_NONE,
+    PAROLE_ASPECT_RATIO_AUTO,
+    PAROLE_ASPECT_RATIO_SQUARE,
+    PAROLE_ASPECT_RATIO_4_3,
+    PAROLE_ASPECT_RATIO_16_9,
+    PAROLE_ASPECT_RATIO_DVB
+	
+} ParoleAspectRatio;
+
 typedef struct ParoleGstPrivate ParoleGstPrivate;
 
 typedef struct
@@ -81,10 +92,14 @@ typedef struct
 
 GType        		parole_gst_get_type        	(void) G_GNUC_CONST;
 
-GtkWidget      	       *parole_gst_new             	(void);
+GtkWidget      	       *parole_gst_new             	(gboolean embedded,
+							 gpointer conf_obj);
+
+GtkWidget	       *parole_gst_get 			(void);
 
 void		        parole_gst_play_uri        	(ParoleGst *gst,
-							 const gchar *uri);
+							 const gchar *uri,
+							 const gchar *subtitles);
 
 void		        parole_gst_play_device_uri     	(ParoleGst *gst,
 							 const gchar *uri,
diff --git a/parole/parole-stream.c b/gst/parole-stream.c
similarity index 95%
rename from parole/parole-stream.c
rename to gst/parole-stream.c
index a98b645..f4d3047 100644
--- a/parole/parole-stream.c
+++ b/gst/parole-stream.c
@@ -29,8 +29,7 @@
 #include <glib.h>
 
 #include "parole-stream.h"
-#include "parole-file.h"
-#include "enum-gtypes.h"
+#include "gst-enum-types.h"
 
 #define PAROLE_STREAM_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_STREAM, ParoleStreamPrivate))
@@ -50,6 +49,7 @@ struct _ParoleStreamPrivate
 {
     /*Properties*/
     gchar      *uri;
+    gchar      *subtitles;
     gboolean 	has_audio;
     gboolean    has_video;
     gboolean 	live;
@@ -76,6 +76,7 @@ enum
 {
     PROP_0,
     PROP_URI,
+    PROP_SUBTITLES,
     PROP_LIVE,
     PROP_MEDIA_TYPE,
     PROP_HAS_AUDIO,
@@ -121,7 +122,7 @@ parole_stream_get_media_type_from_uri (ParoleStream *stream, const gchar *uri)
     else 
 	type = PAROLE_MEDIA_TYPE_UNKNOWN;
     
-    g_value_init (&val, ENUM_GTYPE_MEDIA_TYPE);
+    g_value_init (&val, GST_ENUM_TYPE_MEDIA_TYPE);
     g_value_set_enum (&val, type);
     g_object_set_property (G_OBJECT (stream), "media-type", &val);
     g_value_unset (&val);
@@ -145,6 +146,9 @@ static void parole_stream_set_property (GObject *object,
 	    parole_stream_get_media_type_from_uri (stream, priv->uri);
 	    break;
 	}
+	case PROP_SUBTITLES:
+	    PAROLE_STREAM_DUP_GVALUE_STRING (PAROLE_STREAM_GET_PRIVATE (stream)->subtitles, value);
+	    break;
 	case PROP_LIVE:
 	    PAROLE_STREAM_GET_PRIVATE (stream)->live = g_value_get_boolean (value);
 	    break;
@@ -221,6 +225,9 @@ static void parole_stream_get_property (GObject *object,
 	case PROP_URI:
 	    g_value_set_string (value, PAROLE_STREAM_GET_PRIVATE (stream)->uri);
 	    break;
+	case PROP_SUBTITLES:
+	    g_value_set_string (value, PAROLE_STREAM_GET_PRIVATE (stream)->subtitles);
+	    break;
 	case PROP_LIVE:
 	    g_value_set_boolean (value, PAROLE_STREAM_GET_PRIVATE (stream)->live);
 	    break;
@@ -321,6 +328,20 @@ parole_stream_class_init (ParoleStreamClass *klass)
 							  G_PARAM_READWRITE));
     
     /**
+     * ParoleStream:subtitles:
+     * 
+     * Subtitles path, this is only valid for local files
+     * 
+     * Since: 0.2 
+     **/
+    g_object_class_install_property (object_class,
+				     PROP_SUBTITLES,
+				     g_param_spec_string ("subtitles",
+							  NULL, NULL,
+							  NULL,
+							  G_PARAM_READWRITE));
+    
+    /**
      * ParoleStream:has-audio:
      * 
      * Whether the stream has audio.
@@ -372,7 +393,7 @@ parole_stream_class_init (ParoleStreamClass *klass)
 				     PROP_MEDIA_TYPE,
 				     g_param_spec_enum ("media-type",
 							NULL, NULL,
-							ENUM_GTYPE_MEDIA_TYPE,
+							GST_ENUM_TYPE_MEDIA_TYPE,
 							PAROLE_MEDIA_TYPE_UNKNOWN,
 							G_PARAM_READWRITE));
 
@@ -635,6 +656,7 @@ void parole_stream_init_properties (ParoleStream *stream)
     
     PAROLE_STREAM_FREE_STR_PROP (priv->title);
     PAROLE_STREAM_FREE_STR_PROP (priv->uri);
+    PAROLE_STREAM_FREE_STR_PROP (priv->subtitles);
     PAROLE_STREAM_FREE_STR_PROP (priv->artist);
     PAROLE_STREAM_FREE_STR_PROP (priv->year);
     PAROLE_STREAM_FREE_STR_PROP (priv->album);
diff --git a/parole/parole-stream.h b/gst/parole-stream.h
similarity index 100%
rename from parole/parole-stream.h
rename to gst/parole-stream.h
diff --git a/parole/Makefile.am b/parole/Makefile.am
index fd135cd..dbe78a0 100644
--- a/parole/Makefile.am
+++ b/parole/Makefile.am
@@ -7,7 +7,9 @@ INCLUDES =					\
 	-I$(top_srcdir)				\
 	-I$(top_srcdir)/data			\
 	-I$(top_srcdir)/data/mime		\
-	-I$(top_srcdir)/common                  \
+	-I$(top_srcdir)/gst	                \
+	-I$(top_srcdir)/dbus	                \
+	-I$(top_srcdir)/common	                \
 	-DLOCALEDIR=\"$(localedir)\"		\
 	-DG_LOG_DOMAIN=\"parole\"		\
 	-DPAROLE_PLUGINS_DIR=\"$(libdir)/parole-$(PAROLE_VERSION_API)\"\
@@ -25,7 +27,9 @@ PAROLE_LDFLAGS =				\
 	-export-symbols-regex "^[[^_]].*"
 
 PAROLE_LIBS = 					\
-	$(top_builddir)/common/libparoledbus.la \
+	$(top_builddir)/dbus/libparoledbus.la 	\
+	$(top_builddir)/gst/libparolegst.la 	\
+	$(top_builddir)/common/libparolecommon.la\
         $(GTHREAD_LIBS)                         \
 	$(GIO_LIBS)				\
         $(DBUS_GLIB_LIBS)                       \
@@ -45,12 +49,10 @@ GENERATED_FILES =				\
 INST_HFILES =					\
 	parole.h				\
 	parole-plugin.h				\
-	parole-file.h				\
-	parole-stream.h
+	parole-file.h
 
 NOINST_HFILES =					\
 	parole-player.h				\
-	parole-gst.h				\
 	parole-vis.h				\
 	parole-statusbar.h			\
 	parole-mediachooser.h			\
@@ -88,8 +90,6 @@ libparole_la_SOURCES =				\
 	$(INST_HFILES)				\
 	$(NOINST_HFILES)			\
 	parole-player.c				\
-	parole-gst.c				\
-	parole-stream.c				\
 	parole-file.c				\
 	parole-vis.c				\
 	parole-statusbar.c			\
@@ -131,15 +131,11 @@ parole_LDFLAGS =				\
 	$(PAROLE_LDFLAGS)
 
 parole_glib_enum_headers =			\
-	parole-gst.h				\
 	parole-plugin.h				\
 	parole-pl-parser.h			\
-	parole-stream.h				\
 	parole-conf.h				\
 	parole-button.h
 
-# Parole Browser Player plugin
-
 if MAINTAINER_MODE
 
 BUILT_SOURCES = 				\
diff --git a/parole/gmarshal.list b/parole/gmarshal.list
index 002d61d..8f1d1ea 100644
--- a/parole/gmarshal.list
+++ b/parole/gmarshal.list
@@ -1,5 +1,2 @@
-VOID:OBJECT,ENUM
-VOID:OBJECT,DOUBLE
-VOID:OBJECT,INT
 VOID:STRING,STRING
 VOID:BOOL,POINTER
diff --git a/parole/parole-conf-dialog.c b/parole/parole-conf-dialog.c
index 96f0066..e6db9b6 100644
--- a/parole/parole-conf-dialog.c
+++ b/parole/parole-conf-dialog.c
@@ -362,7 +362,7 @@ void parole_conf_dialog_open (ParoleConfDialog *self, GtkWidget *parent)
 
     parole_conf_dialog_set_defaults (self);
     
-    with_display = parole_gst_get_is_xvimage_sink (PAROLE_GST (parole_gst_new ()));
+    with_display = parole_gst_get_is_xvimage_sink (PAROLE_GST (parole_gst_get ()));
     
     if ( !with_display )
     {
diff --git a/parole/parole-conf.c b/parole/parole-conf.c
index b4a234e..21136c4 100644
--- a/parole/parole-conf.c
+++ b/parole/parole-conf.c
@@ -32,6 +32,9 @@
 #include "parole-rc-utils.h"
 #include "enum-gtypes.h"
 
+#include "gst/parole-gst.h"
+#include "gst/gst-enum-types.h"
+
 #define PAROLE_CONF_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_CONF, ParoleConfPrivate))
 
@@ -199,8 +202,8 @@ parole_conf_class_init (ParoleConfClass *klass)
     if (!g_value_type_transformable (G_TYPE_STRING, G_TYPE_BOOLEAN))
 	g_value_register_transform_func (G_TYPE_STRING, G_TYPE_BOOLEAN, transform_string_to_boolean);
     
-    if (!g_value_type_transformable (G_TYPE_STRING, ENUM_GTYPE_ASPECT_RATIO))
-	g_value_register_transform_func (G_TYPE_STRING, ENUM_GTYPE_ASPECT_RATIO, transform_string_to_enum);
+    if (!g_value_type_transformable (G_TYPE_STRING, GST_ENUM_TYPE_ASPECT_RATIO))
+	g_value_register_transform_func (G_TYPE_STRING, GST_ENUM_TYPE_ASPECT_RATIO, transform_string_to_enum);
 	
     g_object_class_install_property (object_class,
                                      PROP_VIS_ENABLED,
@@ -290,7 +293,7 @@ parole_conf_class_init (ParoleConfClass *klass)
                                      PROP_ASPECT_RATIO,
                                      g_param_spec_enum ("aspect-ratio",
                                                         NULL, NULL,
-							ENUM_GTYPE_ASPECT_RATIO,
+							GST_ENUM_TYPE_ASPECT_RATIO,
 							PAROLE_ASPECT_RATIO_NONE,
                                                         G_PARAM_READWRITE));
 						       
diff --git a/parole/parole-conf.h b/parole/parole-conf.h
index 722c0b5..79910a2 100644
--- a/parole/parole-conf.h
+++ b/parole/parole-conf.h
@@ -29,17 +29,7 @@ G_BEGIN_DECLS
 #define PAROLE_CONF(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_CONF, ParoleConf))
 #define PAROLE_IS_CONF(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_CONF))
 
-typedef enum
-{
-    PAROLE_ASPECT_RATIO_NONE,
-    PAROLE_ASPECT_RATIO_AUTO,
-    PAROLE_ASPECT_RATIO_SQUARE,
-    PAROLE_ASPECT_RATIO_4_3,
-    PAROLE_ASPECT_RATIO_16_9,
-    PAROLE_ASPECT_RATIO_DVB
-	
-} ParoleAspectRatio;
-    
+   
 typedef struct ParoleConfPrivate ParoleConfPrivate;
 
 typedef struct
diff --git a/parole/parole-disc-menu.c b/parole/parole-disc-menu.c
index 40c90a0..08edb8a 100644
--- a/parole/parole-disc-menu.c
+++ b/parole/parole-disc-menu.c
@@ -274,7 +274,7 @@ parole_disc_menu_init (ParoleDiscMenu *menu)
     g_signal_connect_swapped (menu->priv->chapter_menu, "clicked",
 			      G_CALLBACK (parole_disc_menu_chapter_menu_cb), menu);
 			      
-    menu->priv->gst = PAROLE_GST (parole_gst_new ());
+    menu->priv->gst = PAROLE_GST (parole_gst_get ());
     
     g_signal_connect (G_OBJECT (menu->priv->gst), "media_state",
 		      G_CALLBACK (parole_disc_menu_media_state_cb), menu);
diff --git a/parole/parole-mediachooser.c b/parole/parole-mediachooser.c
index c17c4e7..59ec020 100644
--- a/parole/parole-mediachooser.c
+++ b/parole/parole-mediachooser.c
@@ -41,6 +41,8 @@
 #include "parole-rc-utils.h"
 #include "parole-utils.h"
 
+#include "common/parole-common.h"
+
 #include "gmarshal.h"
 
 /*
diff --git a/parole/parole-medialist.c b/parole/parole-medialist.c
index 91dd34f..db9f8e2 100644
--- a/parole/parole-medialist.c
+++ b/parole/parole-medialist.c
@@ -50,6 +50,8 @@
 #include "parole-rc-utils.h"
 #include "parole-dbus.h"
 
+#include "common/parole-common.h"
+
 #define PAROLE_AUTO_SAVED_PLAYLIST 	"xfce4/parole/auto-saved-playlist.m3u"
 
 typedef struct
diff --git a/parole/parole-player.c b/parole/parole-player.c
index b2bb105..f3d7b5a 100644
--- a/parole/parole-player.c
+++ b/parole/parole-player.c
@@ -60,6 +60,10 @@
 #include "enum-gtypes.h"
 #include "parole-debug.h"
 
+#include "gst/gst-enum-types.h"
+
+#include "common/parole-common.h"
+
 /*
  * DBus Glib init
  */
@@ -365,9 +369,24 @@ parole_player_media_activated_cb (ParoleMediaList *list, GtkTreeRowReference *ro
 	
 	if ( file )
 	{
+	    /*
+	    gchar *sub = NULL;
+	    
+	    if ( g_str_has_prefix (uri, "file:/") )
+	    {
+		
+	    }
+	    TRACE ("File content type %s", parole_file_get_content_type (file));
+	    */
+	    
 	    TRACE ("Trying to play media file %s", parole_file_get_uri (file));
+	    
 	    gtk_widget_set_sensitive (player->priv->stop, TRUE);
-	    parole_gst_play_uri (PAROLE_GST (player->priv->gst), parole_file_get_uri (file));
+	    
+	    parole_gst_play_uri (PAROLE_GST (player->priv->gst), 
+				 parole_file_get_uri (file),
+				 NULL);//FIXME, load subtitles
+				 
 	    gtk_widget_grab_focus (player->priv->gst);
 	    g_object_unref (file);
 	}
@@ -390,7 +409,7 @@ parole_player_uri_opened_cb (ParoleMediaList *list, const gchar *uri, ParolePlay
     parole_player_reset (player);
     gtk_widget_set_sensitive (player->priv->stop, TRUE);
     gtk_widget_grab_focus (player->priv->gst);
-    parole_gst_play_uri (PAROLE_GST (player->priv->gst), uri);
+    parole_gst_play_uri (PAROLE_GST (player->priv->gst), uri, NULL);
 }
 
 static void
@@ -695,7 +714,7 @@ parole_player_media_state_cb (ParoleGst *gst, const ParoleStream *stream, Parole
 {
     gboolean has_video;
     
-    PAROLE_DEBUG_ENUM ("State callback", state, ENUM_GTYPE_MEDIA_STATE);
+    PAROLE_DEBUG_ENUM ("State callback", state, GST_ENUM_TYPE_MEDIA_STATE);
     
     g_object_get (G_OBJECT (stream),
 		  "has-video", &has_video,
@@ -1619,7 +1638,7 @@ parole_player_init (ParolePlayer *player)
     g_signal_connect_swapped (player->priv->session, "die",
 			      G_CALLBACK (parole_player_session_die_cb), player);
     
-    player->priv->gst = parole_gst_new ();
+    player->priv->gst = parole_gst_new (FALSE, player->priv->conf);
     
     player->priv->status = parole_statusbar_new ();
     player->priv->disc = parole_disc_new ();
diff --git a/parole/parole-plugin.c b/parole/parole-plugin.c
index bd2fc6a..8ca83c6 100644
--- a/parole/parole-plugin.c
+++ b/parole/parole-plugin.c
@@ -328,7 +328,7 @@ parole_plugin_init (ParolePlugin *plugin)
     priv->widget = NULL;
     priv->configurable = FALSE;
     
-    priv->gst = PAROLE_GST (parole_gst_new ());
+    priv->gst = PAROLE_GST (parole_gst_get ());
     
     priv->gst_sig1 = g_signal_connect (G_OBJECT (priv->gst), "media-state",
 				       G_CALLBACK (parole_plugin_media_state_changed_cb), plugin);
@@ -587,7 +587,7 @@ gboolean parole_plugin_play_uri (ParolePlugin *plugin, const gchar *uri)
     g_return_val_if_fail (PAROLE_IS_PLUGIN (plugin), FALSE);
     g_return_val_if_fail (PAROLE_IS_PLUGIN (uri != NULL), FALSE);
     
-    parole_gst_play_uri (PAROLE_PLUGIN_GET_PRIVATE (plugin)->gst, uri);
+    parole_gst_play_uri (PAROLE_PLUGIN_GET_PRIVATE (plugin)->gst, uri, NULL);
     
     return TRUE;
 }
diff --git a/parole/parole-utils.c b/parole/parole-utils.c
index 04139d7..e429d65 100644
--- a/parole/parole-utils.c
+++ b/parole/parole-utils.c
@@ -44,50 +44,6 @@ static const char subtitle_ext[][4] = {
 	"ass"
 };
 
-void parole_window_busy_cursor		(GdkWindow *window)
-{
-    GdkCursor *cursor;
-    
-    if ( G_UNLIKELY (window == NULL) )
-	return;
-	
-    cursor = gdk_cursor_new (GDK_WATCH);
-    gdk_window_set_cursor (window, cursor);
-    gdk_cursor_unref (cursor);
-
-    gdk_flush ();
-}
-
-void parole_window_invisible_cursor		(GdkWindow *window)
-{
-    GdkBitmap *empty_bitmap;
-    GdkCursor *cursor;
-    GdkColor  color;
-
-    char cursor_bits[] = { 0x0 }; 
-    
-    if ( G_UNLIKELY (window == NULL) )
-	return;
-	
-    color.red = color.green = color.blue = 0;
-    color.pixel = 0;
-
-    empty_bitmap = gdk_bitmap_create_from_data (window,
-		   cursor_bits,
-		   1, 1);
-
-    cursor = gdk_cursor_new_from_pixmap (empty_bitmap,
-					 empty_bitmap,
-					 &color,
-					 &color, 0, 0);
-
-    gdk_window_set_cursor (window, cursor);
-
-    gdk_cursor_unref (cursor);
-
-    g_object_unref (empty_bitmap);
-}
-
 /*
  * compare_by_name_using_number
  * 
diff --git a/parole/parole-utils.h b/parole/parole-utils.h
index a755200..9db205a 100644
--- a/parole/parole-utils.h
+++ b/parole/parole-utils.h
@@ -26,10 +26,6 @@
 
 #include "parole-file.h"
 
-void		parole_window_busy_cursor		(GdkWindow *window);
-
-void		parole_window_invisible_cursor		(GdkWindow *window);
-
 gint            thunar_file_compare_by_name 		(ParoleFile *file_a,
 							 ParoleFile *file_b,
 							 gboolean         case_sensitive);



More information about the Xfce4-commits mailing list