[Xfce4-commits] <parole:master> Change the plugin API, should be much better now.

Ali Abdallah noreply at xfce.org
Mon Nov 23 16:04:01 CET 2009


Updating branch refs/heads/master
         to 5c0d359544fd44140ce88f45f990eb5b6b93dc65 (commit)
       from 99e2c560a6604a734d7df6de489a5ccf301cb251 (commit)

commit 5c0d359544fd44140ce88f45f990eb5b6b93dc65
Author: Ali Abdallah <ali at ali-xfce.org>
Date:   Mon Nov 23 15:50:42 2009 +0100

    Change the plugin API, should be much better now.

 Makefile.am                                        |    2 +-
 NEWS                                               |   20 +
 browser-plugin/media-plugin/Makefile.am            |    1 +
 configure.ac.in                                    |    3 +-
 data/icons/Makefile.am                             |    2 +-
 data/interfaces/plugins.ui                         |    8 +-
 docs/plugin-api/Makefile.am                        |   20 +-
 docs/plugin-api/Parole-Plugins-docs.sgml           |   16 +-
 docs/plugin-api/Parole-Plugins-sections.txt        |  327 ++--------
 docs/plugin-api/Parole-Plugins.types               |   18 +-
 gst/Makefile.am                                    |   10 +-
 parole/Makefile.am                                 |   93 +++-
 {src => parole}/parole-file.c                      |    0
 parole/parole-file.h                               |    4 +
 gst/gstmarshal.list => parole/parole-marshal.list  |    1 -
 parole/parole-plugin.h                             |  121 ----
 parole/parole-provider-player.c                    |  212 +++++++
 parole/parole-provider-player.h                    |  117 ++++
 parole/parole-provider-plugin.c                    |  100 +++
 parole/parole-provider-plugin.h                    |   73 +++
 {gst => parole}/parole-stream.c                    |    6 +-
 parole/parole-stream.h                             |    4 +
 parole/parole.h                                    |   62 +--
 plugins/Makefile.am                                |    4 +-
 plugins/properties/Makefile.am                     |   21 +-
 .../properties/stream-properties-plugin.c          |   30 +-
 ...m-properties.c => stream-properties-provider.c} |  208 ++++---
 plugins/properties/stream-properties-provider.h    |   42 ++
 plugins/properties/stream-properties.desktop.in    |    6 +
 plugins/{properties => sample}/Makefile.am         |   23 +-
 .../sample/sample-plugin.c                         |   30 +-
 plugins/sample/sample-provider.c                   |   86 +++
 plugins/sample/sample-provider.h                   |   42 ++
 plugins/tray/Makefile.am                           |   20 +-
 plugins/tray/system-tray.desktop.in                |    6 +
 src/parole-builder.h => plugins/tray/tray-plugin.c |   30 +-
 plugins/tray/{tray-icon.c => tray-provider.c}      |  269 +++++----
 plugins/tray/tray-provider.h                       |   42 ++
 plugins/window-title/Makefile.am                   |   21 +-
 .../window-title/window-title-plugin.c             |   31 +-
 plugins/window-title/window-title-provider.c       |  146 +++++
 plugins/window-title/window-title-provider.h       |   42 ++
 plugins/window-title/window-title.c                |  106 ----
 plugins/window-title/window-title.desktop.in       |    6 +
 src/Makefile.am                                    |   65 +--
 src/main.c                                         |    3 +-
 src/parole-disc.c                                  |    2 +-
 src/parole-filters.h                               |    2 +-
 src/parole-mediachooser.c                          |    3 +-
 src/parole-medialist.c                             |    3 +-
 src/parole-module.c                                |  155 +++--
 src/parole-module.h                                |   49 +-
 src/parole-pl-parser.c                             |    3 +-
 src/parole-player.c                                |    6 +-
 src/parole-plugin-player.c                         |  160 +++++
 .../media-plugin => src}/parole-plugin-player.h    |   24 +-
 src/parole-plugin.c                                |  662 --------------------
 src/parole-plugins-manager.c                       |  365 ++++++++----
 src/parole-plugins-manager.h                       |   12 +-
 src/parole-statusbar.c                             |   66 +-
 src/parole-utils.h                                 |    2 +-
 61 files changed, 2190 insertions(+), 1823 deletions(-)

diff --git a/Makefile.am b/Makefile.am
index a3bad15..b864bec 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -4,10 +4,10 @@ endif
 
 SUBDIRS =  			\
 	data			\
+	parole 			\
 	common			\
 	gst			\
 	dbus			\
-	parole 			\
 	src			\
 	plugins			\
 	$(browser_plugin_dir)  	\
diff --git a/NEWS b/NEWS
index c3bc253..31a8f19 100644
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,23 @@
+1.95
+====
+- Use taglib when compiled to get the media title and display it in
+  the list instead of waiting for a tag message from gst to change
+  the display name while playing.
+- Added -n command line to load parolw without plugins.
+- Added XF86 button handler.
+- Added an option in the media chooser dialog to enable/disable
+  scanning folders recursively for media files
+- Handle CTL_O and XF86XK_OpenURL.
+- Use cdda:// for audio disc, sine cdda:/ doesn't work!
+- Give focus to media list view on GDK_Up and Down.
+- Added an option in the media chooser to replace current playlist 
+  with opened files
+- Hide control full screen popup when switch from a desktop to another.
+- Enter/leave fullscreen on double click on the video widget, thanks
+  for Enrico Troger for the patch.
+- Save stream tags when stream playback finished, should be safer.
+- Added browser media player plugin.
+
 1.91
 ====
 - Don't runref the vis plugin as playbin will remove it on exit (bug #5830).
diff --git a/browser-plugin/media-plugin/Makefile.am b/browser-plugin/media-plugin/Makefile.am
index d488ee4..0ae092a 100644
--- a/browser-plugin/media-plugin/Makefile.am
+++ b/browser-plugin/media-plugin/Makefile.am
@@ -15,6 +15,7 @@ parole_media_plugin_CFLAGS =			\
 	-I$(top_srcdir)/common               	\
         -DLOCALEDIR=\"$(localedir)\"            \
         -DG_LOG_DOMAIN=\"parole-media-plugin\"  \
+	-DPAROLE_COMPILATION            	\
 	$(GTHREAD_CFLAGS)                       \
 	$(GTK_CFLAGS)				\
 	$(GST_VIDEO_CFLAGS)                     \
diff --git a/configure.ac.in b/configure.ac.in
index 2762654..ff900c3 100644
--- a/configure.ac.in
+++ b/configure.ac.in
@@ -5,7 +5,7 @@ m4_define([parole_version_major],  [0])
 m4_define([parole_version_minor],  [1])
 m4_define([parole_version_micro],  [95])
 m4_define([parole_version_build],  [@REVISION@])
-m4_define([parole_version_tag], [git])
+m4_define([parole_version_tag], [])
 m4_define([parole_version], [parole_version_major().parole_version_minor().parole_version_micro()ifelse(parole_version_tag(), [git], [parole_version_tag().parole_version_build()], [parole_version_tag()])])
 
 AC_INIT([parole], [parole_version], [aliov at xfce.org])
@@ -246,6 +246,7 @@ dbus/Makefile
 parole/Makefile
 src/Makefile
 plugins/Makefile
+plugins/sample/Makefile
 plugins/properties/Makefile
 plugins/tray/Makefile
 plugins/window-title/Makefile
diff --git a/data/icons/Makefile.am b/data/icons/Makefile.am
index 357528f..a6ea43b 100644
--- a/data/icons/Makefile.am
+++ b/data/icons/Makefile.am
@@ -2,7 +2,7 @@ SUBDIRS =         \
 	scalable  \
 	16x16     \
 	22x22	  \
-	32x32     \	
+	32x32     \
 	48x48
 
 gtk_update_icon_cache = gtk-update-icon-cache -f -t $(datadir)/icons/hicolor
diff --git a/data/interfaces/plugins.ui b/data/interfaces/plugins.ui
index 70df469..d760c56 100644
--- a/data/interfaces/plugins.ui
+++ b/data/interfaces/plugins.ui
@@ -9,8 +9,10 @@
       <column type="gboolean"/>
       <!-- column-name plugin -->
       <column type="gchararray"/>
-      <!-- column-name data -->
+      <!-- column-name module -->
       <column type="GObject"/>
+      <!-- column-name info -->
+      <column type="gpointer"/>
     </columns>
   </object>
   <object class="XfceTitledDialog" id="dialog">
@@ -50,7 +52,7 @@
                     <child>
                       <object class="GtkTreeViewColumn" id="treeviewcolumn1">
                         <property name="resizable">True</property>
-                        <property name="title" translatable="yes">Enabled</property>
+                        <property name="title">Enabled</property>
                         <property name="clickable">True</property>
                         <child>
                           <object class="GtkCellRendererToggle" id="cellrenderertoggle">
@@ -64,7 +66,7 @@
                     </child>
                     <child>
                       <object class="GtkTreeViewColumn" id="treeviewcolumn2">
-                        <property name="title" translatable="yes">Plugin</property>
+                        <property name="title">Plugin</property>
                         <child>
                           <object class="GtkCellRendererText" id="cellrenderertext1"/>
                           <attributes>
diff --git a/docs/plugin-api/Makefile.am b/docs/plugin-api/Makefile.am
index e4d00c7..b19bbb8 100644
--- a/docs/plugin-api/Makefile.am
+++ b/docs/plugin-api/Makefile.am
@@ -46,22 +46,7 @@ HFILE_GLOB=$(top_srcdir)/parole/*.h
 
 # Header files to ignore when scanning.
 # e.g. IGNORE_HFILES=gtkdebug.h gtkintl.h
-IGNORE_HFILES=
-	parole-player.h				\
-	parole-gst.h				\
-	parole-vis.h				\
-	parole-statusbar.h			\
-	parole-builder.h			\
-	parole-mediachooser.h			\
-	parole-filters.h			\
-	parole-screensaver.h			\
-	parole-conf.h				\
-	parole-conf-dialog.h			\
-	parole-rc-utils.h			\
-	parole-utils.h				\
-	parole-dbus.h				\
-	parole-debug.h				\
-	parole-plugin-manager.h
+#IGNORE_HFILES=
 
 # Images to copy into HTML directory.
 # e.g. HTML_IMAGES=$(top_srcdir)/gtk/stock-icons/stock_about_24.png
@@ -81,13 +66,14 @@ GTKDOC_CFLAGS=                  \
 	$(GTK_CFLAGS)		\
         $(GLIB_CFLAGS)          \
         $(GOBJECT_CFLAGS)       \
-        -I$(top_srcdir)/parole  \
+	$(TAGLIBC_CFLAGS)	\
         -I$(top_builddir)/parole
 
 GTKDOC_LIBS=                    \
 	$(GTK_LIBS)		\
         $(GLIB_LIBS)            \
         $(GOBJECT_LIBS)		\
+	$(TAGLIBC_LIBS)		\
 	$(top_builddir)/parole/libparole.la
 
 if ENABLE_GTK_DOC
diff --git a/docs/plugin-api/Parole-Plugins-docs.sgml b/docs/plugin-api/Parole-Plugins-docs.sgml
index 5040142..c3a9272 100644
--- a/docs/plugin-api/Parole-Plugins-docs.sgml
+++ b/docs/plugin-api/Parole-Plugins-docs.sgml
@@ -5,6 +5,7 @@
   <!ENTITY % local.common.attrib "xmlns:xi  CDATA  #FIXED 'http://www.w3.org/2003/XInclude'">
   <!ENTITY version SYSTEM "version.xml">
   <!ENTITY date "July 2009">
+
 ]>
 <book id="index">
   <bookinfo>
@@ -33,14 +34,17 @@
   </bookinfo>
 
   <chapter>
-    <title>Parole Plugins Overview</title>
-        <xi:include href="xml/parole.xml"/>
+    <title>Parole Plugin Reference</title>
+    <xi:include href="xml/parole-provider-player.xml"/>
+    <xi:include href="xml/parole-provider-plugin.xml"/>
+    <xi:include href="xml/parole-file.xml"/>
+    <xi:include href="xml/parole-stream.xml"/>
 
-        <xi:include href="xml/parole-plugin.xml"/>
-	<xi:include href="xml/parole-mediafile.xml"/>
-	<xi:include href="xml/parole-stream.xml"/>
   </chapter>
-  
+  <chapter id="object-tree">
+    <title>Object Hierarchy</title>
+     <xi:include href="xml/tree_index.sgml"/>
+  </chapter>
   <index id="api-index-full">
     <title>API Index</title>
     <xi:include href="xml/api-index-full.xml"><xi:fallback /></xi:include>
diff --git a/docs/plugin-api/Parole-Plugins-sections.txt b/docs/plugin-api/Parole-Plugins-sections.txt
index 7bc4a74..04d24ee 100644
--- a/docs/plugin-api/Parole-Plugins-sections.txt
+++ b/docs/plugin-api/Parole-Plugins-sections.txt
@@ -1,203 +1,61 @@
 <SECTION>
-<FILE>parole-plugin</FILE>
+<FILE>parole-provider-player</FILE>
+PAROLE_PROVIDER_PLAYER_GET_INTERFACE
+ParoleProviderPlayerIface
+ParoleProviderPlayer
 ParolePluginContainer
 ParoleState
-<TITLE>ParolePlugin</TITLE>
-ParolePlugin
-parole_plugin_new
-parole_plugin_get_main_window
-parole_plugin_pack_widget
-parole_plugin_play_uri
-parole_plugin_play_file
-parole_plugin_pause_playing
-parole_plugin_resume
-parole_plugin_stop_playing
-parole_plugin_seek
+parole_provider_player_get_main_window
+parole_provider_player_pack
+parole_provider_player_get_state
+parole_provider_player_play_uri
+parole_provider_player_pause
+parole_provider_player_resume
+parole_provider_player_stop
+parole_provider_player_seek
 <SUBSECTION Standard>
-PAROLE_PLUGIN
-PAROLE_IS_PLUGIN
-PAROLE_TYPE_PLUGIN
-parole_plugin_get_type
+PAROLE_PROVIDER_PLAYER
+PAROLE_IS_PROVIDER_PLAYER
+PAROLE_TYPE_PROVIDER_PLAYER
+parole_provider_player_get_type
 </SECTION>
 
 <SECTION>
-<FILE>parole-mediachooser</FILE>
-ParoleMediaChooserPrivate
-media_files_opened
-media_file_opened
-parole_media_chooser_open_local
-parole_media_chooser_open_location
+<FILE>parole-provider-plugin</FILE>
+PAROLE_PROVIDER_PLUGIN_GET_INTERFACE
+ParoleProviderPluginIface
+ParoleProviderPlugin
+parole_provider_plugin_get_is_configurable
+parole_provider_plugin_configure
+parole_provider_plugin_set_player
+parole_provider_plugin_get_is_active
 <SUBSECTION Standard>
-PAROLE_MEDIA_CHOOSER
-PAROLE_IS_MEDIA_CHOOSER
-PAROLE_TYPE_MEDIA_CHOOSER
-parole_media_chooser_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-plugins-manager</FILE>
-ParolePluginsManagerPrivate
-parole_plugins_manager_new
-parole_plugins_manager_load_plugins
-parole_plugins_manager_pack
-<SUBSECTION Standard>
-PAROLE_PLUGINS_MANAGER
-PAROLE_IS_PLUGINS_MANAGER
-PAROLE_TYPE_PLUGINS_MANAGER
-parole_plugins_manager_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-module</FILE>
-ParoleModulePrivate
-constructor
-parole_module_new
-<SUBSECTION Standard>
-PAROLE_MODULE
-PAROLE_IS_MODULE
-PAROLE_TYPE_MODULE
-parole_module_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-screensaver</FILE>
-PAROLE_SCREEN_SAVER
-ParoleScreenSaverPrivate
-parole_screen_saver_new
-parole_screen_saver_inhibit
-parole_screen_saver_uninhibit
-<SUBSECTION Standard>
-PAROLE_IS_SCREENSAVER
-PAROLE_TYPE_SCREENSAVER
-parole_screen_saver_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-sidebar</FILE>
-ParoleSidebarPrivate
-parole_sidebar_new
-parole_sidebar_set_visible
-<SUBSECTION Standard>
-PAROLE_SIDEBAR
-PAROLE_IS_SIDEBAR
-PAROLE_TYPE_SIDEBAR
-parole_sidebar_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-gst</FILE>
-ParoleMediaState
-ParoleGstPrivate
-media_state
-media_progressed
-buffering
-media_tag
-error
-parole_gst_new
-parole_gst_play_file
-parole_gst_pause
-parole_gst_resume
-parole_gst_stop
-parole_gst_null_state
-parole_gst_seek
-parole_gst_set_volume
-parole_gst_get_volume
-<SUBSECTION Standard>
-PAROLE_GST
-PAROLE_IS_GST
-PAROLE_TYPE_GST
-parole_gst_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-mediafile</FILE>
-<TITLE>ParoleMediaFile</TITLE>
-ParoleMediaFile
-parole_media_file_new
-parole_media_file_get_file_name
-parole_media_file_get_display_name
-parole_media_file_get_uri
-parole_media_file_get_content_type
-<SUBSECTION Standard>
-PAROLE_MEDIA_FILE
-PAROLE_IS_MEDIA_FILE
-PAROLE_TYPE_MEDIA_FILE
-parole_media_file_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-player</FILE>
-ParolePlayerPrivate
-parole_player_new
-parole_player_get_media_list
-<SUBSECTION Standard>
-PAROLE_PLAYER
-PAROLE_IS_PLAYER
-PAROLE_TYPE_PLAYER
-parole_player_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-medialist</FILE>
-ParoleMediaListPrivate
-media_activated
-media_cursor_changed
-parole_media_list_new
-parole_media_list_get_selected_row
-parole_media_list_get_next_row
-parole_media_list_set_row_pixbuf
-parole_media_list_set_row_name
-parole_media_list_open
-parole_media_list_open_location
-parole_media_list_add_files
-<SUBSECTION Standard>
-PAROLE_MEDIA_LIST
-PAROLE_IS_MEDIA_LIST
-PAROLE_TYPE_MEDIA_LIST
-parole_media_list_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-conf-dialog</FILE>
-ParoleConfDialogPrivate
-parole_conf_dialog_new
-parole_conf_dialog_open
-<SUBSECTION Standard>
-PAROLE_CONF_DIALOG
-PAROLE_IS_CONF_DIALOG
-PAROLE_TYPE_CONF_DIALOG
-parole_conf_dialog_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-statusbar</FILE>
-ParoleStatusbarPrivate
-parole_statusbar_new
-parole_statusbar_set_text
-parole_statusbar_set_duration
-parole_statusbar_set_position
-parole_statusbar_set_buffering
-parole_statusbar_set_visible
-<SUBSECTION Standard>
-PAROLE_STATUSBAR
-PAROLE_IS_STATUSBAR
-PAROLE_TYPE_STATUSBAR
-parole_statusbar_get_type
-</SECTION>
-
-<SECTION>
-<FILE>parole-conf</FILE>
-ParoleConfPrivate
-parole_conf_new
+PAROLE_PROVIDER_PLUGIN
+PAROLE_IS_PROVIDER_PLUGIN
+PAROLE_TYPE_PROVIDER_PLUGIN
+parole_provider_plugin_get_type
+</SECTION>
+
+<SECTION>
+<FILE>parole-file</FILE>
+<TITLE>ParoleFile</TITLE>
+ParoleFile
+parole_file_new
+parole_file_new_with_display_name
+parole_file_get_file_name
+parole_file_get_display_name
+parole_file_get_uri
+parole_file_get_content_type
 <SUBSECTION Standard>
-PAROLE_CONF
-PAROLE_IS_CONF
-PAROLE_TYPE_CONF
-parole_conf_get_type
+PAROLE_FILE
+PAROLE_IS_FILE
+PAROLE_TYPE_FILE
+parole_file_get_type
 </SECTION>
 
 <SECTION>
 <FILE>parole-stream</FILE>
+ParoleMediaType
 <TITLE>ParoleStream</TITLE>
 ParoleStream
 parole_stream_new
@@ -210,102 +68,27 @@ parole_stream_get_type
 </SECTION>
 
 <SECTION>
-<FILE>enum-gtypes</FILE>
-parole_media_state_get_type
-ENUM_GTYPE_MEDIA_STATE
+<FILE>parole-enum-types</FILE>
+parole_media_type_get_type
+PAROLE_ENUM_TYPE_MEDIA_TYPE
 parole_plugin_container_get_type
-ENUM_GTYPE_PLUGIN_CONTAINER
+PAROLE_ENUM_TYPE_PLUGIN_CONTAINER
 parole_state_get_type
-ENUM_GTYPE_STATE
-</SECTION>
-
-<SECTION>
-<FILE>parole-rc-utils</FILE>
-parole_rc_write_entry_bool
-parole_rc_write_entry_int
-parole_rc_write_entry_string
-parole_rc_read_entry_bool
-parole_rc_read_entry_int
-parole_rc_read_entry_string
-</SECTION>
-
-<SECTION>
-<FILE>org.parole.media.list</FILE>
-g_marshal_value_peek_boolean
-g_marshal_value_peek_char
-g_marshal_value_peek_uchar
-g_marshal_value_peek_int
-g_marshal_value_peek_uint
-g_marshal_value_peek_long
-g_marshal_value_peek_ulong
-g_marshal_value_peek_int64
-g_marshal_value_peek_uint64
-g_marshal_value_peek_enum
-g_marshal_value_peek_flags
-g_marshal_value_peek_float
-g_marshal_value_peek_double
-g_marshal_value_peek_string
-g_marshal_value_peek_param
-g_marshal_value_peek_boxed
-g_marshal_value_peek_pointer
-g_marshal_value_peek_object
-dbus_glib_marshal_parole_media_list_BOOLEAN__BOXED_POINTER
+PAROLE_ENUM_TYPE_STATE
 </SECTION>
 
 <SECTION>
-<FILE>parole-utils</FILE>
-parole_window_busy_cursor
-parole_window_invisible_cursor
-thunar_file_compare_by_name
-parole_get_name_without_extension
-parole_get_subtitle_path
+<FILE>stamp-enum-types</FILE>
 </SECTION>
 
 <SECTION>
 <FILE>parole</FILE>
-parole_plugin_constructor
-ParolePluginConstruct
-PAROLE_PLUGIN_CONSTRUCT
-</SECTION>
-
-<SECTION>
-<FILE>gmarshal</FILE>
-</SECTION>
-
-<SECTION>
-<FILE>stamp-enum-gtypes</FILE>
-</SECTION>
-
-<SECTION>
-<FILE>parole-filters</FILE>
-parole_get_supported_audio_filter
-parole_get_supported_video_filter
-parole_get_supported_media_filter
-parole_file_filter
-parole_get_media_files
-</SECTION>
-
-<SECTION>
-<FILE>parole-vis</FILE>
-parole_vis_get_plugins
-</SECTION>
-
-<SECTION>
-<FILE>parole-debug</FILE>
-PAROLE_DEBUG_ENUM
-PAROLE_DEBUG_ENUM_FULL
-parole_debug_enum
-parole_debug_enum_full
 </SECTION>
 
 <SECTION>
-<FILE>parole-dbus</FILE>
-PAROLE_DBUS_NAME
-PAROLE_DBUS_PATH
-PAROLE_DBUS_INTERFACE
-parole_g_session_bus_get
-parole_dbus_name_has_owner
-parole_dbus_register_name
-parole_dbus_release_name
+<FILE>parole-marshal</FILE>
+parole_marshal_VOID__OBJECT_ENUM
+parole_marshal_VOID__OBJECT_DOUBLE
+parole_marshal_VOID__OBJECT_INT
 </SECTION>
 
diff --git a/docs/plugin-api/Parole-Plugins.types b/docs/plugin-api/Parole-Plugins.types
index 1d7ed2b..53def75 100644
--- a/docs/plugin-api/Parole-Plugins.types
+++ b/docs/plugin-api/Parole-Plugins.types
@@ -1,17 +1,7 @@
-parole_plugin_get_type
-parole_media_state_get_type
+parole_media_type_get_type
 parole_plugin_container_get_type
 parole_state_get_type
-parole_media_chooser_get_type
-parole_plugins_manager_get_type
-parole_module_get_type
-parole_screen_saver_get_type
-parole_sidebar_get_type
-parole_gst_get_type
-parole_media_file_get_type
-parole_player_get_type
-parole_media_list_get_type
-parole_conf_dialog_get_type
-parole_statusbar_get_type
-parole_conf_get_type
+parole_provider_player_get_type
+parole_provider_plugin_get_type
+parole_file_get_type
 parole_stream_get_type
diff --git a/gst/Makefile.am b/gst/Makefile.am
index 582ebed..55aadf8 100644
--- a/gst/Makefile.am
+++ b/gst/Makefile.am
@@ -6,6 +6,7 @@ INCLUDES =                              \
         -I$(top_srcdir)/common          \
 	-I$(top_srcdir)/parole		\
         -DLOCALEDIR=\"$(localedir)\"    \
+	-DPAROLE_COMPILATION            \
         -DG_LOG_DOMAIN=\"parole-gst\"
 
 GENERATED_FILES =			\
@@ -17,9 +18,7 @@ GENERATED_FILES =			\
 libparolegst_la_SOURCES =		\
 	$(GENERATED_FILES)		\
 	parole-gst.c			\
-	parole-gst.h			\
-	parole-stream.c			\
-	parole-stream.h
+	parole-gst.h
 	
 libparolegst_la_CFLAGS =		\
 	$(GST_VIDEO_CFLAGS)             \
@@ -28,11 +27,11 @@ libparolegst_la_CFLAGS =		\
 	$(LIBXFCE4GUI_CFLAGS)
 
 libparolegst_la_LIBADD =		\
+	$(top_builddir)/parole/libparole.la\
 	$(top_builddir)/common/libparolecommon.la
 
 parole_glib_enum_headers =		\
-	parole-gst.h			\
-	$(top_srcdir)/parole/parole-stream.h
+	parole-gst.h
 
 if MAINTAINER_MODE
 
@@ -63,7 +62,6 @@ 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@\" }," \
diff --git a/parole/Makefile.am b/parole/Makefile.am
index 78d0d27..6c74c78 100644
--- a/parole/Makefile.am
+++ b/parole/Makefile.am
@@ -1,14 +1,97 @@
-INST_HFILES =					\
+noinst_LTLIBRARIES =                    	\
+        libparole.la
+
+INCLUDES =                              	\
+        -I$(top_srcdir)                 	\
+        -DLOCALEDIR=\"$(localedir)\"		\
+	-DPAROLE_COMPILATION
+
+libparole_la_SOURCES =				\
+	$(GENERATED_FILES)			\
 	parole.h				\
-	parole-plugin.h				\
+	parole-provider-plugin.c		\
+	parole-provider-plugin.h		\
+	parole-provider-player.c		\
+	parole-provider-player.h		\
+	parole-file.c				\
 	parole-file.h				\
+	parole-stream.c				\
 	parole-stream.h
 
-parole_headers =				\
+libparole_la_CFLAGS =				\
+	$(GIO_CFLAGS)                           \
+	$(GTK_CFLAGS)				\
+	$(TAGLIBC_CFLAGS)
+
+GENERATED_FILES =				\
+	parole-marshal.c			\
+	parole-marshal.h			\
+	parole-enum-types.c			\
+	parole-enum-types.h
+
+if MAINTAINER_MODE
+
+BUILT_SOURCES =                         	\
+	$(GENERATED_FILES)
+
+parole-marshal.c: parole-marshal.list
+	echo "#include \"parole-marshal.h\"" > $@ && \
+	glib-genmarshal $< --prefix=parole_marshal --body >> $@
+
+parole-marshal.h: parole-marshal.list
+	glib-genmarshal $< --prefix=parole_marshal --header > $@
+
+parole_glib_enum_headers =		\
+	parole-stream.h			\
+	parole-provider-player.h
+
+parole-enum-types.h: stamp-enum-types.h
+	@true
+stamp-enum-types.h: $(parole_glib_enum_headers) Makefile
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#ifndef __PAROLE_ENUM_TYPE_H__\n#define __PAROLE_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 PAROLE_ENUM_TYPE_ at ENUMSHORT@ (@enum_name at _get_type())\n" \
+		--ftail "G_END_DECLS\n\n#endif /* __PAROLE_ENUM_TYPE_H__ */" \
+		$(parole_glib_enum_headers) ) > xgen-enum.h \
+	&& (cmp -s xgen-enum.h parole-enum-types.h || cp xgen-enum.h parole-enum-types.h) \
+	&& rm -f xgen-enum.h \
+	&& echo timestamp > $(@F)
+
+parole-enum-types.c: $(parole_glib_enum_headers) Makefile
+	( cd $(srcdir) && glib-mkenums \
+		--fhead "#include \"parole-enum-types.h\"\n\n" \
+		--fhead "#include \"parole-stream.h\"\n\n" \
+		--fhead "#include \"parole-provider-player.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 parole-enum-types.c \
+	&& rm -f xgen-enum.c
+
+endif
+
+EXTRA_DIST =					\
+	parole-marshal.list
+
+DISTCLEANFILES =				\
+	$(BUILT_SOURCES)			\
+	stamp-enum-types.h
+
+INST_HFILES =					\
+	parole.h				\
+	parole-file.h				\
+	parole-stream.h				\
+	parole-provider-player.h		\
+	parole-provider-plugin.h
+
+libparole_headers =				\
 	$(INST_HFILES)
 
-parole_includedir =				\
+libparole_includedir =				\
 	$(includedir)/parole
 
-parole_include_HEADERS =			\
+libparole_include_HEADERS =			\
 	$(parole_headers)
\ No newline at end of file
diff --git a/src/parole-file.c b/parole/parole-file.c
similarity index 100%
rename from src/parole-file.c
rename to parole/parole-file.c
diff --git a/parole/parole-file.h b/parole/parole-file.h
index 716b505..d98ab7f 100644
--- a/parole/parole-file.h
+++ b/parole/parole-file.h
@@ -18,6 +18,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#if !defined (__PAROLE_H_INSIDE__) && !defined (PAROLE_COMPILATION)
+#error "Only <parole.h> can be included directly."
+#endif
+
 #ifndef __PAROLE_MEDIA_FILE_H
 #define __PAROLE_MEDIA_FILE_H
 
diff --git a/gst/gstmarshal.list b/parole/parole-marshal.list
similarity index 98%
copy from gst/gstmarshal.list
copy to parole/parole-marshal.list
index 61cba6f..3747a11 100644
--- a/gst/gstmarshal.list
+++ b/parole/parole-marshal.list
@@ -1,4 +1,3 @@
 VOID:OBJECT,ENUM
 VOID:OBJECT,DOUBLE
 VOID:OBJECT,INT
-
diff --git a/parole/parole-plugin.h b/parole/parole-plugin.h
deleted file mode 100644
index bfbc1f6..0000000
--- a/parole/parole-plugin.h
+++ /dev/null
@@ -1,121 +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
- */
-
-#ifndef __PAROLE_PLUGIN_H
-#define __PAROLE_PLUGIN_H
-
-#include <glib-object.h>
-#include <gtk/gtk.h>
-
-#include <parole/parole-stream.h>
-
-G_BEGIN_DECLS
-
-#define PAROLE_TYPE_PLUGIN        (parole_plugin_get_type () )
-#define PAROLE_PLUGIN(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PLUGIN, ParolePlugin))
-#define PAROLE_IS_PLUGIN(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PLUGIN))
-
-typedef struct _ParolePlugin 	    ParolePlugin;
-typedef struct _ParolePluginClass   ParolePluginClass;
-
-typedef enum
-{
-    PAROLE_PLUGIN_CONTAINER_PLAYLIST,
-    PAROLE_PLUGIN_CONTAINER_MAIN_VIEW
-} ParolePluginContainer;
-
-
-typedef enum
-{
-    
-    PAROLE_STATE_STOPPED = 0,
-    PAROLE_STATE_PLAYBACK_FINISHED,
-    PAROLE_STATE_PAUSED,
-    PAROLE_STATE_PLAYING
-    
-} ParoleState;
-
-struct _ParolePlugin
-{
-    GObject       	     parent;
-};
-
-struct _ParolePluginClass
-{
-    GObjectClass 	     parent_class;
-    
-    void		    (*state_changed)		   		(ParolePlugin *plugin,
-									 const ParoleStream *stream,
-									 ParoleState state);
-    
-    void		    (*tag_message)                 		(ParolePlugin *plugin,
-									 const ParoleStream *stream);
-
-    void		    (*progressed)	 			(ParolePlugin *gst,
-									 const ParoleStream *stream,
-									 gdouble value);
-
-    void		    (*buffering)		 		(ParolePlugin *plugin,
-									 const ParoleStream *stream,
-									 gint percentage);
-						  
-    void		    (*free_data)		   		(ParolePlugin *plugin);
-    
-    void		    (*configure)				(ParolePlugin *plugin,
-									 GtkWidget *widget);
-};
-
-GType        		     parole_plugin_get_type        		(void) G_GNUC_CONST;
-
-ParolePlugin       	    *parole_plugin_new             		(const gchar *title,
-								         const gchar *desc, 
-									 const gchar *author,
-									 const gchar *website);
-
-GtkWidget		    *parole_plugin_get_main_window 		(ParolePlugin *plugin);
-
-void			     parole_plugin_pack_widget	   		(ParolePlugin *plugin,
-									 GtkWidget *widget,
-									 ParolePluginContainer container);
-
-ParoleState		     parole_plugin_get_state	   		(ParolePlugin *plugin);
-
-gboolean		     parole_plugin_get_is_configurable 		(ParolePlugin *plugin);
-
-void			     parole_plugin_set_is_configurable 		(ParolePlugin *plugin,
-									 gboolean is_configurable);
-
-gboolean		     parole_plugin_get_show_about 		(ParolePlugin *plugin);
-
-gboolean		     parole_plugin_play_uri        		(ParolePlugin *plugin,
-									 const gchar *uri);
-
-gboolean		     parole_plugin_pause_playback   		(ParolePlugin *plugin);
-
-gboolean		     parole_plugin_resume_playback     		(ParolePlugin *plugin);
-							    
-gboolean		     parole_plugin_stop_playback    		(ParolePlugin *plugin);
-
-gboolean		     parole_plugin_seek            		(ParolePlugin *plugin,
-									 gdouble pos);
-
-G_END_DECLS
-
-#endif /* __PAROLE_PLUGIN_H */
diff --git a/parole/parole-provider-player.c b/parole/parole-provider-player.c
new file mode 100644
index 0000000..75be233
--- /dev/null
+++ b/parole/parole-provider-player.c
@@ -0,0 +1,212 @@
+/*
+ * * 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 "parole/parole-provider-player.h"
+#include "parole-marshal.h"
+#include "parole-enum-types.h"
+
+static void	parole_provider_player_base_init	(gpointer klass);
+static void	parole_provider_player_class_init	(gpointer klass);
+
+GType
+parole_provider_player_get_type (void)
+{
+    static GType type = G_TYPE_INVALID;
+
+    if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+	static const GTypeInfo info =
+	{
+	    sizeof (ParoleProviderPlayerIface),
+	    (GBaseInitFunc) parole_provider_player_base_init,
+	    NULL,
+	    (GClassInitFunc) parole_provider_player_class_init,
+	    NULL,
+	    NULL,
+	    0,
+	    0,
+	    NULL,
+	    NULL,
+	};
+
+	type = g_type_register_static (G_TYPE_INTERFACE, "ParoleProviderPlayerIface", &info, 0);
+
+	g_type_interface_add_prerequisite (type, G_TYPE_OBJECT);
+    }
+    
+    return type;
+}
+
+static void parole_provider_player_base_init (gpointer klass)
+{
+    static gboolean initialized = FALSE;
+
+    if (G_UNLIKELY (!initialized))
+    {
+	/**
+	 * ParolePlugin::state-changed:
+	 * @plugin: the object which received the signal.
+	 * @stream: a #ParoleStream.
+	 * @state: the new state.
+	 * 
+	 * Since: 0.2 
+	 **/
+        g_signal_new ("state-changed",
+                      G_TYPE_FROM_INTERFACE (klass),
+                      G_SIGNAL_RUN_LAST,
+                      G_STRUCT_OFFSET (ParoleProviderPlayerIface, state_changed),
+                      NULL, NULL,
+                      parole_marshal_VOID__OBJECT_ENUM,
+                      G_TYPE_NONE, 2,
+		      PAROLE_TYPE_STREAM, PAROLE_ENUM_TYPE_STATE);
+
+	/**
+	 * ParoleProviderPlayer::tag-message:
+	 * @player: the object which received the signal.
+	 * @stream: a #ParoleStream.
+	 * 
+	 * Since: 0.2 
+	 **/
+	g_signal_new ("tag-message",
+		      G_TYPE_FROM_INTERFACE (klass),
+		      G_SIGNAL_RUN_LAST,
+		      G_STRUCT_OFFSET (ParoleProviderPlayerIface, tag_message),
+		      NULL, NULL,
+		      g_cclosure_marshal_VOID__OBJECT,
+		      G_TYPE_NONE, 1, PAROLE_TYPE_STREAM);
+			  
+	initialized = TRUE;
+    }
+}
+
+static void parole_provider_player_class_init (gpointer klass)
+{
+}
+
+GtkWidget *parole_provider_player_get_main_window (ParoleProviderPlayer *player)
+{
+    GtkWidget *window = NULL;
+    
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLAYER (player), NULL);
+    
+    if ( PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->get_main_window )
+    {
+	window  = (*PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->get_main_window) (player);
+    }
+    return window;
+}
+
+void parole_provider_player_pack (ParoleProviderPlayer *player, GtkWidget *widget, 
+				  const gchar *title, ParolePluginContainer container)
+{
+    g_return_if_fail (PAROLE_IS_PROVIDER_PLAYER (player));
+    
+    if ( PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->pack )
+    {
+        (*PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->pack) (player, widget, title, container);
+    }
+}
+							 
+ParoleState parole_provider_player_get_state (ParoleProviderPlayer *player)
+{
+    ParoleState state = PAROLE_STATE_STOPPED;
+    
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLAYER (player), PAROLE_STATE_STOPPED);
+    
+    if ( PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->get_state )
+    {
+	state = (*PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->get_state) (player);
+    }
+    
+    return state;
+}
+
+gboolean parole_provider_player_play_uri (ParoleProviderPlayer *player, const gchar *uri)
+{
+    gboolean ret = FALSE;
+     
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLAYER (player), FALSE);
+    
+    if ( PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->play_uri )
+    {
+	ret = (*PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->play_uri) (player, uri);
+    }
+    return ret;
+}
+
+gboolean parole_provider_player_pause (ParoleProviderPlayer *player)
+{
+    gboolean ret = FALSE;
+    
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLAYER (player), FALSE);
+    
+    if ( PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->pause )
+    {
+	ret = (*PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->pause) (player);
+    }
+    
+    return ret;
+}
+
+gboolean parole_provider_player_resume (ParoleProviderPlayer *player)
+{
+    gboolean ret = FALSE;
+    
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLAYER (player), FALSE);
+    
+    if ( PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->resume )
+    {
+	ret = (*PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->resume) (player);
+    }
+    
+    return ret;
+}
+
+gboolean parole_provider_player_stop (ParoleProviderPlayer *player)
+{
+    gboolean ret = FALSE;
+    
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLAYER (player), FALSE);
+    
+    if ( PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->stop )
+    {
+	ret = (*PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->stop) (player);
+    }
+    
+    return ret;
+}
+
+gboolean parole_provider_player_seek (ParoleProviderPlayer *player, gdouble pos)
+{
+    gboolean ret = FALSE;
+    
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLAYER (player), FALSE);
+    
+    if ( PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->seek )
+    {
+	ret = (*PAROLE_PROVIDER_PLAYER_GET_INTERFACE (player)->seek) (player, pos);
+    }
+    
+    return ret;
+}
diff --git a/parole/parole-provider-player.h b/parole/parole-provider-player.h
new file mode 100644
index 0000000..c13b11f
--- /dev/null
+++ b/parole/parole-provider-player.h
@@ -0,0 +1,117 @@
+/*
+ * * 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
+ */
+
+#if !defined (__PAROLE_H_INSIDE__) && !defined (PAROLE_COMPILATION)
+#error "Only <parole.h> can be included directly."
+#endif
+
+#ifndef __PAROLE_PROVIDER_PLAYER_H__
+#define __PAROLE_PROVIDER_PLAYER_H__
+
+#include <gtk/gtk.h>
+#include <parole/parole-stream.h>
+
+G_BEGIN_DECLS 
+
+#define PAROLE_TYPE_PROVIDER_PLAYER      	   (parole_provider_player_get_type ())
+#define PAROLE_PROVIDER_PLAYER(o)        	   (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PROVIDER_PLAYER, ParoleProviderPlayer))
+#define PAROLE_IS_PROVIDER_PLAYER(o)      	   (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PROVIDER_PLAYER))
+#define PAROLE_PROVIDER_PLAYER_GET_INTERFACE(o)    (G_TYPE_INSTANCE_GET_INTERFACE((o), PAROLE_TYPE_PROVIDER_PLAYER, ParoleProviderPlayerIface))
+
+typedef struct _ParoleProviderPlayerIface ParoleProviderPlayerIface;
+typedef struct _ParoleProviderPlayer 	  ParoleProviderPlayer;
+
+typedef enum
+{
+    PAROLE_PLUGIN_CONTAINER_PLAYLIST,
+    PAROLE_PLUGIN_CONTAINER_MAIN_VIEW
+} ParolePluginContainer;
+
+typedef enum
+{
+    PAROLE_STATE_STOPPED = 0,
+    PAROLE_STATE_PLAYBACK_FINISHED,
+    PAROLE_STATE_PAUSED,
+    PAROLE_STATE_PLAYING
+    
+} ParoleState;
+
+struct _ParoleProviderPlayerIface 
+{
+    GTypeInterface __parent__;
+    
+    /*< private >*/
+    GtkWidget 	*(*get_main_window)			(ParoleProviderPlayer *player);
+    
+    void	 (*pack)				(ParoleProviderPlayer *player,
+							 GtkWidget *widget, 
+							 const gchar *title,
+							 ParolePluginContainer container);
+							 
+    ParoleState  (*get_state)				(ParoleProviderPlayer *player);
+    
+    gboolean	 (*play_uri)				(ParoleProviderPlayer *player,
+							 const gchar *uri);
+							 
+    gboolean	 (*pause)				(ParoleProviderPlayer *player);
+    
+    gboolean	 (*resume)				(ParoleProviderPlayer *player);
+    
+    gboolean	 (*stop)				(ParoleProviderPlayer *player);
+    
+    gboolean	 (*seek)				(ParoleProviderPlayer *player,
+							 gdouble pos);
+							 
+    /*< signals >*/
+    void	 (*tag_message)                 	(ParoleProviderPlayer *player,
+							 const ParoleStream *stream);
+							 
+    void	 (*state_changed)		   	(ParoleProviderPlayer *player,
+							 const ParoleStream *stream,
+							 ParoleState state);
+
+};
+
+GType		 parole_provider_player_get_type	(void) G_GNUC_CONST;
+
+GtkWidget       *parole_provider_player_get_main_window (ParoleProviderPlayer *player);
+
+void		 parole_provider_player_pack		(ParoleProviderPlayer *player, 
+							 GtkWidget *widget, 
+							 const gchar *title,
+							 ParolePluginContainer container);
+							 
+ParoleState	parole_provider_player_get_state	(ParoleProviderPlayer *player);
+
+gboolean	parole_provider_player_play_uri		(ParoleProviderPlayer *player,
+							 const gchar *uri);
+
+gboolean	parole_provider_player_pause		(ParoleProviderPlayer *player);
+
+gboolean	parole_provider_player_resume		(ParoleProviderPlayer *player);
+
+gboolean	parole_provider_player_stop		(ParoleProviderPlayer *player);
+
+gboolean	parole_provider_player_seek		(ParoleProviderPlayer *player,
+							 gdouble pos);
+
+G_END_DECLS
+
+#endif /* __PAROLE_PLUGIN_IFACE_H__ */
diff --git a/parole/parole-provider-plugin.c b/parole/parole-provider-plugin.c
new file mode 100644
index 0000000..cefa738
--- /dev/null
+++ b/parole/parole-provider-plugin.c
@@ -0,0 +1,100 @@
+/*
+ * * 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 "parole/parole-provider-plugin.h"
+
+GType
+parole_provider_plugin_get_type (void)
+{
+    static GType type = G_TYPE_INVALID;
+
+    if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+	static const GTypeInfo info =
+	{
+	    sizeof (ParoleProviderPluginIface),
+	    NULL,
+	    NULL,
+	    NULL,
+	    NULL,
+	    NULL,
+	    0,
+	    0,
+	    NULL,
+	    NULL,
+	};
+
+	type = g_type_register_static (G_TYPE_INTERFACE, "ParoleProviderPlugin", &info, 0);
+    }
+    
+    return type;
+}
+
+gboolean parole_provider_plugin_get_is_configurable (ParoleProviderPlugin *provider)
+{
+    gboolean configurable = FALSE;
+    
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLUGIN (provider), FALSE);
+    
+    if ( PAROLE_PROVIDER_PLUGIN_GET_INTERFACE (provider)->get_is_configurable )
+    {
+	configurable = (*PAROLE_PROVIDER_PLUGIN_GET_INTERFACE (provider)->get_is_configurable) (provider);
+    }
+    
+    return configurable;
+}
+
+void parole_provider_plugin_configure (ParoleProviderPlugin *provider, GtkWidget *parent)
+{
+    g_return_if_fail (PAROLE_IS_PROVIDER_PLUGIN (provider));
+    
+    if ( PAROLE_PROVIDER_PLUGIN_GET_INTERFACE (provider)->configure )
+    {
+	(*PAROLE_PROVIDER_PLUGIN_GET_INTERFACE (provider)->configure) (provider, parent);
+    }
+}
+
+void parole_provider_plugin_set_player (ParoleProviderPlugin *provider, ParoleProviderPlayer *player)
+{
+    g_return_if_fail (PAROLE_IS_PROVIDER_PLUGIN (provider));
+    
+    if ( PAROLE_PROVIDER_PLUGIN_GET_INTERFACE (provider)->set_player )
+    {
+	(*PAROLE_PROVIDER_PLUGIN_GET_INTERFACE (provider)->set_player) (provider, player);
+    }
+}
+
+gboolean parole_provider_plugin_get_is_active   (ParoleProviderPlugin *provider)
+{
+    gboolean active = FALSE;
+    
+    g_return_val_if_fail (PAROLE_IS_PROVIDER_PLUGIN (provider), FALSE);
+    
+    if ( PAROLE_PROVIDER_PLUGIN_GET_INTERFACE (provider)->get_is_active )
+    {
+	active = (*PAROLE_PROVIDER_PLUGIN_GET_INTERFACE (provider)->get_is_active) (provider);
+    }
+    
+    return active;
+}
diff --git a/parole/parole-provider-plugin.h b/parole/parole-provider-plugin.h
new file mode 100644
index 0000000..4e7cb75
--- /dev/null
+++ b/parole/parole-provider-plugin.h
@@ -0,0 +1,73 @@
+/*
+ * * 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
+ */
+
+#if !defined (__PAROLE_H_INSIDE__) && !defined (PAROLE_COMPILATION)
+#error "Only <parole.h> can be included directly."
+#endif
+
+#ifndef __PAROLE_PROVIDER_PLUGIN_H__
+#define __PAROLE_PROVIDER_PLUGIN_H__
+
+#include <gtk/gtk.h>
+#include <parole/parole-stream.h>
+#include <parole/parole-provider-player.h>
+
+G_BEGIN_DECLS 
+
+#define PAROLE_TYPE_PROVIDER_PLUGIN      	   (parole_provider_plugin_get_type ())
+#define PAROLE_PROVIDER_PLUGIN(o)        	   (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PROVIDER_PLUGIN, ParoleProviderPlugin))
+#define PAROLE_IS_PROVIDER_PLUGIN(o)      	   (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PROVIDER_PLUGIN))
+#define PAROLE_PROVIDER_PLUGIN_GET_INTERFACE(o)    (G_TYPE_INSTANCE_GET_INTERFACE((o), PAROLE_TYPE_PROVIDER_PLUGIN, ParoleProviderPluginIface))
+
+typedef struct _ParoleProviderPluginIface ParoleProviderPluginIface;
+typedef struct _ParoleProviderPlugin 	  ParoleProviderPlugin;
+
+struct _ParoleProviderPluginIface 
+{
+    GTypeInterface 	__parent__;
+    
+    /*< public >*/
+    gboolean	   	 (*get_is_configurable)			(ParoleProviderPlugin *provider);
+    
+    void		 (*configure)				(ParoleProviderPlugin *provider,
+								 GtkWidget *parent);
+								 
+    void		 (*set_player)				(ParoleProviderPlugin *provider,
+								 ParoleProviderPlayer *player);
+								 
+    /*< private >*/
+    gboolean		(*get_is_active)			(ParoleProviderPlugin *provider);
+};
+
+GType		 	 parole_provider_plugin_get_type	(void) G_GNUC_CONST;
+
+gboolean     		 parole_provider_plugin_get_is_configurable (ParoleProviderPlugin *provider);
+
+void			 parole_provider_plugin_configure       (ParoleProviderPlugin *provider,
+								 GtkWidget *parent);
+								 
+void			 parole_provider_plugin_set_player	(ParoleProviderPlugin *provider,
+								 ParoleProviderPlayer *player);
+
+gboolean		 parole_provider_plugin_get_is_active   (ParoleProviderPlugin *provider);
+
+G_END_DECLS
+
+#endif /* __PAROLE_PLUGIN_IFACE_H__ */
diff --git a/gst/parole-stream.c b/parole/parole-stream.c
similarity index 99%
copy from gst/parole-stream.c
copy to parole/parole-stream.c
index f4d3047..c0834e3 100644
--- a/gst/parole-stream.c
+++ b/parole/parole-stream.c
@@ -29,7 +29,7 @@
 #include <glib.h>
 
 #include "parole-stream.h"
-#include "gst-enum-types.h"
+#include "parole-enum-types.h"
 
 #define PAROLE_STREAM_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_STREAM, ParoleStreamPrivate))
@@ -122,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, GST_ENUM_TYPE_MEDIA_TYPE);
+    g_value_init (&val, PAROLE_ENUM_TYPE_MEDIA_TYPE);
     g_value_set_enum (&val, type);
     g_object_set_property (G_OBJECT (stream), "media-type", &val);
     g_value_unset (&val);
@@ -393,7 +393,7 @@ parole_stream_class_init (ParoleStreamClass *klass)
 				     PROP_MEDIA_TYPE,
 				     g_param_spec_enum ("media-type",
 							NULL, NULL,
-							GST_ENUM_TYPE_MEDIA_TYPE,
+							PAROLE_ENUM_TYPE_MEDIA_TYPE,
 							PAROLE_MEDIA_TYPE_UNKNOWN,
 							G_PARAM_READWRITE));
 
diff --git a/parole/parole-stream.h b/parole/parole-stream.h
index 9026563..3df8e77 100644
--- a/parole/parole-stream.h
+++ b/parole/parole-stream.h
@@ -18,6 +18,10 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
+#if !defined (__PAROLE_H_INSIDE__) && !defined (PAROLE_COMPILATION)
+#error "Only <parole.h> can be included directly."
+#endif
+
 #ifndef __PAROLE_STREAM_H
 #define __PAROLE_STREAM_H
 
diff --git a/parole/parole.h b/parole/parole.h
index da3b6b9..26c39af 100644
--- a/parole/parole.h
+++ b/parole/parole.h
@@ -18,58 +18,18 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#include <parole/parole-plugin.h>
+#ifndef __PAROLE_H_
+#define __PAROLE_H_
 
-typedef struct
-{
-    gchar *title;
-    gchar *desc;
-    gchar *author;
-    gchar *site;
-    
-} ParolePluginDesc;
+#define __PAROLE_H_INSIDE__
 
-ParolePluginDesc     *parole_plugin_get_description  (void);
-ParolePlugin         *parole_plugin_constructor      (void);
+#include <glib-object.h>
 
-/**
- * ParolePluginConstruct:
- * @plugin: A #ParolePlugin.
- * 
- * Argument registration function to be used with 
- * the registration macro PAROLE_PLUGIN_CONSTRUCT().
- * 
- **/
-typedef void 	(*ParolePluginConstruct)	(ParolePlugin *plugin);
+#include <parole/parole-provider-plugin.h>
+#include <parole/parole-provider-player.h>
+#include <parole/parole-file.h>
+#include <parole/parole-stream.h>
 
-/**
- * PAROLE_PLUGIN_CONSTRUCT:
- * @construct: a function that can be cast to #ParolePluginConstruct type.
- * @title: title.
- * @desc: description.
- * @author: author.
- * 
- * Since: 0.2
- * 
- **/
-#define PAROLE_PLUGIN_CONSTRUCT(construct, p_title, p_desc, p_author, p_site)   \
-    G_MODULE_EXPORT ParolePluginDesc *parole_plugin_get_description (void) 	\
-    {									   	\
-	ParolePluginDesc *plugin_desc;					   	\
-	plugin_desc = g_new0 (ParolePluginDesc, 1);			   	\
-	plugin_desc->author = (p_author);				   	\
-	plugin_desc->title =  (p_title);				   	\
-	plugin_desc->desc =  (p_desc);					   	\
-	plugin_desc->site =  (p_site);					   	\
-	return plugin_desc;						   	\
-    }								 	   	\
-    G_MODULE_EXPORT ParolePlugin  *parole_plugin_constructor (void)	   	\
-    {									   	\
-	ParolePlugin *plugin;						   	\
-	ParolePluginConstruct constructor 				   	\
-	    = (ParolePluginConstruct) construct;			   	\
-										\
-	plugin = parole_plugin_new (p_title, p_desc, p_author, p_site);		\
-	constructor (plugin);						   	\
-	return plugin;							   	\
-    }
+#undef __PAROLE_H_INSIDE__
+
+#endif /*__PAROLE_H_*/
diff --git a/plugins/Makefile.am b/plugins/Makefile.am
index c3b1ac1..d351044 100644
--- a/plugins/Makefile.am
+++ b/plugins/Makefile.am
@@ -1,4 +1,4 @@
-SUBDIRS = 
+SUBDIRS = sample
 
 if PAROLE_PROPERTIES_PLUGIN
 SUBDIRS+=properties
@@ -10,4 +10,4 @@ endif
 
 if WINDOW_TITLE_PLUGIN
 SUBDIRS+=window-title
-endif
\ No newline at end of file
+endif
diff --git a/plugins/properties/Makefile.am b/plugins/properties/Makefile.am
index feae225..f4169d0 100644
--- a/plugins/properties/Makefile.am
+++ b/plugins/properties/Makefile.am
@@ -12,12 +12,15 @@ plugins_LTLIBRARIES =				\
 	stream-properties.la
 
 stream_properties_la_SOURCES =			\
-	stream-properties.c
+	stream-properties-plugin.c		\
+	stream-properties-provider.c		\
+	stream-properties-provider.h
 
 stream_properties_la_CFLAGS =			\
 	$(PLATFORM_CFLAGS)			\
 	$(GTK_CFLAGS)				\
-	$(TAGLIBC_CFLAGS)
+	$(TAGLIBC_CFLAGS)			\
+	$(LIBXFCE4UTIL_CFLAGS)
 
 stream_properties_la_LIBADD =			\
 	$(TAGLIBC_LIBS)
@@ -27,3 +30,17 @@ stream_properties_la_LDFLAGS =			\
 	-export-dynamic				\
 	-module					\
 	$(PLATFORM_LDFLAGS)
+
+#
+# .desktop file
+#
+desktop_in_files = stream-properties.desktop.in
+desktopdir = $(datadir)/parole/parole-plugins-$(PAROLE_VERSION_API)
+desktop_DATA =  $(desktop_in_files:.desktop.in=.desktop)
+ at INTLTOOL_DESKTOP_RULE@
+
+EXTRA_DIST = 		  	\
+	$(desktop_in_files)
+    
+DISTCLEANFILES = 		\
+	$(desktop_DATA)
diff --git a/src/parole-builder.h b/plugins/properties/stream-properties-plugin.c
similarity index 61%
copy from src/parole-builder.h
copy to plugins/properties/stream-properties-plugin.c
index 3f0cbf0..f74c680 100644
--- a/src/parole-builder.h
+++ b/plugins/properties/stream-properties-plugin.c
@@ -18,19 +18,27 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef __PAROLE_BUILDER_H
-#define __PAROLE_BUILDER_H
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <glib-object.h>
-#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
 
-G_BEGIN_DECLS
+#include "stream-properties-provider.h"
 
-GtkBuilder       	       *parole_builder_get_main_interface       (void);
+G_MODULE_EXPORT GType	parole_plugin_initialize (ParoleProviderPlugin *plugin);
+						  
+G_MODULE_EXPORT void	parole_plugin_shutdown   (void);
 
-GtkBuilder		       *parole_builder_new_from_string 		(const gchar *ui,
-									 gsize length);
+G_MODULE_EXPORT GType
+parole_plugin_initialize (ParoleProviderPlugin *plugin)
+{
+    xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+    return STREAM_TYPE_PROPERTIES_PROVIDER;
+}
 
-G_END_DECLS
-
-#endif /* __PAROLE_BUILDER_H */
+G_MODULE_EXPORT void
+parole_plugin_shutdown (void)
+{
+    
+}
diff --git a/plugins/properties/stream-properties.c b/plugins/properties/stream-properties-provider.c
similarity index 65%
rename from plugins/properties/stream-properties.c
rename to plugins/properties/stream-properties-provider.c
index 27f30e7..6538c4e 100644
--- a/plugins/properties/stream-properties.c
+++ b/plugins/properties/stream-properties-provider.c
@@ -26,17 +26,28 @@
 #include <stdlib.h>
 
 #include <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include <parole/parole.h>
 
 #ifdef HAVE_TAGLIBC
 #include <taglib/tag_c.h>
 #endif
 
-typedef struct
+#include <libxfce4util/libxfce4util.h>
+
+#include "stream-properties-provider.h"
+
+static void   stream_properties_iface_init 	   (ParoleProviderPluginIface *iface);
+static void   stream_properties_finalize             (GObject 	              *object);
+
+
+struct _StreamPropertiesClass
 {
+    GObjectClass parent_class;
+};
+
+struct _StreamProperties
+{
+    GObject      parent;
+    ParoleProviderPlayer *player;
     GtkWidget *title;
     GtkWidget *artist;
     GtkWidget *album;
@@ -51,7 +62,13 @@ typedef struct
 #endif
     gboolean     block_edit_signal;
     
-} PluginData;
+};
+
+G_DEFINE_TYPE_WITH_CODE (StreamProperties, 
+			 stream_properties, 
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (PAROLE_TYPE_PROVIDER_PLUGIN, 
+						stream_properties_iface_init));
 
 enum
 {
@@ -62,7 +79,7 @@ enum
 };
 
 static void
-set_widget_text (PluginData *data, GtkWidget *widget, const gchar *text)
+set_widget_text (StreamProperties *data, GtkWidget *widget, const gchar *text)
 {
     data->block_edit_signal = TRUE;
 #ifdef HAVE_TAGLIBC
@@ -72,37 +89,38 @@ set_widget_text (PluginData *data, GtkWidget *widget, const gchar *text)
 #endif
     data->block_edit_signal = FALSE;
 }
-
+						
 #ifdef HAVE_TAGLIBC
 static void
-title_entry_edited (PluginData *data)
+title_entry_edited (StreamProperties *prop)
 {
-    if (!data->block_edit_signal)
-	data->changed |= TITLE_ENTRY_EDITED;
+    if (!prop->block_edit_signal)
+	prop->changed |= TITLE_ENTRY_EDITED;
 }
 
 static void
-artist_entry_edited (PluginData *data)
+artist_entry_edited (StreamProperties *prop)
 {
-    if (!data->block_edit_signal)
-	data->changed |= ARTIST_ENTRY_EDITED;
+    if (!prop->block_edit_signal)
+	prop->changed |= ARTIST_ENTRY_EDITED;
 }
 
 static void
-album_entry_edited (PluginData *data)
+album_entry_edited (StreamProperties *prop)
 {
-    if (!data->block_edit_signal)
-	data->changed |= ALBUM_ENTRY_EDITED;
+    if (!prop->block_edit_signal)
+	prop->changed |= ALBUM_ENTRY_EDITED;
 }
 
 static void
-year_entry_edited (PluginData *data)
+year_entry_edited (StreamProperties *prop)
 {
-    if (!data->block_edit_signal)
-	data->changed |= YEAR_ENTRY_EDITED;
+    if (!prop->block_edit_signal)
+	prop->changed |= YEAR_ENTRY_EDITED;
 }
 #endif
 
+
 static GtkWidget *
 new_tag_widget (void)
 {
@@ -117,7 +135,7 @@ new_tag_widget (void)
 }
 
 static void
-init_media_tag_entries (PluginData *data)
+init_media_tag_entries (StreamProperties *data)
 {
     set_widget_text (data, data->title, _("Unknown"));
     set_widget_text (data, data->artist, _("Unknown"));
@@ -144,7 +162,7 @@ init_media_tag_entries (PluginData *data)
 
 #ifdef HAVE_TAGLIBC
 static void
-save_media_tags (PluginData *data)
+save_media_tags (StreamProperties *data)
 {
     TagLib_Tag *tag;
     const gchar *entry;
@@ -206,13 +224,14 @@ save_media_tags (PluginData *data)
 
 #ifdef HAVE_TAGLIBC
 static void 
-save_media_clicked_cb (PluginData *data)
+save_media_clicked_cb (StreamProperties *data)
 {
     data->need_save = TRUE;
 }
 #endif
 
-static GtkWidget *create_properties_widget (PluginData *data)
+static GtkWidget *
+stream_properties_create_widgets (StreamProperties *prop)
 {
     PangoFontDescription *pfd;
     
@@ -241,9 +260,9 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    data->title = new_tag_widget ();
+    prop->title = new_tag_widget ();
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
-    gtk_container_add (GTK_CONTAINER (align), data->title);
+    gtk_container_add (GTK_CONTAINER (align), prop->title);
     gtk_table_attach (GTK_TABLE (table), align,
                       1, 2, i, i+1, 
                       GTK_SHRINK, GTK_SHRINK,
@@ -264,9 +283,9 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    data->artist = new_tag_widget ();
+    prop->artist = new_tag_widget ();
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
-    gtk_container_add (GTK_CONTAINER (align), data->artist);
+    gtk_container_add (GTK_CONTAINER (align), prop->artist);
     gtk_table_attach (GTK_TABLE (table), align,
                       1, 2, i, i+1, 
                       GTK_SHRINK, GTK_SHRINK,
@@ -287,9 +306,9 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    data->album = new_tag_widget ();
+    prop->album = new_tag_widget ();
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
-    gtk_container_add (GTK_CONTAINER (align), data->album);
+    gtk_container_add (GTK_CONTAINER (align), prop->album);
     gtk_table_attach (GTK_TABLE (table), align,
                       1, 2, i, i+1, 
                       GTK_SHRINK, GTK_SHRINK,
@@ -310,9 +329,9 @@ static GtkWidget *create_properties_widget (PluginData *data)
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    data->year = new_tag_widget ();
+    prop->year = new_tag_widget ();
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
-    gtk_container_add (GTK_CONTAINER (align), data->year);
+    gtk_container_add (GTK_CONTAINER (align), prop->year);
     gtk_table_attach (GTK_TABLE (table), align,
                       1, 2, i, i+1, 
                       GTK_SHRINK, GTK_SHRINK,
@@ -324,45 +343,45 @@ static GtkWidget *create_properties_widget (PluginData *data)
     gtk_box_pack_start (GTK_BOX (vbox), frame, FALSE, FALSE, 0);
     
 #ifdef HAVE_TAGLIBC
-    data->save = gtk_button_new_from_stock (GTK_STOCK_APPLY);
+    prop->save = gtk_button_new_from_stock (GTK_STOCK_APPLY);
     i++;
     align = gtk_alignment_new (0.0, 0.5, 0, 0);
-    gtk_container_add (GTK_CONTAINER (align), data->save);
+    gtk_container_add (GTK_CONTAINER (align), prop->save);
     gtk_table_attach (GTK_TABLE (table), align,
                       1, 2, i, i+1, 
                       GTK_SHRINK, GTK_SHRINK,
                       2, 8);
 
-    g_signal_connect_swapped (data->save, "clicked",
-			      G_CALLBACK (save_media_clicked_cb), data);
+    g_signal_connect_swapped (prop->save, "clicked",
+			      G_CALLBACK (save_media_clicked_cb), prop);
     
-    g_signal_connect_swapped (data->title, "changed",
-			      G_CALLBACK (title_entry_edited), data);
+    g_signal_connect_swapped (prop->title, "changed",
+			      G_CALLBACK (title_entry_edited), prop);
     
-    g_signal_connect_swapped (data->artist, "changed",
-			      G_CALLBACK (artist_entry_edited), data);
+    g_signal_connect_swapped (prop->artist, "changed",
+			      G_CALLBACK (artist_entry_edited), prop);
 			      
-    g_signal_connect_swapped (data->album, "changed",
-			      G_CALLBACK (album_entry_edited), data);
+    g_signal_connect_swapped (prop->album, "changed",
+			      G_CALLBACK (album_entry_edited), prop);
 			    
-    g_signal_connect_swapped (data->year, "changed",
-			      G_CALLBACK (year_entry_edited), data);
+    g_signal_connect_swapped (prop->year, "changed",
+			      G_CALLBACK (year_entry_edited), prop);
 			      
 #endif
-    
-    init_media_tag_entries (data);
+    init_media_tag_entries (prop);
     return vbox;
 }
 
 static void
-state_changed_cb (ParolePlugin *plugin, const ParoleStream *stream, ParoleState state, PluginData *data)
+state_changed_cb (ParoleProviderPlayer *player, const ParoleStream *stream, 
+		  ParoleState state, StreamProperties *prop)
 {
 #ifdef HAVE_TAGLIBC
-    save_media_tags (data);
+    save_media_tags (prop);
 #endif
 
     if ( state <= PAROLE_STATE_PLAYBACK_FINISHED )
-	init_media_tag_entries (data);
+	init_media_tag_entries (prop);
 }
 
 #ifdef HAVE_TAGLIBC
@@ -382,7 +401,7 @@ enable_tag_save (GtkWidget *widget)
 #endif
 
 static void
-tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *data)
+tag_message_cb (ParoleProviderPlayer *player, const ParoleStream *stream, StreamProperties *prop)
 {
     gchar *str = NULL;
 #ifdef HAVE_TAGLIBC
@@ -400,43 +419,43 @@ tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *da
 		  NULL);
     
 #ifdef HAVE_TAGLIBC
-    if ( data->filename )
+    if ( prop->filename )
     {
-	g_free (data->filename);
-	data->filename = NULL;
+	g_free (prop->filename);
+	prop->filename = NULL;
     }
     
-    if ( data->tag_file )
+    if ( prop->tag_file )
     {
-	taglib_file_free (data->tag_file);
-	data->tag_file = NULL;
+	taglib_file_free (prop->tag_file);
+	prop->tag_file = NULL;
     }
     
     if ( media_type == PAROLE_MEDIA_TYPE_LOCAL_FILE )
     {
-	data->filename = g_filename_from_uri (uri, NULL, &error);
+	prop->filename = g_filename_from_uri (uri, NULL, &error);
 	
 	if ( G_UNLIKELY (error) )
 	{
 	    g_critical ("Unablet to convert uri : %s to filename : %s", uri, error->message);
 	    g_error_free (error);
-	    disable_tag_save (data->save);
+	    disable_tag_save (prop->save);
 	}
 	else
 	{
-	    data->tag_file = taglib_file_new (data->filename);
+	    prop->tag_file = taglib_file_new (prop->filename);
 	    
-	    if ( !data->tag_file )
-		disable_tag_save (data->save);
+	    if ( !prop->tag_file )
+		disable_tag_save (prop->save);
 	    else
-		enable_tag_save (data->save);
+		enable_tag_save (prop->save);
 	}
     }
 #endif
 
     if ( str )
     {
-	set_widget_text (data, data->title, str);
+	set_widget_text (prop, prop->title, str);
 	g_free (str);
     }
     
@@ -446,7 +465,7 @@ tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *da
 		  
     if ( str )
     {
-	set_widget_text (data, data->artist, str);
+	set_widget_text (prop, prop->artist, str);
 	g_free (str);
     }
     
@@ -456,7 +475,7 @@ tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *da
 		  
     if ( str )
     {
-	set_widget_text (data, data->year, str);
+	set_widget_text (prop, prop->year, str);
 	g_free (str);
     }
     
@@ -466,7 +485,7 @@ tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *da
 		  
     if ( str )
     {
-	set_widget_text (data, data->album, str);
+	set_widget_text (prop, prop->album, str);
 	g_free (str);
     }
 
@@ -477,36 +496,53 @@ tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *da
     
 }
 
-static void
-free_data_cb (ParolePlugin *plugin, PluginData *data)
+static gboolean stream_properties_is_configurable (ParoleProviderPlugin *plugin)
 {
-    g_free (data);
+    return FALSE;
 }
 
-G_MODULE_EXPORT static void
-construct (ParolePlugin *plugin)
+static void
+stream_properties_set_player (ParoleProviderPlugin *plugin, ParoleProviderPlayer *player)
 {
-    PluginData *data;
+    StreamProperties *prop;
     GtkWidget *vbox;
     
-    data = g_new0 (PluginData, 1);
+    prop = STREAM_PROPERTIES_PROVIDER (plugin);
     
-    vbox = create_properties_widget (data);
+    prop->player = player;
     
-    parole_plugin_pack_widget (plugin, vbox, PAROLE_PLUGIN_CONTAINER_PLAYLIST);
+    vbox = stream_properties_create_widgets (prop);
     
-    g_signal_connect (plugin, "state_changed", 
-		      G_CALLBACK (state_changed_cb), data);
+    parole_provider_player_pack (player, vbox, _("Properties"), PAROLE_PLUGIN_CONTAINER_PLAYLIST);
+ 
+    g_signal_connect (player, "state_changed", 
+		      G_CALLBACK (state_changed_cb), prop);
 		      
-    g_signal_connect (plugin, "tag-message",
-		      G_CALLBACK (tag_message_cb), data);
+    g_signal_connect (player, "tag-message",
+		      G_CALLBACK (tag_message_cb), prop);
     
-    g_signal_connect (plugin, "free-data",
-		      G_CALLBACK (free_data_cb), data);
 }
 
-PAROLE_PLUGIN_CONSTRUCT (construct,                  /* Construct function */
-			 _("Properties"),            /* Title */
-			 _("Read media properties"), /* Description */
-			 "Copyright \302\251 2009 Ali Abdallah aliov at xfce.org",            /* Author */
-			 "http://goodies.xfce.org/projects/applications/parole"); /* Site */
+static void
+stream_properties_iface_init (ParoleProviderPluginIface *iface)
+{
+    iface->get_is_configurable = stream_properties_is_configurable;
+    iface->set_player = stream_properties_set_player;
+}
+
+static void stream_properties_class_init (StreamPropertiesClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+    
+    gobject_class->finalize = stream_properties_finalize;
+}
+
+static void stream_properties_init (StreamProperties *provider)
+{
+    provider->player = NULL;
+}
+
+static void stream_properties_finalize (GObject *object)
+{
+    G_OBJECT_CLASS (stream_properties_parent_class)->finalize (object);
+}
diff --git a/plugins/properties/stream-properties-provider.h b/plugins/properties/stream-properties-provider.h
new file mode 100644
index 0000000..1896757
--- /dev/null
+++ b/plugins/properties/stream-properties-provider.h
@@ -0,0 +1,42 @@
+/*
+ * * 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
+ */
+
+#ifndef STREAM_PROPERTIES_PROVIDER_H_
+#define STREAM_PROPERTIES_PROVIDER_H_
+
+#include <parole/parole.h>
+
+G_BEGIN_DECLS
+
+typedef struct _StreamPropertiesClass StreamPropertiesClass;
+typedef struct _StreamProperties      StreamProperties;
+
+#define STREAM_TYPE_PROPERTIES_PROVIDER             (stream_properties_get_type ())
+#define STREAM_PROPERTIES_PROVIDER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), STREAM_TYPE_PROPERTIES_PROVIDER, StreamProperties))
+#define STREAM_PROPERTIES_PROVIDER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), STREAM_TYPE_PROPERTIES_PROVIDER, StreamPropertiesClass))
+#define STREAM_IS_PROPERTIES_PROVIDER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), STREAM_TYPE_PROPERTIES_PROVIDER))
+#define STREAM_IS_PROPERTIES_PROVIDER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), STREAM_TYPE_PROPERTIES_PROVIDER))
+#define STREAM_PROPERTIES_PROVIDER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), STREAM_TYPE_PROPERTIES_PROVIDER, StreamPropertiesClass))
+
+GType stream_properties_get_type      	(void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /*STREAM_PROPERTIES_PROVIDER_H_*/
diff --git a/plugins/properties/stream-properties.desktop.in b/plugins/properties/stream-properties.desktop.in
new file mode 100644
index 0000000..32c5736
--- /dev/null
+++ b/plugins/properties/stream-properties.desktop.in
@@ -0,0 +1,6 @@
+[Parole Plugin]
+Module=stream-properties
+_Name=Stream Properties
+_Description=Read media properties
+Authors=Ali Abdallah aliov at xfce.org
+Website=http://goodies.xfce.org/projects/applications/parole
diff --git a/plugins/properties/Makefile.am b/plugins/sample/Makefile.am
similarity index 52%
copy from plugins/properties/Makefile.am
copy to plugins/sample/Makefile.am
index feae225..d7d3410 100644
--- a/plugins/properties/Makefile.am
+++ b/plugins/sample/Makefile.am
@@ -1,28 +1,27 @@
+noinst_LTLIBRARIES =				\
+	sample-plugin.la
+
 INCLUDES =					\
 	-I$(top_builddir)			\
 	-I$(top_srcdir)				\
-	-DG_LOG_DOMAIN=\"stream_properties\"    \
+	-DG_LOG_DOMAIN=\"sample_plugin\"    	\
 	-DLIBEXECDIR=\"$(libexecdir)\"		\
 	-DPACKAGE_LOCALE_DIR=\"$(localedir)\"
 
 pluginsdir = 					\
 	$(libdir)/parole-$(PAROLE_VERSION_API)
 
-plugins_LTLIBRARIES =				\
-	stream-properties.la
-
-stream_properties_la_SOURCES =			\
-	stream-properties.c
+sample_plugin_la_SOURCES =			\
+	sample-plugin.c				\
+	sample-provider.c			\
+	sample-provider.h
 
-stream_properties_la_CFLAGS =			\
+sample_plugin_la_CFLAGS =			\
 	$(PLATFORM_CFLAGS)			\
 	$(GTK_CFLAGS)				\
-	$(TAGLIBC_CFLAGS)
-
-stream_properties_la_LIBADD =			\
-	$(TAGLIBC_LIBS)
+	$(LIBXFCE4UTIL_CFLAGS)
 
-stream_properties_la_LDFLAGS =			\
+sample_plugin_la_LDFLAGS =			\
 	-avoid-version				\
 	-export-dynamic				\
 	-module					\
diff --git a/src/parole-builder.h b/plugins/sample/sample-plugin.c
similarity index 62%
copy from src/parole-builder.h
copy to plugins/sample/sample-plugin.c
index 3f0cbf0..5d7b6a2 100644
--- a/src/parole-builder.h
+++ b/plugins/sample/sample-plugin.c
@@ -18,19 +18,27 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef __PAROLE_BUILDER_H
-#define __PAROLE_BUILDER_H
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <glib-object.h>
-#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
 
-G_BEGIN_DECLS
+#include "sample-provider.h"
 
-GtkBuilder       	       *parole_builder_get_main_interface       (void);
+G_MODULE_EXPORT GType	parole_plugin_initialize (ParoleProviderPlugin *plugin);
+						  
+G_MODULE_EXPORT void	parole_plugin_shutdown   (void);
 
-GtkBuilder		       *parole_builder_new_from_string 		(const gchar *ui,
-									 gsize length);
+G_MODULE_EXPORT GType
+parole_plugin_initialize (ParoleProviderPlugin *plugin)
+{
+    xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+    return SAMPLE_TYPE_PROVIDER;
+}
 
-G_END_DECLS
-
-#endif /* __PAROLE_BUILDER_H */
+G_MODULE_EXPORT void
+parole_plugin_shutdown (void)
+{
+    
+}
diff --git a/plugins/sample/sample-provider.c b/plugins/sample/sample-provider.c
new file mode 100644
index 0000000..57bf2ee
--- /dev/null
+++ b/plugins/sample/sample-provider.c
@@ -0,0 +1,86 @@
+/*
+ * * 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 <glib/gi18n.h>
+
+#include "sample-provider.h"
+
+static void   sample_provider_iface_init 	   (ParoleProviderPluginIface *iface);
+static void   sample_provider_finalize             (GObject 	              *object);
+
+
+struct _SampleProviderClass
+{
+    GObjectClass parent_class;
+};
+
+struct _SampleProvider
+{
+    GObject      parent;
+    ParoleProviderPlayer *player;
+};
+
+G_DEFINE_TYPE_WITH_CODE (SampleProvider, 
+			 sample_provider, 
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (PAROLE_TYPE_PROVIDER_PLUGIN, 
+						sample_provider_iface_init));
+							  
+static gboolean sample_provider_is_configurable (ParoleProviderPlugin *plugin)
+{
+    return FALSE;
+}
+
+static void
+sample_provider_set_player (ParoleProviderPlugin *plugin, ParoleProviderPlayer *player)
+{
+    SampleProvider *provider;
+    provider = SAMPLE_PROVIDER (plugin);
+    
+    provider->player = player;
+}
+
+static void
+sample_provider_iface_init (ParoleProviderPluginIface *iface)
+{
+    iface->get_is_configurable = sample_provider_is_configurable;
+    iface->set_player = sample_provider_set_player;
+}
+
+static void sample_provider_class_init (SampleProviderClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+    
+    gobject_class->finalize = sample_provider_finalize;
+}
+
+static void sample_provider_init (SampleProvider *provider)
+{
+    provider->player = NULL;
+}
+
+static void sample_provider_finalize (GObject *object)
+{
+    G_OBJECT_CLASS (sample_provider_parent_class)->finalize (object);
+}
diff --git a/plugins/sample/sample-provider.h b/plugins/sample/sample-provider.h
new file mode 100644
index 0000000..21e16c9
--- /dev/null
+++ b/plugins/sample/sample-provider.h
@@ -0,0 +1,42 @@
+/*
+ * * 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
+ */
+
+#ifndef SAMPLE_PROVIDER_H_
+#define SAMPLE_PROVIDER_H_
+
+#include <parole/parole.h>
+
+G_BEGIN_DECLS
+
+typedef struct _SampleProviderClass SampleProviderClass;
+typedef struct _SampleProvider      SampleProvider;
+
+#define SAMPLE_TYPE_PROVIDER             (sample_provider_get_type ())
+#define SAMPLE_PROVIDER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), SAMPLE_TYPE_PROVIDER, SampleProvider))
+#define SAMPLE_PROVIDER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), SAMPLE_TYPE_PROVIDER, SampleProviderClass))
+#define SAMPLE_IS_PROVIDER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), SAMPLE_TYPE_PROVIDER))
+#define SAMPLE_IS_PROVIDER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), SAMPLE_TYPE_PROVIDER))
+#define SAMPLE_PROVIDER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), SAMPLE_TYPE_PROVIDER, SampleProviderClass))
+
+GType sample_provider_get_type      	(void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /*SAMPLE_PROVIDER_H_*/
diff --git a/plugins/tray/Makefile.am b/plugins/tray/Makefile.am
index 06e3c66..a240229 100644
--- a/plugins/tray/Makefile.am
+++ b/plugins/tray/Makefile.am
@@ -12,7 +12,9 @@ plugins_LTLIBRARIES =				\
 	tray-icon.la
 
 tray_icon_la_SOURCES =				\
-	tray-icon.c
+	tray-plugin.c				\
+	tray-provider.c				\
+	tray-provider.h
 
 tray_icon_la_CFLAGS =				\
 	$(PLATFORM_CFLAGS)			\
@@ -28,4 +30,18 @@ tray_icon_la_LDFLAGS =				\
 	$(PLATFORM_LDFLAGS)
 
 tray_icon_la_LIBADD =				\
-	$(LIBNOTIFY_LIBS)
\ No newline at end of file
+	$(LIBNOTIFY_LIBS)
+
+#
+# .desktop file
+#
+desktop_in_files = system-tray.desktop.in
+desktopdir = $(datadir)/parole/parole-plugins-$(PAROLE_VERSION_API)
+desktop_DATA =  $(desktop_in_files:.desktop.in=.desktop)
+ at INTLTOOL_DESKTOP_RULE@
+
+EXTRA_DIST = 		  	\
+	$(desktop_in_files)
+    
+DISTCLEANFILES = 		\
+	$(desktop_DATA)
\ No newline at end of file
diff --git a/plugins/tray/system-tray.desktop.in b/plugins/tray/system-tray.desktop.in
new file mode 100644
index 0000000..8afbd6d
--- /dev/null
+++ b/plugins/tray/system-tray.desktop.in
@@ -0,0 +1,6 @@
+[Parole Plugin]
+Module=tray-icon
+_Name=Tray icon
+_Description=Show icon in the system tray
+Authors=Ali Abdallah aliov at xfce.org
+Website=http://goodies.xfce.org/projects/applications/parole
diff --git a/src/parole-builder.h b/plugins/tray/tray-plugin.c
similarity index 62%
copy from src/parole-builder.h
copy to plugins/tray/tray-plugin.c
index 3f0cbf0..595e5c6 100644
--- a/src/parole-builder.h
+++ b/plugins/tray/tray-plugin.c
@@ -18,19 +18,27 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef __PAROLE_BUILDER_H
-#define __PAROLE_BUILDER_H
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <glib-object.h>
-#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
 
-G_BEGIN_DECLS
+#include "tray-provider.h"
 
-GtkBuilder       	       *parole_builder_get_main_interface       (void);
+G_MODULE_EXPORT GType	parole_plugin_initialize (ParoleProviderPlugin *plugin);
+						  
+G_MODULE_EXPORT void	parole_plugin_shutdown   (void);
 
-GtkBuilder		       *parole_builder_new_from_string 		(const gchar *ui,
-									 gsize length);
+G_MODULE_EXPORT GType
+parole_plugin_initialize (ParoleProviderPlugin *plugin)
+{
+    xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+    return TRAY_TYPE_PROVIDER;
+}
 
-G_END_DECLS
-
-#endif /* __PAROLE_BUILDER_H */
+G_MODULE_EXPORT void
+parole_plugin_shutdown (void)
+{
+    
+}
diff --git a/plugins/tray/tray-icon.c b/plugins/tray/tray-provider.c
similarity index 64%
rename from plugins/tray/tray-icon.c
rename to plugins/tray/tray-provider.c
index b56b57d..2c13ae1 100644
--- a/plugins/tray/tray-icon.c
+++ b/plugins/tray/tray-provider.c
@@ -34,11 +34,23 @@
 #include <libxfcegui4/libxfcegui4.h>
 #include <libxfce4util/libxfce4util.h>
 
+#include "tray-provider.h"
+
 #define RESOURCE_FILE 	"xfce4/parole/parole-plugins/tray.rc"
 
-typedef struct
+static void   tray_provider_iface_init 	   (ParoleProviderPluginIface *iface);
+static void   tray_provider_finalize             (GObject 	              *object);
+
+
+struct _TrayProviderClass
 {
-    ParolePlugin  *plugin;
+    GObjectClass parent_class;
+};
+
+struct _TrayProvider
+{
+    GObject      parent;
+    ParoleProviderPlayer *player;
     GtkStatusIcon *tray;
     GtkWidget     *window;
     gulong         sig;
@@ -50,52 +62,57 @@ typedef struct
 #endif
     ParoleState state;
     GtkWidget     *menu;
-    
-} PluginData;
+};
 
+G_DEFINE_TYPE_WITH_CODE (TrayProvider, 
+			 tray_provider, 
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (PAROLE_TYPE_PROVIDER_PLUGIN, 
+						tray_provider_iface_init));
+	
 static void
-menu_selection_done_cb (PluginData *data)
+menu_selection_done_cb (TrayProvider *tray)
 {
-    gtk_widget_destroy (data->menu);
-    data->menu = NULL;
+    gtk_widget_destroy (tray->menu);
+    tray->menu = NULL;
 }
 
 static void
-exit_activated_cb (PluginData *data)
+exit_activated_cb (TrayProvider *tray)
 {
     GdkEventAny ev;
     
-    menu_selection_done_cb (data);
+    menu_selection_done_cb (tray);
     
     ev.type = GDK_DELETE;
-    ev.window = data->window->window;
+    ev.window = tray->window->window;
     ev.send_event = TRUE;
 
-    g_signal_handler_block (data->window, data->sig);
+    g_signal_handler_block (tray->window, tray->sig);
     gtk_main_do_event ((GdkEvent *) &ev);
 }
 
 static void
-play_pause_activated_cb (PluginData *data)
+play_pause_activated_cb (TrayProvider *tray)
 {
-    menu_selection_done_cb (data);
+    menu_selection_done_cb (tray);
     
-    if ( data->state == PAROLE_STATE_PLAYING )
-	parole_plugin_pause_playback (data->plugin);
-    else if ( data->state == PAROLE_STATE_PAUSED )
-	parole_plugin_resume_playback (data->plugin);
+    if ( tray->state == PAROLE_STATE_PLAYING )
+	parole_provider_player_pause (tray->player);
+    else if ( tray->state == PAROLE_STATE_PAUSED )
+	parole_provider_player_resume (tray->player);
 }   
   
 static void
-stop_activated_cb (PluginData *data)
+stop_activated_cb (TrayProvider *tray)
 {
-    menu_selection_done_cb (data);
-    parole_plugin_stop_playback (data->plugin);
+    menu_selection_done_cb (tray);
+    parole_provider_player_stop (tray->player);
 }
 
 static void
 popup_menu_cb (GtkStatusIcon *icon, guint button, 
-               guint activate_time, PluginData *data)
+               guint activate_time, TrayProvider *tray)
 {
     GtkWidget *menu, *mi;
     
@@ -104,20 +121,20 @@ popup_menu_cb (GtkStatusIcon *icon, guint button,
     /*
      * Play pause.
      */
-    mi = gtk_image_menu_item_new_from_stock (data->state == PAROLE_STATE_PLAYING ? GTK_STOCK_MEDIA_PAUSE : 
+    mi = gtk_image_menu_item_new_from_stock (tray->state == PAROLE_STATE_PLAYING ? GTK_STOCK_MEDIA_PAUSE : 
 					     GTK_STOCK_MEDIA_PLAY, NULL);
     gtk_widget_set_sensitive (mi, TRUE);
     gtk_widget_show (mi);
-    g_signal_connect_swapped (mi, "activate", G_CALLBACK (play_pause_activated_cb), data);
+    g_signal_connect_swapped (mi, "activate", G_CALLBACK (play_pause_activated_cb), tray);
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
     
     /*
      * Stop
      */
     mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_MEDIA_STOP, NULL);
-    gtk_widget_set_sensitive (mi, data->state >= PAROLE_STATE_PAUSED);
+    gtk_widget_set_sensitive (mi, tray->state >= PAROLE_STATE_PAUSED);
     gtk_widget_show (mi);
-    g_signal_connect_swapped (mi, "activate", G_CALLBACK (stop_activated_cb), data);
+    g_signal_connect_swapped (mi, "activate", G_CALLBACK (stop_activated_cb), tray);
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
     
     /*
@@ -133,7 +150,7 @@ popup_menu_cb (GtkStatusIcon *icon, guint button,
     mi = gtk_image_menu_item_new_from_stock (GTK_STOCK_QUIT, NULL);
     gtk_widget_set_sensitive (mi, TRUE);
     gtk_widget_show (mi);
-    g_signal_connect_swapped (mi, "activate", G_CALLBACK (exit_activated_cb), data);
+    g_signal_connect_swapped (mi, "activate", G_CALLBACK (exit_activated_cb), tray);
     gtk_menu_shell_append (GTK_MENU_SHELL (menu), mi);
     
     gtk_menu_popup (GTK_MENU (menu), NULL, NULL,
@@ -141,39 +158,29 @@ popup_menu_cb (GtkStatusIcon *icon, guint button,
                     icon, button, activate_time);
 
     g_signal_connect_swapped (menu, "selection-done",
-			      G_CALLBACK (menu_selection_done_cb), data);
-
-    data->menu = menu;
-}
+			      G_CALLBACK (menu_selection_done_cb), tray);
 
-static void
-free_data_cb (ParolePlugin *plugin, PluginData *data)
-{
-    if ( GTK_IS_WIDGET (data->window) && g_signal_handler_is_connected (data->window, data->sig) )
-	g_signal_handler_disconnect (data->window, data->sig);
- 
-    g_object_unref (G_OBJECT (data->tray));
-    g_free (data);
+    tray->menu = menu;
 }
 
 static void
-tray_activate_cb (GtkStatusIcon *tray, PluginData *data)
+tray_activate_cb (GtkStatusIcon *tray_icon, TrayProvider *tray)
 {
-    if ( GTK_WIDGET_VISIBLE (data->window) )
-	gtk_widget_hide (data->window);
+    if ( GTK_WIDGET_VISIBLE (tray->window) )
+	gtk_widget_hide (tray->window);
     else
-	gtk_widget_show (data->window);
+	gtk_widget_show (tray->window);
 }
 
 #ifdef HAVE_LIBNOTIFY
 static void
-notification_closed_cb (NotifyNotification *n, PluginData *data)
+notification_closed_cb (NotifyNotification *n, TrayProvider *tray)
 {
-    data->n = NULL;
+    tray->n = NULL;
 }
 
 static void
-notify_playing (PluginData *data, const ParoleStream *stream)
+notify_playing (TrayProvider *tray, const ParoleStream *stream)
 {
     GdkPixbuf *pix;
     gboolean live, has_audio, has_video;
@@ -182,7 +189,7 @@ notify_playing (PluginData *data, const ParoleStream *stream)
     gdouble duration;
     ParoleMediaType media_type;
     
-    if ( !data->notify || !data->enabled)
+    if ( !tray->notify || !tray->enabled)
 	return;
     
     g_object_get (G_OBJECT (stream), 
@@ -221,42 +228,42 @@ notify_playing (PluginData *data, const ParoleStream *stream)
     
     message = g_strdup_printf ("%s %s %s %4.2f", _("<b>Playing:</b>"), title, _("<b>Duration:</b>"), duration);
     
-    data->n = notify_notification_new (title, message, NULL, NULL);
+    tray->n = notify_notification_new (title, message, NULL, NULL);
     g_free (title);
     g_free (message);
     
-    notify_notification_attach_to_status_icon (data->n, data->tray);
+    notify_notification_attach_to_status_icon (tray->n, tray->tray);
     pix = xfce_themed_icon_load (has_video ? "video" : "audio-x-generic", 48);
     if ( pix )
     {
-	notify_notification_set_icon_from_pixbuf (data->n, pix);
+	notify_notification_set_icon_from_pixbuf (tray->n, pix);
 	g_object_unref (pix);
     }
-    notify_notification_set_urgency (data->n, NOTIFY_URGENCY_LOW);
-    notify_notification_set_timeout (data->n, 5000);
+    notify_notification_set_urgency (tray->n, NOTIFY_URGENCY_LOW);
+    notify_notification_set_timeout (tray->n, 5000);
     
-    notify_notification_show (data->n, NULL);
-    g_signal_connect (data->n, "closed",
-		      G_CALLBACK (notification_closed_cb), data);
+    notify_notification_show (tray->n, NULL);
+    g_signal_connect (tray->n, "closed",
+		      G_CALLBACK (notification_closed_cb), tray);
 		      
-    data->notify = FALSE;
+    tray->notify = FALSE;
 }
 #endif
 
 static void
-state_changed_cb (ParolePlugin *plugin, const ParoleStream *stream, ParoleState state, PluginData *data)
+state_changed_cb (ParoleProviderPlayer *player, const ParoleStream *stream, ParoleState state, TrayProvider *tray)
 {
 #ifdef HAVE_LIBNOTIFY
     gboolean tag;
 #endif
 
-    data->state = state;
+    tray->state = state;
     
-    if ( data->menu )
+    if ( tray->menu )
     {
-	gtk_widget_destroy (data->menu);
-	data->menu = NULL;
-	g_signal_emit_by_name (G_OBJECT (data->tray), "popup-menu", 0, gtk_get_current_event_time ());
+	gtk_widget_destroy (tray->menu);
+	tray->menu = NULL;
+	g_signal_emit_by_name (G_OBJECT (tray->tray), "popup-menu", 0, gtk_get_current_event_time ());
     }
     
 #ifdef HAVE_LIBNOTIFY
@@ -268,31 +275,31 @@ state_changed_cb (ParolePlugin *plugin, const ParoleStream *stream, ParoleState
 		      NULL);
 
 	if ( tag )
-	    notify_playing (data, stream);
+	    notify_playing (tray, stream);
     }
     else if ( state <= PAROLE_STATE_PAUSED )
     {
-	if ( data->n )
+	if ( tray->n )
 	{
-	    notify_notification_close (data->n, NULL);
-	    data->n = NULL;
+	    notify_notification_close (tray->n, NULL);
+	    tray->n = NULL;
 	}
 	if ( state < PAROLE_STATE_PAUSED )
-	    data->notify = TRUE;
+	    tray->notify = TRUE;
     }
 #endif
 }
 
 static void
-tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *data)
+tag_message_cb (ParoleProviderPlayer *player, const ParoleStream *stream, TrayProvider *tray)
 {
 #ifdef HAVE_LIBNOTIFY
     ParoleState state;
     
-    state = parole_plugin_get_state (plugin);
+    state = parole_provider_player_get_state (player);
     
     if (state == PAROLE_STATE_PLAYING )
-	notify_playing (data, stream);
+	notify_playing (tray, stream);
     
 #endif
 }
@@ -341,18 +348,18 @@ notify_enabled (void)
 }
 
 static void
-notify_toggled_cb (GtkToggleButton *bt, PluginData *data)
+notify_toggled_cb (GtkToggleButton *bt, TrayProvider *tray)
 {
     gboolean active;
     active = gtk_toggle_button_get_active (bt);
-    data->enabled = active;
+    tray->enabled = active;
     
     write_entry_bool ("NOTIFY", active);
 }
 #endif /*HAVE_LIBNOTIFY*/
 
 static void
-hide_on_delete_toggled_cb (GtkWidget *widget, gpointer data)
+hide_on_delete_toggled_cb (GtkWidget *widget, gpointer tray)
 {
     gboolean toggled;
     toggled = gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget));
@@ -360,7 +367,7 @@ hide_on_delete_toggled_cb (GtkWidget *widget, gpointer data)
 }
 
 static void
-configure_cb (ParolePlugin *plugin, GtkWidget *widget, PluginData *data)
+configure_plugin (TrayProvider *tray, GtkWidget *widget)
 {
     GtkWidget *dialog;
     GtkWidget *content_area;
@@ -381,9 +388,9 @@ configure_cb (ParolePlugin *plugin, GtkWidget *widget, PluginData *data)
     
 #ifdef HAVE_LIBNOTIFY    
     check = gtk_check_button_new_with_label (_("Enable notification"));
-    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), data->enabled);
+    gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (check), tray->enabled);
     g_signal_connect (check, "toggled",
-		      G_CALLBACK (notify_toggled_cb), data);
+		      G_CALLBACK (notify_toggled_cb), tray);
     gtk_box_pack_start_defaults (GTK_BOX (content_area), check) ;
     
 #endif /*HAVE_LIBNOTIFY*/
@@ -414,7 +421,7 @@ action_on_hide_confirmed_cb (GtkWidget *widget, gpointer data)
 }
 
 static gboolean
-delete_event_cb (GtkWidget *widget, GdkEvent *ev, PluginData *data)
+delete_event_cb (GtkWidget *widget, GdkEvent *ev, TrayProvider *tray)
 {
     GtkWidget *dialog, *check, *content_area, *label;
     GtkWidget *quit, *minimize, *cancel, *img;
@@ -484,64 +491,106 @@ delete_event_cb (GtkWidget *widget, GdkEvent *ev, PluginData *data)
     return ret_val;
 }
 
-G_MODULE_EXPORT static void
-construct (ParolePlugin *plugin)
+static gboolean tray_provider_is_configurable (ParoleProviderPlugin *plugin)
 {
-    PluginData *data;
+#ifdef HAVE_LIBNOTIFY
+    return TRUE;
+#else
+    return FALSE;
+#endif
+}
+
+static void
+tray_provider_set_player (ParoleProviderPlugin *plugin, ParoleProviderPlayer *player)
+{
+    TrayProvider *tray;
     GdkPixbuf *pix;
     
-    data = g_new0 (PluginData, 1);
-
-    data->state = PAROLE_STATE_STOPPED;
+    tray = TRAY_PROVIDER (plugin);
+    
+    tray->player = player;
     
-    data->window = parole_plugin_get_main_window (plugin);
+    tray->state = PAROLE_STATE_STOPPED;
     
-    data->tray = gtk_status_icon_new ();
-    data->plugin = plugin;
-    data->menu = NULL;
+    tray->window = parole_provider_player_get_main_window (player);
+    
+    tray->tray = gtk_status_icon_new ();
+    tray->player = player;
+    tray->menu = NULL;
 
 #ifdef HAVE_LIBNOTIFY
-    data->n = NULL;
+    tray->n = NULL;
     notify_init ("parole-tray-icon");
-    data->enabled = notify_enabled ();
-    data->notify = TRUE;
+    tray->enabled = notify_enabled ();
+    tray->notify = TRUE;
 #endif
     
     pix = xfce_themed_icon_load ("parole", 48);
     
     if ( pix )
     {
-	gtk_status_icon_set_from_pixbuf (data->tray, pix);
+	gtk_status_icon_set_from_pixbuf (tray->tray, pix);
 	g_object_unref (pix);
     }
     
-    g_signal_connect (data->tray, "popup-menu",
-		      G_CALLBACK (popup_menu_cb), data);
+    g_signal_connect (tray->tray, "popup-menu",
+		      G_CALLBACK (popup_menu_cb), tray);
     
-    g_signal_connect (data->tray, "activate",
-		      G_CALLBACK (tray_activate_cb), data);
+    g_signal_connect (tray->tray, "activate",
+		      G_CALLBACK (tray_activate_cb), tray);
     
-    data->sig = g_signal_connect (data->window, "delete-event",
+    tray->sig = g_signal_connect (tray->window, "delete-event",
 			          G_CALLBACK (delete_event_cb), NULL);
 				  
-    g_signal_connect (plugin, "free-data",
-		      G_CALLBACK (free_data_cb), data);
-		      
-    g_signal_connect (plugin, "state_changed", 
-		      G_CALLBACK (state_changed_cb), data);
+    g_signal_connect (player, "state_changed", 
+		      G_CALLBACK (state_changed_cb), tray);
 		      
-    g_signal_connect (plugin, "tag-message",
-		      G_CALLBACK (tag_message_cb), data);
+    g_signal_connect (player, "tag-message",
+		      G_CALLBACK (tag_message_cb), tray);
 
+}
+
+static void
+tray_provider_configure (ParoleProviderPlugin *provider, GtkWidget *parent)
+{
+    TrayProvider *tray;
+    
+    tray = TRAY_PROVIDER (provider);
+    configure_plugin (tray, parent);
+}
+
+static void
+tray_provider_iface_init (ParoleProviderPluginIface *iface)
+{
+    iface->get_is_configurable = tray_provider_is_configurable;
+    iface->set_player = tray_provider_set_player;
 #ifdef HAVE_LIBNOTIFY
-    parole_plugin_set_is_configurable (plugin, TRUE);
-    g_signal_connect (plugin, "configure", 
-		      G_CALLBACK (configure_cb), data);
+    iface->configure = tray_provider_configure;
 #endif
 }
 
-PAROLE_PLUGIN_CONSTRUCT (construct,                  	    /* Construct function */
-			 _("Tray icon"),            	    /* Title */
-			 _("Show icon in the system tray"), /* Description */
-			 "Copyright \302\251 2009 Ali Abdallah aliov at xfce.org", /* Author */
-			 "http://goodies.xfce.org/projects/applications/parole"); /* Site */
+static void tray_provider_class_init (TrayProviderClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+    
+    gobject_class->finalize = tray_provider_finalize;
+}
+
+static void tray_provider_init (TrayProvider *provider)
+{
+    provider->player = NULL;
+}
+
+static void tray_provider_finalize (GObject *object)
+{
+    TrayProvider *tray;
+    
+    tray = TRAY_PROVIDER (object);
+    
+    if ( GTK_IS_WIDGET (tray->window) && g_signal_handler_is_connected (tray->window, tray->sig) )
+	g_signal_handler_disconnect (tray->window, tray->sig);
+ 
+    g_object_unref (G_OBJECT (tray->tray));
+    
+    G_OBJECT_CLASS (tray_provider_parent_class)->finalize (object);
+}
diff --git a/plugins/tray/tray-provider.h b/plugins/tray/tray-provider.h
new file mode 100644
index 0000000..fa429b4
--- /dev/null
+++ b/plugins/tray/tray-provider.h
@@ -0,0 +1,42 @@
+/*
+ * * 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
+ */
+
+#ifndef TRAY_PROVIDER_H_
+#define TRAY_PROVIDER_H_
+
+#include <parole/parole.h>
+
+G_BEGIN_DECLS
+
+typedef struct _TrayProviderClass TrayProviderClass;
+typedef struct _TrayProvider      TrayProvider;
+
+#define TRAY_TYPE_PROVIDER             (tray_provider_get_type ())
+#define TRAY_PROVIDER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), TRAY_TYPE_PROVIDER, TrayProvider))
+#define TRAY_PROVIDER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), TRAY_TYPE_PROVIDER, TrayProviderClass))
+#define TRAY_IS_PROVIDER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), TRAY_TYPE_PROVIDER))
+#define TRAY_IS_PROVIDER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), TRAY_TYPE_PROVIDER))
+#define TRAY_PROVIDER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), TRAY_TYPE_PROVIDER, TrayProviderClass))
+
+GType tray_provider_get_type      	(void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /*TRAY_PROVIDER_H_*/
diff --git a/plugins/window-title/Makefile.am b/plugins/window-title/Makefile.am
index e3a1bd0..888a2db 100644
--- a/plugins/window-title/Makefile.am
+++ b/plugins/window-title/Makefile.am
@@ -12,14 +12,31 @@ plugins_LTLIBRARIES =				\
 	window-title.la
 
 window_title_la_SOURCES =			\
-	window-title.c
+	window-title-plugin.c			\
+	window-title-provider.c			\
+	window-title-provider.h
 
 window_title_la_CFLAGS =			\
 	$(PLATFORM_CFLAGS)			\
-	$(GTK_CFLAGS)
+	$(GTK_CFLAGS)				\
+	$(LIBXFCE4UTIL_CFLAGS)
 
 window_title_la_LDFLAGS =			\
 	-avoid-version				\
 	-export-dynamic				\
 	-module					\
 	$(PLATFORM_LDFLAGS)
+
+#
+# .desktop file
+#
+desktop_in_files = window-title.desktop.in
+desktopdir = $(datadir)/parole/parole-plugins-$(PAROLE_VERSION_API)
+desktop_DATA =  $(desktop_in_files:.desktop.in=.desktop)
+ at INTLTOOL_DESKTOP_RULE@
+
+EXTRA_DIST = 		  	\
+	$(desktop_in_files)
+    
+DISTCLEANFILES = 		\
+	$(desktop_DATA)
\ No newline at end of file
diff --git a/src/parole-builder.h b/plugins/window-title/window-title-plugin.c
similarity index 61%
copy from src/parole-builder.h
copy to plugins/window-title/window-title-plugin.c
index 3f0cbf0..917fd5e 100644
--- a/src/parole-builder.h
+++ b/plugins/window-title/window-title-plugin.c
@@ -18,19 +18,28 @@
  * Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA  02110-1301  USA
  */
 
-#ifndef __PAROLE_BUILDER_H
-#define __PAROLE_BUILDER_H
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
 
-#include <glib-object.h>
-#include <gtk/gtk.h>
+#include <libxfce4util/libxfce4util.h>
 
-G_BEGIN_DECLS
+#include "window-title-provider.h"
 
-GtkBuilder       	       *parole_builder_get_main_interface       (void);
+G_MODULE_EXPORT GType	parole_plugin_initialize (ParoleProviderPlugin *plugin);
+						  
+G_MODULE_EXPORT void	parole_plugin_shutdown   (void);
 
-GtkBuilder		       *parole_builder_new_from_string 		(const gchar *ui,
-									 gsize length);
+G_MODULE_EXPORT GType
+parole_plugin_initialize (ParoleProviderPlugin *plugin)
+{
+    xfce_textdomain (GETTEXT_PACKAGE, PACKAGE_LOCALE_DIR, "UTF-8");
+    
+    return WINDOW_TYPE_TITLE_PROVIDER;
+}
 
-G_END_DECLS
-
-#endif /* __PAROLE_BUILDER_H */
+G_MODULE_EXPORT void
+parole_plugin_shutdown (void)
+{
+    
+}
diff --git a/plugins/window-title/window-title-provider.c b/plugins/window-title/window-title-provider.c
new file mode 100644
index 0000000..e2b92ea
--- /dev/null
+++ b/plugins/window-title/window-title-provider.c
@@ -0,0 +1,146 @@
+/*
+ * * 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 <libxfce4util/libxfce4util.h>
+
+#include "window-title-provider.h"
+
+static void   window_title_provider_iface_init 	   	(ParoleProviderPluginIface *iface);
+static void   window_title_provider_finalize            (GObject 	           *object);
+
+
+struct _WindowTitleProviderClass
+{
+    GObjectClass parent_class;
+};
+
+struct _WindowTitleProvider
+{
+    GObject      	  parent;
+    
+    ParoleProviderPlayer *player;
+    GtkWidget		 *window;
+};
+
+
+G_DEFINE_TYPE_WITH_CODE (WindowTitleProvider,
+			 window_title_provider,
+			 G_TYPE_OBJECT,
+			 G_IMPLEMENT_INTERFACE (PAROLE_TYPE_PROVIDER_PLUGIN,
+						window_title_provider_iface_init));
+
+
+
+static void
+window_title_provider_set_default_window_title (GtkWidget *window)
+{
+    gtk_window_set_title (GTK_WINDOW (window), _("Parole Media Player"));
+}
+
+static void
+window_title_provider_set_stream_title (GtkWidget *window, const ParoleStream *stream)
+{
+    gchar *title = NULL;
+    
+    g_object_get (G_OBJECT (stream),
+		  "title", &title,
+		  NULL);
+		  
+    if ( title )
+    {
+	gtk_window_set_title (GTK_WINDOW (window), title);
+	g_free (title);
+    }
+}
+
+static void
+window_title_provider_state_changed_cb (ParoleProviderPlayer *player, const ParoleStream *stream, 
+				        ParoleState state, WindowTitleProvider *provider)
+{
+    if ( state < PAROLE_STATE_PAUSED )
+	window_title_provider_set_default_window_title (provider->window);
+    else
+	window_title_provider_set_stream_title (provider->window, stream);
+}
+
+static void
+window_title_provider_tag_message_cb (ParoleProviderPlayer *player, const ParoleStream *stream, WindowTitleProvider *provider)
+{
+    window_title_provider_set_stream_title (provider->window, stream);
+}
+						
+static gboolean window_title_provider_is_configurable (ParoleProviderPlugin *plugin)
+{
+    return FALSE;
+}
+
+static void
+window_title_provider_set_player (ParoleProviderPlugin *plugin, ParoleProviderPlayer *player)
+{
+    WindowTitleProvider *provider;
+    provider = WINDOW_TITLE_PROVIDER (plugin);
+    
+    provider->player = player;
+    
+    provider->window = parole_provider_player_get_main_window (player);
+    
+    g_signal_connect (player, "state-changed", 
+		      G_CALLBACK (window_title_provider_state_changed_cb), provider);
+		      
+    g_signal_connect (player, "tag-message",
+		      G_CALLBACK (window_title_provider_tag_message_cb), provider);
+}
+
+static void
+window_title_provider_iface_init (ParoleProviderPluginIface *iface)
+{
+    iface->get_is_configurable = window_title_provider_is_configurable;
+    iface->set_player = window_title_provider_set_player;
+}
+
+static void window_title_provider_class_init (WindowTitleProviderClass *klass)
+{
+    GObjectClass *gobject_class = G_OBJECT_CLASS (klass);
+    
+    gobject_class->finalize = window_title_provider_finalize;
+}
+
+static void window_title_provider_init (WindowTitleProvider *provider)
+{
+    provider->player = NULL;
+}
+
+static void window_title_provider_finalize (GObject *object)
+{
+    WindowTitleProvider *provider;
+    
+    provider = WINDOW_TITLE_PROVIDER (object);
+    
+    g_debug ("Finalized");
+    
+    if ( provider->window && GTK_IS_WINDOW (provider->window) )
+	window_title_provider_set_default_window_title (provider->window);
+    
+    G_OBJECT_CLASS (window_title_provider_parent_class)->finalize (object);
+}
diff --git a/plugins/window-title/window-title-provider.h b/plugins/window-title/window-title-provider.h
new file mode 100644
index 0000000..dd0bdd0
--- /dev/null
+++ b/plugins/window-title/window-title-provider.h
@@ -0,0 +1,42 @@
+/*
+ * * 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
+ */
+
+#ifndef WINDOW_TITLE_PROVIDER_H_
+#define WINDOW_TITLE_PROVIDER_H_
+
+#include <parole/parole.h>
+
+G_BEGIN_DECLS
+
+typedef struct _WindowTitleProviderClass WindowTitleProviderClass;
+typedef struct _WindowTitleProvider      WindowTitleProvider;
+
+#define WINDOW_TYPE_TITLE_PROVIDER             (window_title_provider_get_type ())
+#define WINDOW_TITLE_PROVIDER(obj)             (G_TYPE_CHECK_INSTANCE_CAST ((obj), WINDOW_TYPE_TITLE_PROVIDER, WindowTitleProvider))
+#define WINDOW_TITLE_PROVIDER_CLASS(klass)     (G_TYPE_CHECK_CLASS_CAST ((klass), WINDOW_TYPE_TITLE_PROVIDER, WindowTitleProviderClass))
+#define WINDOW_IS_TITLE_PROVIDER(obj)          (G_TYPE_CHECK_INSTANCE_TYPE ((obj), WINDOW_TYPE_TITLE_PROVIDER))
+#define WINDOW_IS_TITLE_PROVIDER_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), WINDOW_TYPE_TITLE_PROVIDER))
+#define WINDOW_TITLE_PROVIDER_GET_CLASS(obj)   (G_TYPE_INSTANCE_GET_CLASS ((obj), WINDOW_TYPE_TITLE_PROVIDER, WindowTitleProviderClass))
+
+GType window_title_provider_get_type      	(void) G_GNUC_CONST G_GNUC_INTERNAL;
+
+G_END_DECLS
+
+#endif /*WINDOW_TITLE_PROVIDER_H_*/
diff --git a/plugins/window-title/window-title.c b/plugins/window-title/window-title.c
deleted file mode 100644
index ff49057..0000000
--- a/plugins/window-title/window-title.c
+++ /dev/null
@@ -1,106 +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 <glib.h>
-#include <glib/gi18n.h>
-#include <gtk/gtk.h>
-
-#include <parole/parole.h>
-
-typedef struct
-{
-    GtkWidget *window;
-    
-} PluginData;
-
-static void
-set_default_window_title (GtkWidget *window)
-{
-    gtk_window_set_title (GTK_WINDOW (window), _("Parole Media Player"));
-}
-
-static void
-set_stream_title (GtkWidget *window, const ParoleStream *stream)
-{
-    gchar *title = NULL;
-    
-    g_object_get (G_OBJECT (stream),
-		  "title", &title,
-		  NULL);
-		  
-    if ( title )
-    {
-	gtk_window_set_title (GTK_WINDOW (window), title);
-	g_free (title);
-    }
-}
-
-static void
-state_changed_cb (ParolePlugin *plugin, const ParoleStream *stream, ParoleState state, PluginData *data)
-{
-    if ( state < PAROLE_STATE_PAUSED )
-	set_default_window_title (data->window);
-    else
-	set_stream_title (data->window, stream);
-}
-
-static void
-tag_message_cb (ParolePlugin *plugin, const ParoleStream *stream, PluginData *data)
-{
-    set_stream_title (data->window, stream);
-}
-
-static void
-free_data_cb (ParolePlugin *plugin, PluginData *data)
-{
-    if ( data->window && GTK_IS_WINDOW (data->window) )
-	set_default_window_title (data->window);
-    g_free (data);
-}
-
-G_MODULE_EXPORT static void
-construct (ParolePlugin *plugin)
-{
-    PluginData *data;
-    
-    data = g_new0 (PluginData, 1);
-    
-    data->window = parole_plugin_get_main_window (plugin);
-    
-    g_signal_connect (plugin, "state_changed", 
-		      G_CALLBACK (state_changed_cb), data);
-		      
-    g_signal_connect (plugin, "tag-message",
-		      G_CALLBACK (tag_message_cb), data);
-    
-    g_signal_connect (plugin, "free-data",
-		      G_CALLBACK (free_data_cb), data);
-}
-
-PAROLE_PLUGIN_CONSTRUCT (construct,                  /* Construct function */
-			 _("Window title"),          /* Title */
-			 _("Set the main window name to the current\n"
-			  " playing media name."),    /* Description */
-			  "Copyright \302\251 2009 Sarah Hijazi",            /* Author */
-			  "http://goodies.xfce.org/projects/applications/parole");            /* site */
diff --git a/plugins/window-title/window-title.desktop.in b/plugins/window-title/window-title.desktop.in
new file mode 100644
index 0000000..0d251bd
--- /dev/null
+++ b/plugins/window-title/window-title.desktop.in
@@ -0,0 +1,6 @@
+[Parole Plugin]
+Module=window-title
+_Name=Window Title
+_Description=Set the main window name to the current playing media name.
+Authors=Sarah Hijazi
+Website=http://goodies.xfce.org/projects/applications/parole
diff --git a/src/Makefile.am b/src/Makefile.am
index 4d30ca8..e95a8df 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -1,8 +1,5 @@
 bin_PROGRAMS = parole
 
-noinst_LTLIBRARIES =                    	\
-        libparole.la
-
 INCLUDES =					\
 	-I$(top_srcdir)				\
 	-I$(top_srcdir)/parole			\
@@ -14,32 +11,17 @@ INCLUDES =					\
 	-DLOCALEDIR=\"$(localedir)\"		\
 	-DG_LOG_DOMAIN=\"parole\"		\
 	-DPAROLE_PLUGINS_DIR=\"$(libdir)/parole-$(PAROLE_VERSION_API)\"\
+	-DPAROLE_PLUGINS_DATA_DIR=\"$(datadir)/parole/parole-plugins-$(PAROLE_VERSION_API)\"\
+	-DPAROLE_COMPILATION			\
         $(GTHREAD_CFLAGS)                       \
 	$(GIO_CFLAGS)				\
+	$(GMODULE_CFLAGS)			\
         $(DBUS_GLIB_CFLAGS)                     \
         $(LIBXFCE4GUI_CFLAGS)                   \
 	$(GST_VIDEO_CFLAGS)			\
 	$(GST_INTERFACES_CFLAGS)		\
 	$(TAGLIBC_CFLAGS)
 
-PAROLE_LDFLAGS =				\
-	-export-dynamic 			\
-	-no-undefined				\
-	-export-symbols-regex "^[[^_]].*"
-
-PAROLE_LIBS = 					\
-	$(top_builddir)/dbus/libparoledbus.la 	\
-	$(top_builddir)/gst/libparolegst.la 	\
-	$(top_builddir)/common/libparolecommon.la\
-	$(top_builddir)/common/libparolescreensaver.la\
-        $(GTHREAD_LIBS)                         \
-	$(GIO_LIBS)				\
-        $(DBUS_GLIB_LIBS)                       \
-        $(LIBXFCE4GUI_LIBS)                     \
-	$(GST_VIDEO_LIBS)			\
-	$(GST_INTERFACES_LIBS)			\
-	$(TAGLIBC_LIBS)
-
 GENERATED_FILES =				\
 	gmarshal.c				\
 	gmarshal.h				\
@@ -70,13 +52,14 @@ NOINST_HFILES =					\
 	parole-open-location.h			\
 	parole-disc-menu.h			\
 	parole-session.h			\
-	parole-button.h
+	parole-button.h				\
+	parole-plugin-player.h
 
-libparole_la_SOURCES =				\
+parole_SOURCES =				\
 	$(GENERATED_FILES)			\
 	$(NOINST_HFILES)			\
+	main.c					\
 	parole-player.c				\
-	parole-file.c				\
 	parole-vis.c				\
 	parole-statusbar.c			\
 	parole-medialist.c			\
@@ -89,7 +72,6 @@ libparole_la_SOURCES =				\
 	parole-utils.c				\
 	parole-debug.c				\
 	parole-plugins-manager.c		\
-	parole-plugin.c				\
 	parole-module.c				\
 	parole-pl-parser.c			\
 	parole-about.c				\
@@ -98,25 +80,25 @@ libparole_la_SOURCES =				\
 	parole-open-location.c			\
 	parole-disc-menu.c			\
 	parole-session.c			\
-	parole-button.c
-
-libparole_la_LDFLAGS =				\
-	$(PAROLE_LDFLAGS)
-
-libparole_la_LIBADD =				\
-	$(PAROLE_LIBS)
-
-parole_SOURCES =				\
-	main.c
+	parole-button.c				\
+	parole-plugin-player.c
 
 parole_LDADD =					\
-	libparole.la
-
-parole_LDFLAGS =				\
-	$(PAROLE_LDFLAGS)
-
+	$(top_builddir)/parole/libparole.la 	\
+	$(top_builddir)/dbus/libparoledbus.la 	\
+	$(top_builddir)/gst/libparolegst.la 	\
+	$(top_builddir)/common/libparolecommon.la\
+	$(top_builddir)/common/libparolescreensaver.la\
+        $(GTHREAD_LIBS)                         \
+	$(GIO_LIBS)				\
+	$(GMODULE_LIBS)				\
+        $(DBUS_GLIB_LIBS)                       \
+        $(LIBXFCE4GUI_LIBS)                     \
+	$(GST_VIDEO_LIBS)			\
+	$(GST_INTERFACES_LIBS)			\
+	$(TAGLIBC_LIBS)
+	
 parole_glib_enum_headers =			\
-	$(top_srcdir)/parole/parole-plugin.h  	\
 	parole-pl-parser.h			\
 	parole-conf.h				\
 	parole-button.h
@@ -149,7 +131,6 @@ stamp-enum-gtypes.h: $(parole_glib_enum_headers) Makefile
 enum-gtypes.c: $(parole_glib_enum_headers) Makefile
 	( cd $(srcdir) && glib-mkenums \
 		--fhead "#include \"enum-gtypes.h\"\n\n" \
-		--fhead "#include \"parole-plugin.h\"\n\n" \
 		--fhead "#include \"parole-pl-parser.h\"\n\n" \
 		--fhead "#include \"parole-conf.h\"\n\n" \
 		--fhead "#include \"parole-button.h\"\n\n" \
diff --git a/src/main.c b/src/main.c
index eb52f74..fd12914 100644
--- a/src/main.c
+++ b/src/main.c
@@ -310,8 +310,7 @@ int main (int argc, char **argv)
 	    g_error_free (error);
 	}
 
-	plugins = parole_plugins_manager_get (!no_plugins);
-	parole_plugins_manager_load_plugins (plugins);
+	plugins = parole_plugins_manager_new (!no_plugins);
 	g_object_unref (builder);
 	
 	gdk_notify_startup_complete ();
diff --git a/src/parole-disc.c b/src/parole-disc.c
index 4e29c28..5f0e3bc 100644
--- a/src/parole-disc.c
+++ b/src/parole-disc.c
@@ -199,7 +199,7 @@ got_cdda:
 	gchar *label;
 	
 	name = g_mount_get_name (mount);
-	label = g_strdup_printf ("%s %s", _("Play Disc"), name);
+	label = g_strdup_printf ("%s '%s'", _("Play Disc"), name);
 	
 	data = parole_disc_get_mount_data (disc, label, uri, device, kind);
 	g_free (uri);
diff --git a/src/parole-filters.h b/src/parole-filters.h
index 2a12951..389aa1a 100644
--- a/src/parole-filters.h
+++ b/src/parole-filters.h
@@ -23,7 +23,7 @@
 
 #include <gtk/gtk.h>
 
-#include "parole-file.h"
+#include <parole/parole-file.h>
 
 G_BEGIN_DECLS
 
diff --git a/src/parole-mediachooser.c b/src/parole-mediachooser.c
index 59ec020..e2f251b 100644
--- a/src/parole-mediachooser.c
+++ b/src/parole-mediachooser.c
@@ -32,11 +32,12 @@
 #include <libxfce4util/libxfce4util.h>
 #include <libxfcegui4/libxfcegui4.h>
 
+#include <parole/parole-file.h>
+
 #include "interfaces/mediachooser_ui.h"
 
 #include "parole-mediachooser.h"
 #include "parole-builder.h"
-#include "parole-file.h"
 #include "parole-filters.h"
 #include "parole-rc-utils.h"
 #include "parole-utils.h"
diff --git a/src/parole-medialist.c b/src/parole-medialist.c
index 1244811..47f1622 100644
--- a/src/parole-medialist.c
+++ b/src/parole-medialist.c
@@ -35,12 +35,13 @@
 #include <libxfce4util/libxfce4util.h>
 #include <libxfcegui4/libxfcegui4.h>
 
+#include <parole/parole-file.h>
+
 #include "interfaces/playlist_ui.h"
 #include "interfaces/save-playlist_ui.h"
 
 #include "parole-builder.h"
 #include "parole-medialist.h"
-#include "parole-file.h"
 #include "parole-mediachooser.h"
 #include "parole-open-location.h"
 
diff --git a/src/parole-module.c b/src/parole-module.c
index ecbc800..5cad077 100644
--- a/src/parole-module.c
+++ b/src/parole-module.c
@@ -26,34 +26,79 @@
 #include <stdlib.h>
 #include <string.h>
 
+#include <parole/parole-provider-plugin.h>
+
 #include "parole-module.h"
 
-G_DEFINE_TYPE (ParoleModule, parole_module, G_TYPE_TYPE_MODULE)
+static void     parole_provider_module_plugin_init   (ParoleProviderPluginIface	 *iface);
+
+static void     parole_provider_module_class_init    (ParoleProviderModuleClass  *klass);
+static void	parole_provider_module_init 	     (ParoleProviderModule *module);
+
+GType
+parole_provider_module_get_type (void)
+{
+    static GType type = G_TYPE_INVALID;
+
+    if (G_UNLIKELY (type == G_TYPE_INVALID))
+    {
+	static const GTypeInfo info =
+	{
+	    sizeof (ParoleProviderModuleClass),
+	    NULL,
+	    NULL,
+	    (GClassInitFunc) parole_provider_module_class_init,
+	    NULL,
+	    NULL,
+	    sizeof (ParoleProviderModule),
+	    0,
+	    (GInstanceInitFunc) parole_provider_module_init,
+	    NULL,
+	};
+
+	static const GInterfaceInfo plugin_info =
+	{
+	    (GInterfaceInitFunc) parole_provider_module_plugin_init,
+	    NULL,
+	    NULL,
+	};
+
+	type = g_type_register_static (G_TYPE_TYPE_MODULE, "ParoleProviderModule", &info, 0);
+	g_type_add_interface_static (type, PAROLE_TYPE_PROVIDER_PLUGIN, &plugin_info);
+    }
+
+    return type;
+}
 
 static gboolean
 parole_module_load (GTypeModule *gtype_module)
 {
-    ParoleModule *module;
+    ParoleProviderModule *module;
     
-    module = PAROLE_MODULE (gtype_module);
+    module = PAROLE_PROVIDER_MODULE (gtype_module);
     
-    module->mod = g_module_open (gtype_module->name, G_MODULE_BIND_LOCAL);
+    module->library = g_module_open (gtype_module->name, G_MODULE_BIND_LOCAL);
 
-    if ( G_UNLIKELY (module->mod == NULL) )
+    if ( G_UNLIKELY (module->library == NULL) )
     {
 	g_critical ("Failed to load plugin : %s", g_module_error ());
 	return FALSE;
     }
     
-    if ( !g_module_symbol (module->mod, "parole_plugin_constructor", (gpointer) &module->constructor) || 
-         !g_module_symbol (module->mod, "parole_plugin_get_description", (gpointer) &module->get_plugin_description))
+    if ( !g_module_symbol (module->library, "parole_plugin_initialize", (gpointer) &module->initialize) || 
+         !g_module_symbol (module->library, "parole_plugin_shutdown", (gpointer) &module->shutdown))
     {
 	g_critical ("Plugin %s missing required symbols", gtype_module->name);
-	g_module_close (module->mod);
+	g_module_close (module->library);
 	return FALSE;
     }
     
-    module->desc = (*module->get_plugin_description) ();
+    module->player = parole_plugin_player_new ();
+    
+    module->provider_type = (*module->initialize) (module);
+    module->instance = g_object_new (module->provider_type, NULL);
+    parole_provider_plugin_set_player (PAROLE_PROVIDER_PLUGIN (module->instance), PAROLE_PROVIDER_PLAYER (module->player));
+    module->active = TRUE;
     
     return TRUE;
 }
@@ -61,70 +106,76 @@ parole_module_load (GTypeModule *gtype_module)
 static void
 parole_module_unload (GTypeModule *gtype_module)
 {
-    ParoleModule *module;
+    ParoleProviderModule *module;
     
-    module = PAROLE_MODULE (gtype_module);
+    module = PAROLE_PROVIDER_MODULE (gtype_module);
 
-    parole_module_set_active (module, FALSE);
+    g_object_unref (G_OBJECT (module->instance));
+    g_object_unref (module->player);
 
-    g_module_close (module->mod);
-    module->constructor = NULL;
+    (*module->shutdown) ();
     
-    if ( module->desc )
-    {
-	g_free (module->desc);
-    }
+    g_module_close (module->library);
+    
+    module->initialize = NULL;
+    module->shutdown = NULL;
+    module->library = NULL;
+    module->provider_type = G_TYPE_INVALID;
+    module->active = FALSE;
+    
+    module->player = NULL;
+    module->instance = NULL;
+}
+
+static gboolean
+parole_provider_module_get_is_active (ParoleProviderPlugin *plugin)
+{
+    return PAROLE_PROVIDER_MODULE (plugin)->active;
 }
 
 static void
-parole_module_class_init (ParoleModuleClass *klass)
+parole_provider_module_class_init (ParoleProviderModuleClass *klass)
 {
-    GTypeModuleClass *gtype_module_class = G_TYPE_MODULE_CLASS (klass);
+    GTypeModuleClass *gtype_module_class;
+    
+    gtype_module_class = G_TYPE_MODULE_CLASS (klass);
 
     gtype_module_class->load   = parole_module_load;
     gtype_module_class->unload = parole_module_unload;
 }
 
+static void     
+parole_provider_module_plugin_init (ParoleProviderPluginIface *iface)
+{
+    iface->get_is_active = parole_provider_module_get_is_active;
+}
+
 static void
-parole_module_init (ParoleModule *module)
+parole_provider_module_init (ParoleProviderModule *module)
 {
-    module->mod = NULL;
-    module->constructor = NULL;
-    module->get_plugin_description = NULL;
-    module->plugin = NULL;
-    module->desc = NULL;
+    module->library = NULL;
+    module->initialize = NULL;
+    module->shutdown = NULL;
+    module->active = FALSE;
+    module->instance = NULL;
+    module->desktop_file = NULL;
+    module->provider_type = G_TYPE_INVALID;
+    
+    module->player = NULL;
 }
 
-ParoleModule *
-parole_module_new (const gchar *filename)
+ParoleProviderModule *
+parole_provider_module_new (const gchar *filename, const gchar *desktop_file)
 {
-    ParoleModule *module = NULL;
+    ParoleProviderModule *module = NULL;
     
-    module = g_object_new (PAROLE_TYPE_MODULE, NULL);
+    module = g_object_new (PAROLE_TYPE_PROVIDER_MODULE, NULL);
     
     g_type_module_set_name (G_TYPE_MODULE (module), filename);
     
-    return module;
-}
-
-void parole_module_set_active (ParoleModule *module, gboolean active)
-{
-    if ( active )
-    {
-	g_return_if_fail (module->constructor != NULL);
-	
-	module->plugin = (*module->constructor) ();
+    module->desktop_file = g_strdup (desktop_file);
+    g_object_set_data_full (G_OBJECT (module), "desktop-file", 
+			     module->desktop_file, (GDestroyNotify) g_free);
     
-	module->enabled = TRUE;
-    }
-    else
-    {
-	if ( module->plugin ) 
-	{
-	    g_signal_emit_by_name (G_OBJECT (module->plugin), "free-data");
-	    g_object_unref (module->plugin);
-	    module->plugin = NULL;
-	}
-	module->enabled = FALSE;
-    }
+    return module;
 }
diff --git a/src/parole-module.h b/src/parole-module.h
index 3629489..1972fac 100644
--- a/src/parole-module.h
+++ b/src/parole-module.h
@@ -22,45 +22,48 @@
 #define __PAROLE_MODULE_H
 
 #include <glib-object.h>
+#include <parole/parole.h>
 
-#include "parole.h"
-#include "parole-plugin.h"
+#include "parole-plugin-player.h"
 
 G_BEGIN_DECLS
 
-#define PAROLE_TYPE_MODULE        (parole_module_get_type () )
-#define PAROLE_MODULE(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_MODULE, ParoleModule))
-#define PAROLE_IS_MODULE(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_MODULE))
+#define PAROLE_TYPE_PROVIDER_MODULE         	(parole_provider_module_get_type () )
+#define PAROLE_PROVIDER_MODULE(o)           	(G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PROVIDER_MODULE, ParoleProviderModule))
+#define PAROLE_PROVIDER_MODULE_CLASS(klass) 	(G_TYPE_CHECK_CLASS_CAST ((klass), PAROLE_TYPE_PROVIDER_MODULE, ParoleProviderModuleClass))
+#define PAROLE_IS_PROVIDER_MODULE(o)        	(G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PROVIDER_MODULE))
+#define PAROLE_IS_PROVIDER_MODULE_CLASS(klass)  (G_TYPE_CHECK_CLASS_TYPE ((klass), PAROLE_TYPE_PROVIDER_MODULE))
+#define PAROLE_PROVIDER_MODULE_GET_CLASS(o)	(G_TYPE_INSTANCE_GET_CLASS((o), PAROLE_TYPE_PROVIDER_MODULE, ParoleProviderModuleClass))
 
-typedef struct ParoleModulePrivate ParoleModulePrivate;
+typedef struct _ParoleProviderModuleClass ParoleProviderModuleClass;
+typedef struct _ParoleProviderModule ParoleProviderModule;
 
-typedef struct
+struct _ParoleProviderModule
 {
     GTypeModule       	     parent;
     
-    GModule		    *mod;
-    ParolePlugin            *plugin;
-    ParolePluginDesc        *desc;
-    gboolean		     enabled;
+    GModule		    *library;
+    ParolePluginPlayer      *player;
     
-    ParolePlugin	   *(*constructor)		   (void);
-    
-    ParolePluginDesc	   *(*get_plugin_description)	   (void);
+    GType		    (*initialize)		(ParoleProviderModule *module);
+
+    void		    (*shutdown)			(void);
     
-} ParoleModule;
+    GType		     provider_type;
+    gboolean		     active;
+    gpointer                 instance;
+    gchar                   *desktop_file;
+};
 
-typedef struct
+struct _ParoleProviderModuleClass
 {
     GTypeModuleClass 	     parent_class;
-    
-} ParoleModuleClass;
-
-GType        		     parole_module_get_type        (void) G_GNUC_CONST;
+} ;
 
-ParoleModule       	    *parole_module_new             (const gchar *filename);
+GType        		     parole_provider_module_get_type        (void) G_GNUC_CONST;
 
-void			     parole_module_set_active      (ParoleModule *module,
-							    gboolean active);
+ParoleProviderModule	    *parole_provider_module_new             (const gchar *filename,
+								     const gchar *desktop_file);
 
 G_END_DECLS
 
diff --git a/src/parole-pl-parser.c b/src/parole-pl-parser.c
index 4255cc4..6c05936 100644
--- a/src/parole-pl-parser.c
+++ b/src/parole-pl-parser.c
@@ -40,8 +40,9 @@
 #include <gio/gio.h>
 #include <libxfce4util/libxfce4util.h>
 
+#include <parole/parole-file.h>
+
 #include "parole-pl-parser.h"
-#include "parole-file.h"
 #include "parole-filters.h"
 #include "parole-debug.h"
 #include "enum-gtypes.h"
diff --git a/src/parole-player.c b/src/parole-player.c
index 8c82396..c174810 100644
--- a/src/parole-player.c
+++ b/src/parole-player.c
@@ -38,6 +38,8 @@
 
 #include <dbus/dbus-glib.h>
 
+#include <parole/parole-file.h>
+
 #include "parole-builder.h"
 #include "parole-about.h"
 
@@ -45,7 +47,6 @@
 #include "parole-gst.h"
 #include "parole-dbus.h"
 #include "parole-mediachooser.h"
-#include "parole-file.h"
 #include "parole-filters.h"
 #include "parole-disc.h"
 #include "parole-disc-menu.h"
@@ -1680,8 +1681,9 @@ parole_player_init (ParolePlayer *player)
 			      G_CALLBACK (parole_player_session_die_cb), player);
     
     player->priv->gst = parole_gst_new (FALSE, player->priv->conf);
-    
+
     player->priv->status = parole_statusbar_new ();
+
     player->priv->disc = parole_disc_new ();
     g_signal_connect (player->priv->disc, "disc-selected",
 		      G_CALLBACK (parole_player_disc_selected_cb), player);
diff --git a/src/parole-plugin-player.c b/src/parole-plugin-player.c
new file mode 100644
index 0000000..d154cd2
--- /dev/null
+++ b/src/parole-plugin-player.c
@@ -0,0 +1,160 @@
+/*
+ * * 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/parole-provider-player.h>
+
+#include "parole-plugin-player.h"
+#include "parole-plugins-manager.h"
+
+#include "gst/parole-gst.h"
+
+static void parole_plugin_player_iface_init   (ParoleProviderPlayerIface *iface);
+
+static void parole_plugin_player_finalize     (GObject *object);
+
+#define PAROLE_PLUGIN_PLAYER_GET_PRIVATE(o) \
+(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_PLUGIN_PLAYER, ParolePluginPlayerPrivate))
+
+struct ParolePluginPlayerPrivate
+{
+    GtkWidget *gst;
+    GtkWidget *box;
+    
+    gulong state_changed;
+    gulong tag_message;
+    gboolean packed;
+
+};
+
+G_DEFINE_TYPE_WITH_CODE (ParolePluginPlayer, parole_plugin_player, G_TYPE_OBJECT,
+    G_IMPLEMENT_INTERFACE (PAROLE_TYPE_PROVIDER_PLAYER, parole_plugin_player_iface_init))
+
+static GtkWidget *
+parole_plugin_player_get_main_window (ParoleProviderPlayer *provider)
+{
+    ParolePluginPlayer *player;
+    
+    player = PAROLE_PLUGIN_PLAYER (provider);
+    return gtk_widget_get_toplevel (player->priv->gst);
+}
+
+static void
+parole_plugin_player_pack_widget (ParoleProviderPlayer *provider, GtkWidget *widget, 
+				  const gchar *title, ParolePluginContainer container_type)
+{
+    ParolePluginPlayer *player;
+    ParolePluginsManager *manager;
+    
+    manager = parole_plugins_manager_get ();
+    player = PAROLE_PLUGIN_PLAYER (provider);
+    
+    g_return_if_fail (player->priv->packed == FALSE);
+    
+    player->priv->packed = TRUE;
+    player->priv->box = widget;
+    
+    parole_plugins_manager_pack (manager, widget, title, container_type);
+}
+
+static void parole_plugin_player_iface_init (ParoleProviderPlayerIface *iface)
+{
+    iface->get_main_window = parole_plugin_player_get_main_window;
+    iface->pack = parole_plugin_player_pack_widget;
+}
+
+static void 
+parole_plugin_player_media_state_changed_cb (ParoleGst *gst, const ParoleStream *stream, 
+					     ParoleMediaState state, ParolePluginPlayer *player)
+{
+    g_signal_emit_by_name (G_OBJECT (player), "state-changed", stream, state);
+}
+
+static void 
+parole_plugin_player_media_tag_cb (ParoleGst *gst, const ParoleStream *stream, ParolePluginPlayer *player)
+{
+    g_signal_emit_by_name (G_OBJECT (player), "tag-message", stream);
+}
+
+static void
+parole_plugin_player_class_init (ParolePluginPlayerClass *klass)
+{
+    GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+    object_class->finalize = parole_plugin_player_finalize;
+
+    g_type_class_add_private (klass, sizeof (ParolePluginPlayerPrivate));
+}
+
+static void
+parole_plugin_player_init (ParolePluginPlayer *player)
+{
+    player->priv = PAROLE_PLUGIN_PLAYER_GET_PRIVATE (player);
+    
+    player->priv->gst = parole_gst_get ();
+    
+    player->priv->state_changed = g_signal_connect (G_OBJECT (player->priv->gst), "media-state",
+					    G_CALLBACK (parole_plugin_player_media_state_changed_cb), player);
+		      
+    player->priv->tag_message = g_signal_connect (G_OBJECT (player->priv->gst), "media-tag",
+					  G_CALLBACK (parole_plugin_player_media_tag_cb), player);
+
+    player->priv->packed = FALSE;
+    player->priv->box = NULL;
+}
+
+static void
+parole_plugin_player_finalize (GObject *object)
+{
+    ParolePluginPlayer *player;
+
+    player = PAROLE_PLUGIN_PLAYER (object);
+    
+    if ( G_IS_OBJECT (player->priv->gst) )
+    {
+	if (g_signal_handler_is_connected (player->priv->gst, player->priv->state_changed)) 
+	    g_signal_handler_disconnect (player->priv->gst, player->priv->state_changed);
+
+	if (g_signal_handler_is_connected (player->priv->gst, player->priv->tag_message)) 
+	    g_signal_handler_disconnect (player->priv->gst, player->priv->tag_message);
+    }
+    
+    if ( player->priv->box )
+	gtk_widget_destroy (player->priv->box);
+
+    G_OBJECT_CLASS (parole_plugin_player_parent_class)->finalize (object);
+}
+
+ParolePluginPlayer *
+parole_plugin_player_new (void)
+{
+    ParolePluginPlayer *player = NULL;
+    
+    player = g_object_new (PAROLE_TYPE_PLUGIN_PLAYER, NULL);
+    
+    return player;
+}
diff --git a/browser-plugin/media-plugin/parole-plugin-player.h b/src/parole-plugin-player.h
similarity index 62%
copy from browser-plugin/media-plugin/parole-plugin-player.h
copy to src/parole-plugin-player.h
index d92dbf0..d1a2821 100644
--- a/browser-plugin/media-plugin/parole-plugin-player.h
+++ b/src/parole-plugin-player.h
@@ -21,38 +21,32 @@
 #ifndef __PAROLE_PLUGIN_PLAYER_H
 #define __PAROLE_PLUGIN_PLAYER_H
 
-#include <gtk/gtk.h>
+#include <glib-object.h>
 
 G_BEGIN_DECLS
 
-#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))
+#define PAROLE_TYPE_PLUGIN_PLAYER        (parole_plugin_player_get_type () )
+#define PAROLE_PLUGIN_PLAYER(o)          (G_TYPE_CHECK_INSTANCE_CAST ((o), PAROLE_TYPE_PLUGIN_PLAYER, ParolePluginPlayer))
+#define PAROLE_IS_PLUGIN_PLAYER(o)       (G_TYPE_CHECK_INSTANCE_TYPE ((o), PAROLE_TYPE_PLUGIN_PLAYER))
 
 typedef struct ParolePluginPlayerPrivate ParolePluginPlayerPrivate;
 
 typedef struct
 {
-    GObject         			 parent;
-    
-    ParolePluginPlayerPrivate     	*priv;
+    GObject         		   parent;
+    ParolePluginPlayerPrivate     *priv;
     
 } ParolePluginPlayer;
 
 typedef struct
 {
-    GObjectClass 			 parent_class;
+    GObjectClass 		   parent_class;
     
 } ParolePluginPlayerClass;
 
-GType        				 parole_plugin_player_get_type        (void) G_GNUC_CONST;
-
-ParolePluginPlayer       		*parole_plugin_player_new             (GtkWidget *plug,
-									       gchar *url);
-									       
-void					 parole_plugin_player_play	      (ParolePluginPlayer *player);
+GType        			   parole_plugin_player_get_type        (void) G_GNUC_CONST;
 
-void					 parole_plugin_player_exit 	      (ParolePluginPlayer *player);
+ParolePluginPlayer                *parole_plugin_player_new             (void);
 
 G_END_DECLS
 
diff --git a/src/parole-plugin.c b/src/parole-plugin.c
deleted file mode 100644
index 8ca83c6..0000000
--- a/src/parole-plugin.c
+++ /dev/null
@@ -1,662 +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 "parole-plugin.h"
-#include "parole-plugins-manager.h"
-#include "parole-gst.h"
-#include "gmarshal.h"
-#include "enum-gtypes.h"
-
-static void parole_plugin_finalize     (GObject *object);
-
-static void parole_plugin_set_property (GObject *object,
-				        guint prop_id,
-				        const GValue *value,
-					GParamSpec *pspec);
-			     
-static void parole_plugin_get_property (GObject *object,
-					guint prop_id,
-					GValue *value,
-					GParamSpec *pspec);
-
-#define PAROLE_PLUGIN_GET_PRIVATE(o) \
-(G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_PLUGIN, ParolePluginPrivate))
-
-typedef struct _ParolePluginPrivate ParolePluginPrivate;
-
-struct _ParolePluginPrivate
-{
-    ParoleGst *gst;
-    
-    gchar *title;
-    gchar *author;
-    gchar *desc;
-    gchar *site;
-
-    GtkWidget *widget;
-    gboolean packed;
-    
-    gboolean configurable;
-    
-    /* sig id's*/
-    gulong gst_sig1;
-    gulong gst_sig2;
-    gulong gst_sig3;
-    gulong gst_sig4;
-};
-
-enum
-{
-    PROP_0,
-    PROP_TITLE,
-    PROP_DESC,
-    PROP_AUTHOR,
-    PROP_SITE,
-    PROP_CONFIGURABLE
-};
-
-enum
-{
-    STATE_CHANGED,
-    TAG_MESSAGE,
-    PROGRESSED,
-    BUFFERING,
-    FREE_DATA,
-    CONFIGURE,
-    LAST_SIGNAL
-};
-
-static guint signals [LAST_SIGNAL] = { 0 };
-
-G_DEFINE_TYPE (ParolePlugin, parole_plugin, G_TYPE_OBJECT)
-
-static void 
-parole_plugin_media_state_changed_cb (ParoleGst *gst, const ParoleStream *stream, 
-				      ParoleMediaState state, ParolePlugin *plugin)
-{
-    g_signal_emit (G_OBJECT (plugin), signals [STATE_CHANGED], 0, stream, state);
-}
-
-static void 
-parole_plugin_media_tag_cb (ParoleGst *gst, const ParoleStream *stream, ParolePlugin *plugin)
-{
-    g_signal_emit (G_OBJECT (plugin), signals [TAG_MESSAGE], 0, stream);
-}
-
-static void
-parole_plugin_buffering_changed_cb (ParoleGst *gst, const ParoleStream *stream, 
-				    gint percentage, ParolePlugin *plugin)
-{
-    g_signal_emit (G_OBJECT (plugin), signals [BUFFERING], 0, stream, percentage);
-}
-
-static void
-parole_plugin_media_progressed_cb (ParoleGst *gst, const ParoleStream *stream,
-				   gdouble value, ParolePlugin *plugin)
-{
-    g_signal_emit (G_OBJECT (plugin), signals [PROGRESSED], 0, stream, value);
-}
-
-static void
-parole_plugin_class_init (ParolePluginClass *klass)
-{
-    GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-    object_class->finalize = parole_plugin_finalize;
-
-    object_class->get_property = parole_plugin_get_property;
-    object_class->set_property = parole_plugin_set_property;
-
-    /**
-     * ParolePlugin::state-changed:
-     * @plugin: the object which received the signal.
-     * @stream: a #ParoleStream.
-     * @state: the new state.
-     * 
-     * Since: 0.2 
-     **/
-    signals[STATE_CHANGED] = 
-        g_signal_new ("state-changed",
-                      PAROLE_TYPE_PLUGIN,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (ParolePluginClass, state_changed),
-                      NULL, NULL,
-                      _gmarshal_VOID__OBJECT_ENUM,
-                      G_TYPE_NONE, 2,
-		      PAROLE_TYPE_STREAM, ENUM_GTYPE_STATE);
-
-    /**
-     * ParolePlugin::tag-message:
-     * @plugin: the object which received the signal.
-     * @stream: a #ParoleStream.
-     * 
-     * Since: 0.2 
-     **/
-    signals[TAG_MESSAGE] = 
-        g_signal_new ("tag-message",
-                      PAROLE_TYPE_PLUGIN,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (ParolePluginClass, tag_message),
-                      NULL, NULL,
-		      g_cclosure_marshal_VOID__OBJECT,
-                      G_TYPE_NONE, 1, PAROLE_TYPE_STREAM);
-	
-    /**
-     * ParolePlugin::progressed:
-     * @plugin: the object which received the signal.
-     * @stream: a #ParoleStream.
-     * 
-     * Since: 0.2 
-     **/
-    signals[PROGRESSED] = 
-        g_signal_new ("progressed",
-                      PAROLE_TYPE_PLUGIN,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (ParolePluginClass, progressed),
-                      NULL, NULL,
-                      _gmarshal_VOID__OBJECT_DOUBLE,
-                      G_TYPE_NONE, 2, 
-		      G_TYPE_OBJECT, G_TYPE_DOUBLE);
-
-    /**
-     * ParolePlugin::buffering:
-     * @plugin: the object which received the signal.
-     * @stream: a #ParoleStream.
-     * 
-     * Since: 0.2 
-     **/
-    signals[BUFFERING] = 
-        g_signal_new ("buffering",
-                      PAROLE_TYPE_PLUGIN,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET (ParolePluginClass, buffering),
-                      NULL, NULL,
-                      _gmarshal_VOID__OBJECT_INT,
-                      G_TYPE_NONE, 2, 
-		      G_TYPE_OBJECT, G_TYPE_INT);
-
-    /**
-     * ParolePlugin::free-data:
-     * @plugin: the object which received the signal.
-     * 
-     * Emitted before unloading the plugin from memory, so
-     * any dynamiclly allocated memory should be freed in this signal
-     * handler.
-     * 
-     * Since: 0.2 
-     **/
-    signals [FREE_DATA] = 
-        g_signal_new ("free-data",
-                      PAROLE_TYPE_PLUGIN,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET(ParolePluginClass, free_data),
-                      NULL, NULL,
-                      g_cclosure_marshal_VOID__VOID,
-                      G_TYPE_NONE, 0, G_TYPE_NONE);
-
-    /**
-     * ParolePlugin::configure:
-     * @plugin: the object which received the signal.
-     * 
-     * Emitted when the user click the configure button in the plugins
-     * configuration dialog.
-     * 
-     * Since: 0.2 
-     **/
-    signals [CONFIGURE] = 
-        g_signal_new ("configure",
-                      PAROLE_TYPE_PLUGIN,
-                      G_SIGNAL_RUN_LAST,
-                      G_STRUCT_OFFSET(ParolePluginClass, configure),
-                      NULL, NULL,
-                      g_cclosure_marshal_VOID__OBJECT,
-                      G_TYPE_NONE, 1, GTK_TYPE_WIDGET);
-
-    /**
-     * ParolePlugin:title:
-     * 
-     * Title to display for this plugin.
-     * 
-     * Since: 0.2 
-     **/
-    g_object_class_install_property (object_class,
-                                     PROP_TITLE,
-                                     g_param_spec_string ("title",
-                                                          NULL, NULL,
-                                                          NULL,
-                                                          G_PARAM_READWRITE|
-							  G_PARAM_CONSTRUCT_ONLY));
-
-    /**
-     * ParolePlugin:description:
-     * 
-     * Description of the plugin.
-     * 
-     * Since: 0.2 
-     **/
-    g_object_class_install_property (object_class,
-                                     PROP_DESC,
-                                     g_param_spec_string ("description",
-                                                          NULL, NULL,
-                                                          NULL,
-                                                          G_PARAM_READWRITE|
-							  G_PARAM_CONSTRUCT_ONLY));
-
-    /**
-     * ParolePlugin:author:
-     * 
-     * Author of the plugin.
-     * 
-     * Since: 0.2 
-     **/
-    g_object_class_install_property (object_class,
-                                     PROP_AUTHOR,
-                                     g_param_spec_string ("author",
-                                                          NULL, NULL,
-                                                          NULL,
-                                                          G_PARAM_READWRITE|
-							  G_PARAM_CONSTRUCT_ONLY));
-    
-    /**
-     * ParolePlugin:site:
-     * 
-     * The website of the plugin.
-     * 
-     * Since: 0.2 
-     **/
-    g_object_class_install_property (object_class,
-                                     PROP_SITE,
-                                     g_param_spec_string ("site",
-                                                          NULL, NULL,
-                                                          NULL,
-                                                          G_PARAM_READWRITE|
-							  G_PARAM_CONSTRUCT_ONLY));
-							
-    /**
-     * ParolePlugin:configurable:
-     * 
-     * 
-     * Since: 0.2 
-     **/
-    g_object_class_install_property (object_class,
-                                     PROP_CONFIGURABLE,
-                                     g_param_spec_boolean ("configurable",
-                                                           NULL, NULL,
-                                                           FALSE,
-                                                           G_PARAM_READWRITE));
-							  
-    g_type_class_add_private (klass, sizeof (ParolePluginPrivate));
-}
-
-static void
-parole_plugin_init (ParolePlugin *plugin)
-{
-    ParolePluginPrivate *priv;
-    
-    priv = PAROLE_PLUGIN_GET_PRIVATE (plugin);
-    
-    priv->title  = NULL;
-    priv->desc   = NULL;
-    priv->author = NULL;
-    priv->site   = NULL;
-    priv->packed = FALSE;
-    priv->widget = NULL;
-    priv->configurable = FALSE;
-    
-    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);
-		      
-    priv->gst_sig2 = g_signal_connect (G_OBJECT (priv->gst), "media-tag",
-				       G_CALLBACK (parole_plugin_media_tag_cb), plugin);
-				       
-    priv->gst_sig3 = g_signal_connect (G_OBJECT (priv->gst), "buffering",
-				       G_CALLBACK (parole_plugin_buffering_changed_cb), plugin);
-				       
-    priv->gst_sig4 = g_signal_connect (G_OBJECT (priv->gst), "media-progressed",
-				       G_CALLBACK (parole_plugin_media_progressed_cb), plugin);
-}
-
-static void parole_plugin_set_property (GObject *object,
-					guint prop_id,
-				        const GValue *value,
-					GParamSpec *pspec)
-{
-    ParolePlugin *plugin;
-    plugin = PAROLE_PLUGIN (object);
-
-    switch (prop_id)
-    {
-	case PROP_TITLE:
-	    PAROLE_PLUGIN_GET_PRIVATE (plugin)->title = g_value_dup_string (value);
-	    break;
-	case PROP_DESC:
-	    PAROLE_PLUGIN_GET_PRIVATE (plugin)->desc = g_value_dup_string (value);
-	    break;
-	case PROP_AUTHOR:
-	    PAROLE_PLUGIN_GET_PRIVATE (plugin)->author = g_value_dup_string (value);
-	    break;
-	case PROP_SITE:
-	    PAROLE_PLUGIN_GET_PRIVATE (plugin)->site = g_value_dup_string (value);
-	    break;
-	case PROP_CONFIGURABLE:
-	    PAROLE_PLUGIN_GET_PRIVATE (plugin)->configurable = g_value_get_boolean (value);
-	    break;
-	default:
-            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-            break;
-    }
-}
-
-static void parole_plugin_get_property (GObject *object,
-					guint prop_id,
-					GValue *value,
-	
-					GParamSpec *pspec)
-{
-    ParolePlugin *plugin;
-    plugin = PAROLE_PLUGIN (object);
-
-    switch (prop_id)
-    {
-	case PROP_TITLE:
-	    g_value_set_string (value, PAROLE_PLUGIN_GET_PRIVATE (plugin)->title);
-	    break;
-	case PROP_DESC:
-	    g_value_set_string (value, PAROLE_PLUGIN_GET_PRIVATE (plugin)->desc);
-	    break;
-	case PROP_AUTHOR:
-	    g_value_set_string (value, PAROLE_PLUGIN_GET_PRIVATE (plugin)->author);
-	    break;
-	case PROP_SITE:
-	    g_value_set_string (value, PAROLE_PLUGIN_GET_PRIVATE (plugin)->site);
-	    break;
-	case PROP_CONFIGURABLE:
-	    g_value_set_boolean (value, PAROLE_PLUGIN_GET_PRIVATE (plugin)->configurable);
-	    break;
-	default:
-            G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec);
-            break;
-    }
-}
-
-static void
-parole_plugin_finalize (GObject *object)
-{
-    ParolePlugin *plugin;
-    ParolePluginPrivate *priv;
-
-    plugin = PAROLE_PLUGIN (object);
-    
-    priv = PAROLE_PLUGIN_GET_PRIVATE (plugin);
-    
-    if ( G_IS_OBJECT (priv->gst) )
-    {
-	if (g_signal_handler_is_connected (priv->gst, priv->gst_sig1)) 
-	    g_signal_handler_disconnect (priv->gst, priv->gst_sig1);
-
-	if ( g_signal_handler_is_connected (priv->gst, priv->gst_sig2)) 
-	    g_signal_handler_disconnect (priv->gst, priv->gst_sig2);
-	    
-	if ( g_signal_handler_is_connected (priv->gst, priv->gst_sig3)) 
-	    g_signal_handler_disconnect (priv->gst, priv->gst_sig3);
-	    
-	if ( g_signal_handler_is_connected (priv->gst, priv->gst_sig4)) 
-	    g_signal_handler_disconnect (priv->gst, priv->gst_sig4);
-    }
-    
-    if ( priv->title )
-	g_free (priv->title);
-	
-    if ( priv->desc )
-	g_free (priv->desc);
-	
-    if ( priv->author )
-	g_free (priv->author);
-	
-    if ( priv->site )
-	g_free (priv->site);
-	
-    if ( priv->packed && GTK_IS_WIDGET (priv->widget))
-	gtk_widget_destroy (GTK_WIDGET (priv->widget));
-
-    G_OBJECT_CLASS (parole_plugin_parent_class)->finalize (object);
-}
-
-
-/**
- * parole_plugin_new:
- * @title: title.
- * 
- * 
- * 
- * Returns: A new #ParolePlugin object.
- **/
-ParolePlugin *
-parole_plugin_new (const gchar *title, const gchar *desc, const gchar *author, const gchar *website)
-{
-    ParolePlugin *plugin = NULL;
-    
-    plugin = g_object_new (PAROLE_TYPE_PLUGIN, 
-			   "title", title, 
-			   "description", desc,
-			   "author", author,
-			   "site", website,
-			   NULL);
-    return plugin;
-}
-
-/**
- * parole_plugin_get_main_window:
- * @plugin: a #ParolePlugin.
- * 
- * Get the main window of the media player.
- * 
- * Returns: the main window widget.
- **/
-GtkWidget *parole_plugin_get_main_window (ParolePlugin *plugin)
-{
-    ParolePluginPrivate *priv;
-    
-    g_return_val_if_fail (PAROLE_IS_PLUGIN (plugin), NULL);
-    
-    priv = PAROLE_PLUGIN_GET_PRIVATE (plugin);
-    
-    return gtk_widget_get_toplevel (GTK_WIDGET (priv->gst));
-}
-
-/**
- * parole_plugin_pack_widget:
- * @plugin: a #ParolePlugin.
- * @widget: a #GtkWidget.
- * @container: a ParolePluginContainer type.
- * 
- * This function inserts a tab containing the @widget, the tab can be either
- * on the playlist when PAROLE_PLUGIN_CONTAINER_PLAYLIST is specified or in the 
- * main view when PAROLE_PLUGIN_CONTAINER_VIEW is specified.
- *
- * 
- * Note: You can call this function only one time.
- **/
-void parole_plugin_pack_widget (ParolePlugin *plugin, GtkWidget *widget, ParolePluginContainer container)
-{
-    ParolePluginsManager *manager;
-    ParolePluginPrivate *priv;
-    
-    g_return_if_fail (PAROLE_IS_PLUGIN (plugin));
-    
-    priv = PAROLE_PLUGIN_GET_PRIVATE (plugin);
-    
-    g_return_if_fail (priv->packed == FALSE);
-    
-    manager = parole_plugins_manager_get (TRUE);
-
-    parole_plugins_manager_pack (manager, plugin, widget, container);
-
-    g_object_unref (manager);
-    
-    priv->packed = TRUE;
-    priv->widget = widget;
-}
-
-/**
- * parole_plugin_get_state:
- * @plugin: a #ParolePlugin.
- * 
- * 
- * 
- * Returns: The current state of the media player.
- **/
-ParoleState parole_plugin_get_state (ParolePlugin *plugin)
-{
-    ParolePluginPrivate *priv;
-    
-    g_return_val_if_fail (PAROLE_IS_PLUGIN (plugin), PAROLE_STATE_STOPPED);
-    
-    priv = PAROLE_PLUGIN_GET_PRIVATE (plugin);
-    
-    return parole_gst_get_state (priv->gst);
-}
-
-/**
- * parole_plugin_get_is_configurable:
- * @plugin: a #ParolePlugin.
- * 
- * 
- * 
- * Returns: Whether the plugin is configurable.
- **/
-gboolean parole_plugin_get_is_configurable (ParolePlugin *plugin)
-{
-    g_return_val_if_fail (PAROLE_IS_PLUGIN (plugin), FALSE);
-    
-    return PAROLE_PLUGIN_GET_PRIVATE (plugin)->configurable;
-}
-
-/**
- * parole_plugin_set_is_configurable:
- * @plugin: a #ParolePlugin.
- * 
- * 
- * 
- **/
-void parole_plugin_set_is_configurable (ParolePlugin *plugin, gboolean is_configurable)
-{
-    g_return_if_fail (PAROLE_IS_PLUGIN (plugin));
-    
-    PAROLE_PLUGIN_GET_PRIVATE (plugin)->configurable = is_configurable;
-}
-
-/**
- * parole_plugin_play_uri:
- * @plugin: a #ParolePlugin.
- * @uri: uri of the file to play.
- * 
- * Play a uri.
- * 
- * Returns: TRUE on success, FALSE otherwise.
- **/
-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, NULL);
-    
-    return TRUE;
-}
-
-/**
- * parole_plugin_pause_playback:
- * @plugin: a #ParolePlugin.
- * 
- * Causes the media player to pause any playback.
- * 
- * Returns: TRUE on success, FALSE otherwise.
- **/
-gboolean parole_plugin_pause_playback (ParolePlugin *plugin)
-{
-    g_return_val_if_fail (PAROLE_IS_PLUGIN (plugin), FALSE);
-    
-    parole_gst_pause (PAROLE_PLUGIN_GET_PRIVATE (plugin)->gst);
-    
-    return TRUE;
-}
-
-/**
- * parole_plugin_pause_playback:
- * @plugin: a #ParolePlugin.
- * 
- * Causes the media player to resume playing the currently paused stream.
- * 
- * Returns: TRUE on success, FALSE otherwise.
- **/
-gboolean  parole_plugin_resume_playback (ParolePlugin *plugin)
-{
-    g_return_val_if_fail (PAROLE_IS_PLUGIN (plugin), FALSE);
-    
-    parole_gst_resume (PAROLE_PLUGIN_GET_PRIVATE (plugin)->gst);
-    
-    return TRUE;
-}	
-
-/**
- * parole_plugin_stop_playback:
- * @plugin: a #ParolePlugin.
- * 
- * Causes the media player to stop any playback.
- * 
- * Returns: TRUE on success, FALSE otherwise.
- **/
-gboolean parole_plugin_stop_playback (ParolePlugin *plugin)
-{
-    g_return_val_if_fail (PAROLE_IS_PLUGIN (plugin), FALSE);
-    
-    parole_gst_stop (PAROLE_PLUGIN_GET_PRIVATE (plugin)->gst);
-    
-    return TRUE;
-}
-
-/**
- * parole_plugin_seek:
- * @plugin: a #ParolePlugin.
- * @pos: position.
- * 
- * Seek the current playing stream.
- * 
- * Returns: False is the stream is not seekable or an error occurs, TRUE otherwise.
- **/
-gboolean parole_plugin_seek (ParolePlugin *plugin, gdouble pos)
-{
-    g_return_val_if_fail (PAROLE_IS_PLUGIN (plugin), FALSE);
-    
-    parole_gst_seek (PAROLE_PLUGIN_GET_PRIVATE (plugin)->gst, pos);
-    
-    return TRUE;
-}
diff --git a/src/parole-plugins-manager.c b/src/parole-plugins-manager.c
index 3b10375..7db3689 100644
--- a/src/parole-plugins-manager.c
+++ b/src/parole-plugins-manager.c
@@ -30,13 +30,29 @@
 
 #include <libxfce4util/libxfce4util.h>
 
+#include <parole/parole-provider-plugin.h>
+
 #include "interfaces/plugins_ui.h"
 
 #include "parole-builder.h"
 #include "parole-rc-utils.h"
+#include "parole-utils.h"
 #include "parole-plugins-manager.h"
 #include "parole-module.h"
 
+#include "gst/parole-gst.h"
+
+#define PAROLE_PLUGIN_EXT = ".desktop"
+
+typedef struct 
+{
+    gchar *name;
+    gchar *authors;
+    gchar *desc;
+    gchar *website;
+    
+} ParolePluginInfo;
+
 typedef struct
 {
     ParolePluginsManager *manager;
@@ -87,13 +103,16 @@ struct ParolePluginsManagerPrivate
     gboolean   load_plugins;
 };
 
+static gpointer parole_plugins_manager_object = NULL;
+
 G_DEFINE_TYPE (ParolePluginsManager, parole_plugins_manager, G_TYPE_OBJECT)
 
 enum
 {
     COL_ACTIVE,
     COL_PLUGIN,
-    COL_DATA
+    COL_MODULE,
+    COL_INFO
 };
 
 enum
@@ -106,41 +125,62 @@ void parole_plugins_manager_pref_response_cb		(GtkDialog *dialog,
 							 gint reponse_id,
 							 PrefData *pref)
 {
+    GtkTreeIter   iter;
+    gboolean valid;
+
+    for ( valid = gtk_tree_model_get_iter_first (GTK_TREE_MODEL (pref->store), &iter);
+	  valid;
+	  valid = gtk_tree_model_iter_next (GTK_TREE_MODEL (pref->store), &iter) )
+    {
+	ParolePluginInfo *info;
+	gtk_tree_model_get (GTK_TREE_MODEL (pref->store),
+			    &iter,
+			    COL_INFO, &info,
+			    -1);
+	g_free (info->name);
+	g_free (info->authors);
+	g_free (info->website);
+	g_free (info->desc);
+	g_free (info);
+    }
+    
     gtk_widget_destroy (GTK_WIDGET (dialog));
     g_free (pref);
 }
 
-static ParoleModule *
-parole_plugins_manager_get_selected_module (PrefData *pref)
+static void
+parole_plugins_manager_get_selected_module_data (PrefData *pref, ParoleProviderModule **module, ParolePluginInfo **info)
 {
-    ParoleModule *module;
+    GtkTreeModel *model;
     GtkTreeSelection *sel;
-    GtkTreeModel     *model;
     GtkTreeIter       iter;
 
     sel = gtk_tree_view_get_selection (GTK_TREE_VIEW (pref->view));
 
     if ( !gtk_tree_selection_get_selected (sel, &model, &iter))
-        return NULL;
+    {
+	*module = NULL;
+	*info = NULL;
+        return;
+    }
 
     gtk_tree_model_get (model,
                         &iter,
-                        COL_DATA,
-                        &module,
+                        COL_MODULE, module,
+			COL_INFO, info,
                         -1);
-    return module;
 }
 
 void parole_plugins_manager_show_configure (GtkButton *button, PrefData *pref)
 {
-    ParoleModule *module;
+    ParoleProviderModule *module;
     
-    module = parole_plugins_manager_get_selected_module (pref);
+    parole_plugins_manager_get_selected_module_data (pref, &module, NULL);
     
-    if ( !module )
+    if ( G_UNLIKELY (!module) )
 	return;
 	
-    g_signal_emit_by_name (G_OBJECT (module->plugin), "configure", pref->window);
+    parole_provider_plugin_configure (PAROLE_PROVIDER_PLUGIN (module), pref->window);
 }
 
 static void
@@ -191,7 +231,7 @@ parole_plugins_manager_cell_toggled_cb (GtkCellRendererToggle *cell_renderer,
 					gchar *path_str, 
 					PrefData *pref)
 {
-    ParoleModule *module;
+    ParoleProviderModule *module;
     GtkTreeIter iter;
     GtkTreePath *path;
     gboolean active;
@@ -202,13 +242,18 @@ parole_plugins_manager_cell_toggled_cb (GtkCellRendererToggle *cell_renderer,
     
     gtk_tree_model_get (GTK_TREE_MODEL (pref->store), &iter, 
 		        COL_ACTIVE, &active, 
-			COL_DATA, &module,
+			COL_MODULE, &module,
 			-1);
     
     active ^= 1;
     
     if ( pref->manager->priv->load_plugins )
-	parole_module_set_active (module, active);
+    {
+	if ( active )
+	    g_type_module_use (G_TYPE_MODULE (module));
+	else
+	    g_type_module_unuse (G_TYPE_MODULE (module));
+    }
     
     gtk_list_store_set (GTK_LIST_STORE (pref->store), &iter, 
 			COL_ACTIVE, active,
@@ -222,36 +267,39 @@ parole_plugins_manager_cell_toggled_cb (GtkCellRendererToggle *cell_renderer,
 void parole_plugins_manager_tree_cursor_changed_cb (GtkTreeView *view,
 						    PrefData *pref)
 {
-    ParoleModule *module;
+    ParoleProviderModule *module;
+    ParolePluginInfo *info;
     gboolean configurable = FALSE;
+    const gchar *site;
+    
 #if GTK_CHECK_VERSION (2, 18, 0)
     gchar *site_text;
 #endif
 
-    module = parole_plugins_manager_get_selected_module (pref);
+    parole_plugins_manager_get_selected_module_data (pref, &module, &info);
     
-    if ( !module )
+    if ( G_UNLIKELY (!module || !info))
 	return;
     
-    gtk_label_set_markup (GTK_LABEL (pref->desc), module->desc->desc);
-    gtk_label_set_markup (GTK_LABEL (pref->author), module->desc->author);
+    site = info->website;
+    
+    gtk_label_set_markup (GTK_LABEL (pref->desc), info->desc);
+    gtk_label_set_markup (GTK_LABEL (pref->author), info->authors);
     
 #if GTK_CHECK_VERSION (2, 18, 0)
-    site_text = g_strdup_printf ("<a href=\"%s\">%s</a>", module->desc->site, _("Visit Website"));
+    site_text = g_strdup_printf ("<a href=\"%s\">%s</a>", site, _("Visit Website"));
     gtk_label_set_markup (GTK_LABEL (pref->site), site_text);
     g_free (site_text);
 
 #else
-    gtk_link_button_set_uri (GTK_LINK_BUTTON (pref->site), module->desc->site);
+    gtk_link_button_set_uri (GTK_LINK_BUTTON (pref->site), site);
 #endif
 
-    gtk_widget_set_tooltip_text (pref->site, module->desc->site);
+    gtk_widget_set_tooltip_text (pref->site, site);
 
-    if ( module->enabled )
+    if ( parole_provider_plugin_get_is_active (PAROLE_PROVIDER_PLUGIN (module) ) )
     {
-	g_object_get (G_OBJECT (module->plugin),
-		      "configurable", &configurable,
-		      NULL);
+	configurable = parole_provider_plugin_get_is_configurable (PAROLE_PROVIDER_PLUGIN (module));
     }
     
     gtk_widget_set_sensitive (pref->configure, configurable);
@@ -260,11 +308,13 @@ void parole_plugins_manager_tree_cursor_changed_cb (GtkTreeView *view,
 static void
 parole_plugins_manager_unload_all (gpointer data, gpointer user_data)
 {
-    ParoleModule *module;
+    ParoleProviderModule *module;
     
-    module = PAROLE_MODULE (data);
-    
-    g_type_module_unuse (G_TYPE_MODULE (data));
+    module = PAROLE_PROVIDER_MODULE (data);
+    if ( parole_provider_plugin_get_is_active (PAROLE_PROVIDER_PLUGIN (module)) )
+    {
+	g_type_module_unuse (G_TYPE_MODULE (data));
+    }
     g_object_unref (G_OBJECT (module));
 }
 
@@ -286,6 +336,54 @@ parole_plugins_manager_open_plugins_website (GtkLinkButton *bt, const gchar *lin
 }
 #endif
 
+static ParolePluginInfo *
+parole_plugins_manager_get_plugin_info (const gchar *desktop_file)
+{
+    ParolePluginInfo *info;
+    GKeyFile *file;
+    
+    info = g_new0 (ParolePluginInfo, 1);
+    
+    info->name = NULL;
+    info->website = NULL;
+    info->desc = NULL;
+    info->authors = NULL;
+    
+    file = g_key_file_new ();
+    
+    if ( !g_key_file_load_from_file (file, desktop_file , G_KEY_FILE_NONE, NULL) )
+    {
+	g_warning ("Error opening file : %s", desktop_file);
+	goto out;
+    }
+    
+    info->name = g_key_file_get_string (file, "Parole Plugin", "Name", NULL);
+    
+    if ( !info->name )
+	info->name = g_strdup (_("Unknown"));
+    
+    
+    info->desc = g_key_file_get_string (file, "Parole Plugin", "Description", NULL);
+    
+    if ( !info->desc )
+	info->desc = g_strdup ("");
+	
+    info->authors = g_key_file_get_string (file, "Parole Plugin", "Authors", NULL);
+    
+    if ( !info->authors )
+	info->authors = g_strdup ("");
+	
+    info->website = g_key_file_get_string (file, "Parole Plugin", "Website", NULL);
+    
+    if ( !info->website )
+	info->website = g_strdup ("");
+	
+out:
+    g_key_file_free (file);
+    
+    return info;
+}
+
 static void
 parole_plugins_manager_show_plugins_pref (GtkWidget *widget, ParolePluginsManager *manager)
 {
@@ -328,18 +426,19 @@ parole_plugins_manager_show_plugins_pref (GtkWidget *widget, ParolePluginsManage
 
     for ( i = 0; i < manager->priv->array->len; i++)
     {
-	ParoleModule *module;
+	ParoleProviderModule *module;
+	ParolePluginInfo *info;
 	module = g_ptr_array_index (manager->priv->array, i);
 	
-	if ( module->desc )
-	{
-	    gtk_list_store_append (pref->store, &iter);
-	    gtk_list_store_set (pref->store, &iter, 
-			        COL_ACTIVE, module->enabled, 
-				COL_PLUGIN, module->desc->title, 
-				COL_DATA, module,
-				-1);
-	}
+	info = parole_plugins_manager_get_plugin_info (module->desktop_file);
+	
+	gtk_list_store_append (pref->store, &iter);
+	gtk_list_store_set (pref->store, &iter, 
+			    COL_ACTIVE, parole_provider_plugin_get_is_active (PAROLE_PROVIDER_PLUGIN (module)),
+			    COL_PLUGIN, info->name, 
+			    COL_MODULE, module,
+			    COL_INFO, info,
+			    -1);
     }
     
     gtk_builder_connect_signals (builder, pref);
@@ -416,13 +515,115 @@ static void parole_plugins_manager_get_property (GObject *object,
     }
 }
 
+static gchar * 
+parole_plugins_manager_get_module_name (const gchar *desktop_file)
+{
+    GKeyFile *file;
+    gchar *module_name = NULL;
+    gchar *library_name = NULL;
+
+    file = g_key_file_new ();
+    
+    if ( !g_key_file_load_from_file (file, desktop_file, G_KEY_FILE_NONE, NULL) )
+    {
+	g_warning ("Error opening file : %s", desktop_file);
+	goto out;
+    }
+    
+    module_name = g_key_file_get_string (file, "Parole Plugin", "Module", NULL);
+    library_name = g_strdup_printf ("%s.%s", module_name, G_MODULE_SUFFIX);
+    g_free (module_name);
+out:
+    g_key_file_free (file);
+    
+    return library_name;
+}
+
+static void
+parole_plugins_manager_load_plugins (ParolePluginsManager *manager)
+{
+    gchar **plugins_rc;
+    guint len = 0, i, j;
+    
+    plugins_rc = parole_rc_read_entry_list ("plugins", PAROLE_RC_GROUP_PLUGINS);
+    
+    if ( plugins_rc && plugins_rc[0] )
+	len = g_strv_length (plugins_rc);
+
+    for ( j = 0; j < manager->priv->array->len; j++)
+    {
+	GTypeModule *module;
+	module = g_ptr_array_index (manager->priv->array, j);
+	
+	for ( i = 0; i < len; i++)
+	{
+	    if ( !g_strcmp0 (plugins_rc[i], module->name) )
+	    {
+		TRACE ("Loading plugin :%s", module->name);
+		if ( !g_type_module_use (module) )
+		{
+		    parole_plugins_manager_save_rc (module->name, FALSE);
+		    g_ptr_array_remove (manager->priv->array, module);
+		    g_object_unref (module);
+		}
+		break;
+	    }
+	}
+    }
+}
+
+static void
+parole_plugins_manager_construct (GObject *object)
+{
+    ParolePluginsManager *manager;
+    GDir *dir;
+    GError *error = NULL;
+    const gchar *name;
+    
+    manager = PAROLE_PLUGINS_MANAGER (object);
+    
+    dir = g_dir_open (PAROLE_PLUGINS_DATA_DIR, 0, &error);
+    
+    if ( error )
+    {
+	g_critical ("Error opening plugins data dir: %s", error->message);
+	g_error_free (error);
+	return;
+    }
+    
+    while ( (name = g_dir_read_name (dir) ))
+    {
+	gchar *library_name;
+	gchar *desktop_file;
+    
+	desktop_file = g_build_filename (PAROLE_PLUGINS_DATA_DIR, name, NULL);
+	library_name = parole_plugins_manager_get_module_name (desktop_file);
+	
+	if ( library_name )
+	{
+	    gchar *library_path;
+	    ParoleProviderModule *module;
+	    library_path = g_build_filename (PAROLE_PLUGINS_DIR, library_name, NULL);
+	    module = parole_provider_module_new (library_path, desktop_file);
+	    g_ptr_array_add (manager->priv->array, module);
+	    g_free (library_name);
+	    g_free (library_path);
+	}
+	g_free (desktop_file);
+    }
+    g_dir_close (dir);
+    
+    if ( manager->priv->load_plugins )
+	parole_plugins_manager_load_plugins (manager);
+}
+
 static void
 parole_plugins_manager_class_init (ParolePluginsManagerClass *klass)
 {
     GObjectClass *object_class = G_OBJECT_CLASS (klass);
 
-    object_class->finalize = parole_plugins_manager_finalize;
-    
+    object_class->finalize     = parole_plugins_manager_finalize;
+    object_class->constructed  = parole_plugins_manager_construct;
     object_class->set_property = parole_plugins_manager_set_property;
     object_class->get_property = parole_plugins_manager_get_property;
     
@@ -490,10 +691,8 @@ parole_plugins_manager_finalize (GObject *object)
 }
 
 ParolePluginsManager *
-parole_plugins_manager_get (gboolean load_plugins)
+parole_plugins_manager_new (gboolean load_plugins)
 {
-    static gpointer parole_plugins_manager_object = NULL;
-    
     if ( G_LIKELY (parole_plugins_manager_object != NULL) )
     {
 	g_object_ref (parole_plugins_manager_object);
@@ -509,70 +708,18 @@ parole_plugins_manager_get (gboolean load_plugins)
     return PAROLE_PLUGINS_MANAGER (parole_plugins_manager_object);
 }
 
-void 
-parole_plugins_manager_load_plugins (ParolePluginsManager *manager)
+ParolePluginsManager *
+parole_plugins_manager_get (void)
 {
-    ParoleModule *module;
-    GDir *dir;
-    const gchar *name;
-    gchar *path;
-    GError *error = NULL;
-    gchar **plugins_rc;
-    guint len = 0, i = 0;
-    
-    plugins_rc = parole_rc_read_entry_list ("plugins", PAROLE_RC_GROUP_PLUGINS);
-    
-    if ( plugins_rc && plugins_rc[0] )
-	len = g_strv_length (plugins_rc);
-    
-    dir = g_dir_open (PAROLE_PLUGINS_DIR, 0, &error);
-    
-    if ( error )
-    {
-	g_critical ("Error opening plugins dir: %s", error->message);
-	g_error_free (error);
-	return;
-    }
-    
-    while ( (name = g_dir_read_name (dir) ))
-    {
-	if ( g_str_has_suffix (name, "." G_MODULE_SUFFIX) )
-	{
-	    path = g_build_filename (PAROLE_PLUGINS_DIR, name, NULL);
-	    TRACE ("loading module with path %s", path);
-	    
-	    module = parole_module_new (path);
-
-	    if ( g_type_module_use (G_TYPE_MODULE (module)) )
-	    {
-		g_ptr_array_add (manager->priv->array, module);
-		
-		for ( i = 0; i < len; i++)
-		{
-		    if ( !g_strcmp0 (plugins_rc[i], path) && manager->priv->load_plugins )
-		    {
-			parole_module_set_active (module, TRUE);
-			break;
-		    }
-		}
-	    }
-	    else
-		g_object_unref (module);
-	    g_free (path);
-	}
-    }
-    g_dir_close (dir);
+    if ( G_UNLIKELY (parole_plugins_manager_object == NULL ) )
+	g_error ("Plugins Manager is NULL");
+	
+    return PAROLE_PLUGINS_MANAGER (parole_plugins_manager_object);
 }
 
-void parole_plugins_manager_pack (ParolePluginsManager *manager, ParolePlugin *plugin,
-				  GtkWidget *widget, ParolePluginContainer container)
+void 
+parole_plugins_manager_pack (ParolePluginsManager *manager, GtkWidget *widget, const gchar *title, ParolePluginContainer container)
 {
-    gchar *title;
-    
-    g_object_get (G_OBJECT (plugin),
-		  "title", &title,
-		  NULL);
-    
     if ( container == PAROLE_PLUGIN_CONTAINER_PLAYLIST )
     {
 	gtk_notebook_append_page (GTK_NOTEBOOK (manager->priv->list_nt), widget, gtk_label_new (title));
@@ -583,8 +730,4 @@ void parole_plugins_manager_pack (ParolePluginsManager *manager, ParolePlugin *p
 	gtk_notebook_append_page (GTK_NOTEBOOK (manager->priv->main_nt), widget, gtk_label_new (title));
 	gtk_widget_show_all (widget);
     }
-    
-    if ( title )
-	g_free (title);
-	
 }
diff --git a/src/parole-plugins-manager.h b/src/parole-plugins-manager.h
index 130ba37..ec22070 100644
--- a/src/parole-plugins-manager.h
+++ b/src/parole-plugins-manager.h
@@ -22,7 +22,7 @@
 #define __PAROLE_PLUGINS_MANAGER_H
 
 #include <glib-object.h>
-#include "parole-plugin.h"
+#include <parole/parole-provider-player.h>
 
 G_BEGIN_DECLS
 
@@ -47,13 +47,13 @@ typedef struct
 
 GType        			    parole_plugins_manager_get_type       (void) G_GNUC_CONST;
 
-ParolePluginsManager               *parole_plugins_manager_get            (gboolean load_plugins);
+ParolePluginsManager               *parole_plugins_manager_new            (gboolean load_plugins);
 
-void				    parole_plugins_manager_load_plugins	  (ParolePluginsManager *manager);
+ParolePluginsManager 		   *parole_plugins_manager_get 		  (void);
 
-void				    parole_plugins_manager_pack		  (ParolePluginsManager *manager,
-									   ParolePlugin *plugin,
-									   GtkWidget *widget,
+void 				    parole_plugins_manager_pack 	  (ParolePluginsManager *manager, 
+									   GtkWidget *widget, 
+									   const gchar *title,
 									   ParolePluginContainer container);
 
 G_END_DECLS
diff --git a/src/parole-statusbar.c b/src/parole-statusbar.c
index 9563b09..6929d8d 100644
--- a/src/parole-statusbar.c
+++ b/src/parole-statusbar.c
@@ -32,14 +32,15 @@
 
 #include "parole-builder.h"
 #include "parole-statusbar.h"
-#include "parole-plugin.h"
+
+#include "parole-gst.h"
 
 #define PAROLE_STATUSBAR_GET_PRIVATE(o) \
 (G_TYPE_INSTANCE_GET_PRIVATE ((o), PAROLE_TYPE_STATUSBAR, ParoleStatusbarPrivate))
 
 struct ParoleStatusbarPrivate
 {
-    ParolePlugin *plugin;
+    ParoleGst    *gst;
     GtkWidget    *box;
     GtkWidget    *progress;
     GtkWidget    *label_text;
@@ -68,15 +69,15 @@ parole_statusbar_set_buffering (ParoleStatusbar *bar, gint percentage)
 }
 
 static void 
-parole_statusbar_set_duration (ParoleStatusbar *bar, ParoleState state, gdouble position)
+parole_statusbar_set_duration (ParoleStatusbar *bar, ParoleMediaState state, gdouble position)
 {
     gchar *text = NULL;
 
-    if ( state == PAROLE_STATE_STOPPED )
+    if ( state == PAROLE_MEDIA_STATE_STOPPED )
     {
 	gtk_label_set_text (GTK_LABEL (bar->priv->label_duration), _("Stopped"));
     }
-    else if ( state == PAROLE_STATE_PLAYBACK_FINISHED )
+    else if ( state == PAROLE_MEDIA_STATE_FINISHED )
     {
 	gtk_label_set_text (GTK_LABEL (bar->priv->label_duration), _("Finished"));
     }
@@ -85,7 +86,7 @@ parole_statusbar_set_duration (ParoleStatusbar *bar, ParoleState state, gdouble
 	if ( bar->priv->duration != 0)
 	{
 	    text = g_strdup_printf ("%s %4.2f/%4.2f", 
-				    state == PAROLE_STATE_PAUSED ? _("Paused") : _("Playing"), position, bar->priv->duration);
+				    state == PAROLE_MEDIA_STATE_PAUSED ? _("Paused") : _("Playing"), position, bar->priv->duration);
 	}
 	if ( text )
 	{
@@ -93,18 +94,18 @@ parole_statusbar_set_duration (ParoleStatusbar *bar, ParoleState state, gdouble
 	    g_free (text);
 	}
 	else
-	    gtk_label_set_text (GTK_LABEL (bar->priv->label_duration), state == PAROLE_STATE_PAUSED ? _("Paused") : ("Playing"));
+	    gtk_label_set_text (GTK_LABEL (bar->priv->label_duration), state == PAROLE_MEDIA_STATE_PAUSED ? _("Paused") : ("Playing"));
     }
 }
 
-static void parole_statusbar_set_text (ParoleStatusbar *bar, const ParoleStream *stream, ParoleState state)
+static void parole_statusbar_set_text (ParoleStatusbar *bar, const ParoleStream *stream, ParoleMediaState state)
 {
     gchar *text = NULL;
     gchar *title = NULL;
     gchar *uri = NULL;
     gboolean live;
     
-    if ( state >= PAROLE_STATE_PAUSED )
+    if ( state >= PAROLE_MEDIA_STATE_PAUSED )
     {
 	g_object_get (G_OBJECT (stream),
 		      "title", &title,
@@ -155,10 +156,10 @@ out:
 }
 
 static void
-parole_statusbar_state_changed_cb (ParolePlugin *gst, const ParoleStream *stream, 
-				   ParoleState state, ParoleStatusbar *statusbar)
+parole_statusbar_state_changed_cb (ParoleGst *gst, const ParoleStream *stream, 
+				   ParoleMediaState state, ParoleStatusbar *statusbar)
 {
-    if ( state >= PAROLE_STATE_PAUSED )
+    if ( state >= PAROLE_MEDIA_STATE_PAUSED )
     {
 	g_object_get (G_OBJECT (stream),
 		      "duration", &statusbar->priv->duration,
@@ -170,7 +171,7 @@ parole_statusbar_state_changed_cb (ParolePlugin *gst, const ParoleStream *stream
 	statusbar->priv->pos = 0;
     }
 	
-    if ( state < PAROLE_STATE_PAUSED ) 
+    if ( state < PAROLE_MEDIA_STATE_PAUSED ) 
 	gtk_widget_hide (statusbar->priv->progress);
 	
     parole_statusbar_set_text (statusbar, stream, state);
@@ -178,29 +179,29 @@ parole_statusbar_state_changed_cb (ParolePlugin *gst, const ParoleStream *stream
 }
 
 static void
-parole_statusbar_tag_message_cb (ParolePlugin *gst, const ParoleStream *stream, ParoleStatusbar *statusbar)
+parole_statusbar_tag_message_cb (ParoleGst *gst, const ParoleStream *stream, ParoleStatusbar *statusbar)
 {
-    ParoleState state;
+    ParoleMediaState state;
     
-    state = parole_plugin_get_state (statusbar->priv->plugin);
+    state = parole_gst_get_state (statusbar->priv->gst);
     
     parole_statusbar_set_text (statusbar, stream, state);
 }
 
 static void
-parole_statusbar_progressed_cb (ParolePlugin *gst, const ParoleStream *stream, 
+parole_statusbar_progressed_cb (ParoleGst *gst, const ParoleStream *stream, 
 		 	        gdouble value, ParoleStatusbar *statusbar)
 {
-    ParoleState state;
+    ParoleMediaState state;
     
-    state = parole_plugin_get_state (statusbar->priv->plugin);
+    state = parole_gst_get_state (statusbar->priv->gst);
     statusbar->priv->pos = value;
     
     parole_statusbar_set_duration (statusbar, state, value);
 }
 
 static void
-parole_statusbar_buffering_cb (ParolePlugin *gst, const ParoleStream *stream, gint percentage, ParoleStatusbar *statusbar)
+parole_statusbar_buffering_cb (ParoleGst *gst, const ParoleStream *stream, gint percentage, ParoleStatusbar *statusbar)
 {
     parole_statusbar_set_buffering (statusbar, percentage);
     
@@ -219,18 +220,18 @@ parole_statusbar_finalize (GObject *object)
 
     statusbar = PAROLE_STATUSBAR (object);
     
-    g_object_unref (statusbar->priv->plugin);
-
     G_OBJECT_CLASS (parole_statusbar_parent_class)->finalize (object);
 }
 
 static void
 parole_statusbar_class_init (ParoleStatusbarClass *klass)
 {
-    GObjectClass *object_class = G_OBJECT_CLASS (klass);
-
-    object_class->finalize = parole_statusbar_finalize;
-
+    GObjectClass *gobject_class;
+    
+    gobject_class = G_OBJECT_CLASS (klass);
+    
+    gobject_class->finalize = parole_statusbar_finalize;
+    
     g_type_class_add_private (klass, sizeof (ParoleStatusbarPrivate));
 }
 
@@ -242,7 +243,7 @@ parole_statusbar_init (ParoleStatusbar *statusbar)
     GtkBuilder *builder;
     
     statusbar->priv = PAROLE_STATUSBAR_GET_PRIVATE (statusbar);
-    statusbar->priv->plugin = parole_plugin_new (NULL, NULL, NULL, NULL);
+    statusbar->priv->gst = PAROLE_GST (parole_gst_get ());
     
     statusbar->priv->duration = 0;
     statusbar->priv->pos = 0;
@@ -281,19 +282,16 @@ parole_statusbar_init (ParoleStatusbar *statusbar)
     g_object_unref (builder);
     statusbar->priv->box = box;
     
-    /*
-     * Gst signals
-     */
-    g_signal_connect (G_OBJECT (statusbar->priv->plugin), "state-changed",
+    g_signal_connect (G_OBJECT (statusbar->priv->gst), "media-state",
 		      G_CALLBACK (parole_statusbar_state_changed_cb), statusbar);
 	
-    g_signal_connect (G_OBJECT (statusbar->priv->plugin), "progressed",
+    g_signal_connect (G_OBJECT (statusbar->priv->gst), "media-progressed",
 		      G_CALLBACK (parole_statusbar_progressed_cb), statusbar);
 		      
-    g_signal_connect (G_OBJECT (statusbar->priv->plugin), "tag-message",
+    g_signal_connect (G_OBJECT (statusbar->priv->gst), "media-tag",
 		      G_CALLBACK (parole_statusbar_tag_message_cb), statusbar);
     
-    g_signal_connect (G_OBJECT (statusbar->priv->plugin), "buffering",
+    g_signal_connect (G_OBJECT (statusbar->priv->gst), "buffering",
 		      G_CALLBACK (parole_statusbar_buffering_cb), statusbar);
     
 }
diff --git a/src/parole-utils.h b/src/parole-utils.h
index 9db205a..a26d66d 100644
--- a/src/parole-utils.h
+++ b/src/parole-utils.h
@@ -24,7 +24,7 @@
 #include <gtk/gtk.h>
 #include <gdk/gdk.h>
 
-#include "parole-file.h"
+#include <parole/parole-file.h>
 
 gint            thunar_file_compare_by_name 		(ParoleFile *file_a,
 							 ParoleFile *file_b,



More information about the Xfce4-commits mailing list