[Xfce4-commits] <parole:master> Support for playlist format in the media browser plugin.
Ali Abdallah
noreply at xfce.org
Fri Nov 27 10:02:02 CET 2009
Updating branch refs/heads/master
to ce2b8cfa71b936f086b7dec5cbc0495febf6c036 (commit)
from 43006e0f381ffa329b45543f599a48ad81c033bd (commit)
commit ce2b8cfa71b936f086b7dec5cbc0495febf6c036
Author: Ali Abdallah <ali at ali-xfce.org>
Date: Thu Nov 26 23:03:17 2009 +0100
Support for playlist format in the media browser plugin.
browser-plugin/Makefile.am | 11 +-
browser-plugin/media-plugin/main.c | 4 +-
.../media-plugin/org.parole.media.plugin.xml | 7 +
browser-plugin/media-plugin/parole-plugin-player.c | 136 ++++---
browser-plugin/media-plugin/parole-plugin-player.h | 4 +-
browser-plugin/npp_gate.cpp | 10 +-
browser-plugin/parole-plugin.c | 464 ++++++++++++++++++++
browser-plugin/parole-plugin.h | 76 ++++
browser-plugin/plugin.cpp | 220 +---------
browser-plugin/plugin.h | 40 +--
gst/parole-gst.c | 7 +-
parole/Makefile.am | 15 +-
{src => parole}/parole-debug.c | 0
{src => parole}/parole-debug.h | 0
parole/parole-filters.c | 148 +++++++
{src => parole}/parole-filters.h | 9 +-
{src => parole}/parole-pl-parser.c | 85 +++-
{src => parole}/parole-pl-parser.h | 9 +-
parole/parole.h.in | 3 +
src/Makefile.am | 8 -
src/parole-filters.c | 225 ----------
src/parole-utils.c | 78 ++++
src/parole-utils.h | 5 +
23 files changed, 1015 insertions(+), 549 deletions(-)
diff --git a/browser-plugin/Makefile.am b/browser-plugin/Makefile.am
index 09eeef2..606b622 100644
--- a/browser-plugin/Makefile.am
+++ b/browser-plugin/Makefile.am
@@ -22,12 +22,15 @@ INCLUDES = \
-fPIC \
-I$(top_builddir) \
-I$(top_srcdir) \
+ -I$(top_srcdir)/parole \
-DPACKAGE_LOCALE_DIR=\"$(localedir)\" \
-DG_LOG_DOMAIN=\"parole-browser-plugin\" \
-DLIBEXECDIR="\"$(libexecdir)\"" \
$(GECKO_CFLAGS) \
$(GTK_CFLAGS) \
$(DBUS_GLIB_CFLAGS) \
+ $(TAGLIBC_CFLAGS) \
+ $(LIBXFCE4UTIL_CFLAGS)
$(DEFINES)
install_libexecdir = $(BROWSER_PLUGIN_DIR)
@@ -38,6 +41,8 @@ install_libexec_PROGRAMS = \
parole_player_so_SOURCES = \
plugin.cpp \
plugin.h \
+ parole-plugin.c \
+ parole-plugin.h \
plugin_setup.cpp \
plugin_setup.h \
plugin_types.cpp \
@@ -51,5 +56,7 @@ parole_player_so_LDFLAGS = \
-Xcompiler \
-shared \
$(GTK_LIBS) \
- $(DBUS_GLIB_LIBS)
-
+ $(DBUS_GLIB_LIBS) \
+ $(TAGLIBC_LIBS) \
+ $(LIBXFCE4UTIL_LIBS) \
+ $(top_builddir)/parole/libparole.la
diff --git a/browser-plugin/media-plugin/main.c b/browser-plugin/media-plugin/main.c
index 8a8215c..3877588 100644
--- a/browser-plugin/media-plugin/main.c
+++ b/browser-plugin/media-plugin/main.c
@@ -109,8 +109,6 @@ int main (int argc, char **argv)
dbus_name = g_strdup_printf ("org.Parole.Media.Plugin%d", socket_id);
parole_dbus_register_name (dbus_name);
- g_assert (url != NULL);
-
plug = gtk_plug_new (socket_id);
player = parole_plugin_player_new (plug, url);
@@ -128,7 +126,7 @@ int main (int argc, char **argv)
g_error_free (error);
}
- parole_plugin_player_play (player);
+ //parole_plugin_player_play (player);
gtk_main ();
g_object_unref (player);
diff --git a/browser-plugin/media-plugin/org.parole.media.plugin.xml b/browser-plugin/media-plugin/org.parole.media.plugin.xml
index 42ed852..264373a 100644
--- a/browser-plugin/media-plugin/org.parole.media.plugin.xml
+++ b/browser-plugin/media-plugin/org.parole.media.plugin.xml
@@ -14,6 +14,13 @@
<method name="Ping">
</method>
+ <method name="PlayUrl">
+ <arg type="s" name="url" direction="in"/>
+ </method>
+
+ <signal name="Ready">
+ </signal>
+
<signal name="Exiting">
</signal>
diff --git a/browser-plugin/media-plugin/parole-plugin-player.c b/browser-plugin/media-plugin/parole-plugin-player.c
index 852d767..481fe24 100644
--- a/browser-plugin/media-plugin/parole-plugin-player.c
+++ b/browser-plugin/media-plugin/parole-plugin-player.c
@@ -98,6 +98,7 @@ enum
enum
{
SIG_EXITING,
+ SIG_READY,
LAST_SIGNAL
};
@@ -106,6 +107,17 @@ static guint signals [LAST_SIGNAL] = { 0 };
G_DEFINE_TYPE (ParolePluginPlayer, parole_plugin_player, G_TYPE_OBJECT)
static void
+parole_plugin_player_play (ParolePluginPlayer *player)
+{
+ if ( player->priv->terminate )
+ return;
+
+ player->priv->reload = FALSE;
+ player->priv->finished = FALSE;
+ parole_gst_play_uri (player->priv->gst, player->priv->url, NULL);
+}
+
+static void
parole_plugin_player_set_fullscreen_button (ParolePluginPlayer *player)
{
GtkWidget *img;
@@ -489,6 +501,45 @@ parole_plugin_player_gst_widget_button_press (GtkWidget *widget, GdkEventButton
return ret_val;
}
+static gboolean
+parole_plugin_player_window_delete_event_cb (ParolePluginPlayer *player)
+{
+ parole_plugin_player_fullscreen (player, FALSE);
+ return TRUE;
+}
+
+static gpointer *check_idle_thread (gpointer data)
+{
+ ParolePluginPlayer *player;
+
+ player = PAROLE_PLUGIN_PLAYER (data);
+
+ do
+ {
+ g_usleep (1000000);
+ if ( g_timer_elapsed (idle_timer, NULL ) > 60.f )
+ {
+ g_signal_emit (player, signals [SIG_EXITING], 0);
+ gtk_main_quit ();
+ }
+
+ } while ( player->priv->terminate == FALSE );
+
+ return NULL;
+}
+
+static void
+parole_plugin_player_dispose (GObject *object)
+{
+ ParolePluginPlayer *player;
+
+ player = PAROLE_PLUGIN_PLAYER (object);
+
+ g_signal_emit (player, signals [SIG_EXITING], 0);
+
+ G_OBJECT_CLASS (parole_plugin_player_parent_class)->dispose (object);
+}
+
static void
parole_plugin_player_construct (GObject *object)
{
@@ -627,48 +678,8 @@ parole_plugin_player_construct (GObject *object)
gtk_widget_set_sensitive (player->priv->range, FALSE);
player->priv->vbox = vbox;
-}
-
-static gboolean
-parole_plugin_player_window_delete_event_cb (ParolePluginPlayer *player)
-{
- parole_plugin_player_fullscreen (player, FALSE);
- return TRUE;
-}
-
-static gpointer *check_idle_thread (gpointer data)
-{
- ParolePluginPlayer *player;
-
- player = PAROLE_PLUGIN_PLAYER (data);
- do
- {
- g_usleep (1000000);
- if ( g_timer_elapsed (idle_timer, NULL ) > 60.f )
- {
- g_debug ("Idle timeout expired, exiting...");
- g_signal_emit (player, signals [SIG_EXITING], 0);
- g_debug ("Here");
- gtk_main_quit ();
- g_debug ("Yalla");
- }
-
- } while ( player->priv->terminate == FALSE );
-
- return NULL;
-}
-
-static void
-parole_plugin_player_dispose (GObject *object)
-{
- ParolePluginPlayer *player;
-
- player = PAROLE_PLUGIN_PLAYER (object);
-
- g_signal_emit (player, signals [SIG_EXITING], 0);
-
- G_OBJECT_CLASS (parole_plugin_player_parent_class)->dispose (object);
+ g_signal_emit (player, signals [SIG_READY], 0);
}
static void
@@ -693,6 +704,15 @@ parole_plugin_player_class_init (ParolePluginPlayerClass *klass)
g_cclosure_marshal_VOID__VOID,
G_TYPE_NONE, 0, G_TYPE_NONE);
+ signals[SIG_READY] =
+ g_signal_new ("ready",
+ PAROLE_TYPE_PLUGIN_PLAYER,
+ G_SIGNAL_RUN_LAST,
+ G_STRUCT_OFFSET (ParolePluginPlayerClass, ready),
+ NULL, NULL,
+ g_cclosure_marshal_VOID__VOID,
+ G_TYPE_NONE, 0, G_TYPE_NONE);
+
g_object_class_install_property (object_class,
PROP_PLUG,
@@ -814,6 +834,17 @@ parole_plugin_player_finalize (GObject *object)
G_OBJECT_CLASS (parole_plugin_player_parent_class)->finalize (object);
}
+static gboolean parole_plugin_player_play_idle (gpointer data)
+{
+ ParolePluginPlayer *player;
+
+ player = PAROLE_PLUGIN_PLAYER (data);
+
+ parole_plugin_player_play (player);
+
+ return FALSE;
+}
+
static gboolean
parole_plugin_player_quit_idle (gpointer data)
{
@@ -852,16 +883,6 @@ parole_plugin_player_new (GtkWidget *plug, gchar *url)
return player;
}
-void parole_plugin_player_play (ParolePluginPlayer *player)
-{
- if ( player->priv->terminate )
- return;
-
- player->priv->reload = FALSE;
- player->priv->finished = FALSE;
- parole_gst_play_uri (player->priv->gst, player->priv->url, NULL);
-}
-
void parole_plugin_player_exit (ParolePluginPlayer *player)
{
player->priv->terminate = TRUE;
@@ -878,6 +899,10 @@ static gboolean parole_plugin_player_dbus_stop (ParolePluginPlayer *player,
static gboolean parole_plugin_player_dbus_ping (ParolePluginPlayer *player,
GError **error);
+static gboolean parole_plugin_player_dbus_play_url (ParolePluginPlayer *player,
+ gchar *in_URL,
+ GError **error);
+
#include "org.parole.media.plugin.h"
/*
@@ -931,3 +956,12 @@ static gboolean parole_plugin_player_dbus_ping (ParolePluginPlayer *player,
return TRUE;
}
+static gboolean parole_plugin_player_dbus_play_url (ParolePluginPlayer *player,
+ gchar *in_URL,
+ GError **error)
+{
+ player->priv->url = g_strdup (in_URL);
+ g_debug ("Playing url=%s", in_URL);
+ g_idle_add ((GSourceFunc) parole_plugin_player_play_idle, player);
+ return TRUE;
+}
diff --git a/browser-plugin/media-plugin/parole-plugin-player.h b/browser-plugin/media-plugin/parole-plugin-player.h
index bc3d506..4ada19e 100644
--- a/browser-plugin/media-plugin/parole-plugin-player.h
+++ b/browser-plugin/media-plugin/parole-plugin-player.h
@@ -45,6 +45,8 @@ typedef struct
void (*exiting) (ParolePluginPlayer *player);
+ void (*ready) (ParolePluginPlayer *player);
+
} ParolePluginPlayerClass;
GType parole_plugin_player_get_type (void) G_GNUC_CONST;
@@ -52,8 +54,6 @@ 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);
-
void parole_plugin_player_exit (ParolePluginPlayer *player);
G_END_DECLS
diff --git a/browser-plugin/npp_gate.cpp b/browser-plugin/npp_gate.cpp
index e4ce7ad..239765c 100644
--- a/browser-plugin/npp_gate.cpp
+++ b/browser-plugin/npp_gate.cpp
@@ -197,7 +197,7 @@ int32 NPP_WriteReady(NPP instance, NPStream * stream)
if (pPlugin == NULL)
return NPERR_GENERIC_ERROR;
- //rv = pPlugin->WriteReady(stream);
+ rv = pPlugin->WriteReady(stream);
return rv;
}
@@ -213,7 +213,7 @@ int32 NPP_Write(NPP instance, NPStream * stream, int32 offset, int32 len, void *
if (pPlugin == NULL)
return NPERR_GENERIC_ERROR;
- //rv = pPlugin->Write(stream, offset, len, buffer);
+ rv = pPlugin->Write(stream, offset, len, buffer);
return rv;
}
@@ -236,6 +236,10 @@ void NPP_StreamAsFile(NPP instance, NPStream * stream, const char *fname)
{
if (instance == NULL)
return;
+
+ CPlugin *pPlugin = (CPlugin *) instance->pdata;
+
+ pPlugin->StreamAsFile (stream, fname);
}
void NPP_Print(NPP instance, NPPrint * printInfo)
@@ -254,7 +258,7 @@ void NPP_URLNotify(NPP instance, const char *url, NPReason reason, void *notifyD
if (pPlugin == NULL)
return;
- //pPlugin->URLNotify(url, reason, notifyData);
+ pPlugin->URLNotify(url, reason, notifyData);
}
diff --git a/browser-plugin/parole-plugin.c b/browser-plugin/parole-plugin.c
new file mode 100644
index 0000000..038beef
--- /dev/null
+++ b/browser-plugin/parole-plugin.c
@@ -0,0 +1,464 @@
+/*
+ * * 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 <dbus/dbus-glib.h>
+
+#include <X11/Xlib.h>
+
+#include <gtk/gtk.h>
+
+#include <parole/parole.h>
+
+#include "parole-plugin.h"
+
+int32 STREAMBUFSIZE = 0x0FFFFFFF;
+
+static void parole_plugin_finalize (GObject *object);
+
+struct _ParolePlugin
+{
+ GObject parent;
+
+ DBusGConnection *bus;
+ DBusGProxy *proxy;
+
+ Window window;
+ gchar *url;
+ gchar *tmp_file;
+ FILE *cache;
+ GSList *list;
+
+ gulong ping_id;
+ gboolean window_set;
+ gboolean is_playlist;
+ gboolean checked;
+ gboolean player_ready;
+ gboolean player_started;
+ gboolean player_spawned;
+ gboolean player_exited;
+ gboolean player_playing;
+};
+
+struct _ParolePluginClass
+{
+ GObjectClass parent_class;
+};
+
+G_DEFINE_TYPE (ParolePlugin, parole_plugin, G_TYPE_OBJECT)
+
+static void
+parole_plugin_class_init (ParolePluginClass *klass)
+{
+ GObjectClass *object_class = G_OBJECT_CLASS (klass);
+
+ object_class->finalize = parole_plugin_finalize;
+}
+
+static void
+parole_plugin_init (ParolePlugin *plugin)
+{
+ GError *error = NULL;
+
+ plugin->proxy = NULL;
+ plugin->url = NULL;
+ plugin->cache = NULL;
+ plugin->tmp_file = NULL;
+ plugin->list = NULL;
+
+ plugin->window_set = FALSE;
+ plugin->is_playlist = FALSE;
+ plugin->checked = FALSE;
+ plugin->player_ready = FALSE;
+ plugin->player_started = FALSE;
+ plugin->player_spawned = FALSE;
+ plugin->player_exited = FALSE;
+ plugin->player_playing = FALSE;
+ plugin->ping_id = 0;
+
+ plugin->bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
+
+ if ( error )
+ {
+ g_warning ("Failed to get session bus %s", error->message);
+ g_error_free (error);
+ }
+}
+
+static gboolean
+parole_plugin_ping (gpointer data)
+{
+ ParolePlugin *plugin;
+
+ plugin = PAROLE_PLUGIN (data);
+
+ dbus_g_proxy_call_no_reply (plugin->proxy, "Ping",
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+ return TRUE;
+}
+
+
+static void
+parole_plugin_player_exiting_cb (DBusGProxy *proxy, ParolePlugin *plugin)
+{
+ g_debug ("Player exiting");
+ plugin->player_exited = TRUE;
+ if ( plugin->ping_id != 0 )
+ g_source_remove (plugin->ping_id);
+}
+
+static void
+parole_plugin_player_ready_cb (DBusGProxy *proxy, ParolePlugin *plugin)
+{
+ g_debug ("Player ready");
+ plugin->player_ready = TRUE;
+
+ if ( plugin->ping_id == 0 )
+ {
+ plugin->ping_id = g_timeout_add_seconds (10, (GSourceFunc) parole_plugin_ping, plugin);
+ }
+}
+
+static void
+parole_plugin_stop_player (ParolePlugin *plugin)
+{
+ g_return_if_fail (plugin->proxy != NULL);
+
+ if ( plugin->player_ready || plugin->player_spawned )
+ {
+ gint num_tries = 0;
+
+ do
+ {
+ GError *error = NULL;
+ g_debug ("Sending Quit message");
+ dbus_g_proxy_call (plugin->proxy, "Quit", &error,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ /*
+ * This might happen if the browser unload the plugin quickly
+ * while the process didn't get the dbus name.
+ */
+ if ( error )
+ {
+#ifdef DEBUG
+ g_debug ("Failed to stop the backend via D-Bus %s", error->message);
+#endif
+ if ( g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY ) ||
+ g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN) )
+ {
+ g_error_free (error);
+ g_main_context_iteration(NULL, FALSE);
+ g_usleep (100000);
+ num_tries++;
+ g_debug ("No reply, probably not ready, re-trying");
+ }
+ else
+ break;
+ }
+ else
+ break;
+
+ } while (num_tries < 4 && plugin->player_exited != TRUE);
+ }
+}
+
+static void
+parole_plugin_finalize (GObject *object)
+{
+ ParolePlugin *plugin;
+
+ plugin = PAROLE_PLUGIN (object);
+
+ if ( plugin->ping_id != 0 )
+ g_source_remove (plugin->ping_id);
+
+ parole_plugin_stop_player (plugin);
+
+ if ( plugin->tmp_file )
+ {
+ remove (plugin->tmp_file);
+ g_free (plugin->tmp_file);
+ }
+
+ if ( plugin->cache )
+ fclose (plugin->cache);
+
+ if ( plugin->bus )
+ dbus_g_connection_unref (plugin->bus);
+
+ if ( plugin->url )
+ g_free (plugin->url);
+
+ if ( plugin->proxy )
+ {
+ dbus_g_proxy_disconnect_signal (plugin->proxy, "Exiting",
+ G_CALLBACK (parole_plugin_player_exiting_cb), plugin);
+
+ dbus_g_proxy_disconnect_signal (plugin->proxy, "Ready",
+ G_CALLBACK (parole_plugin_player_ready_cb), plugin);
+
+ g_object_unref (plugin->proxy);
+ }
+
+ G_OBJECT_CLASS (parole_plugin_parent_class)->finalize (object);
+}
+
+static void
+parole_plugin_get_proxy (ParolePlugin *plugin)
+{
+ gchar *dbus_name;
+
+ g_return_if_fail (plugin->bus != NULL);
+
+ dbus_name = g_strdup_printf ("org.Parole.Media.Plugin%ld", plugin->window);
+
+ plugin->proxy = dbus_g_proxy_new_for_name (plugin->bus,
+ dbus_name,
+ "/org/Parole/Media/Plugin",
+ "org.Parole.Media.Plugin");
+
+ if ( plugin->proxy == NULL)
+ g_critical ("Unable to create proxy for %s", dbus_name);
+ else
+ {
+ dbus_g_proxy_add_signal (plugin->proxy, "Exiting", G_TYPE_INVALID);
+ dbus_g_proxy_add_signal (plugin->proxy, "Ready", G_TYPE_INVALID);
+
+ dbus_g_proxy_connect_signal (plugin->proxy, "Exiting",
+ G_CALLBACK (parole_plugin_player_exiting_cb), plugin, NULL);
+
+ dbus_g_proxy_connect_signal (plugin->proxy, "Ready",
+ G_CALLBACK (parole_plugin_player_ready_cb), plugin, NULL);
+ }
+}
+
+static NPError
+parole_plugin_run_player (ParolePlugin *plugin)
+{
+ gchar *command[4];
+ gchar *socket;
+ gchar *app;
+ GError *error = NULL;
+
+ socket = g_strdup_printf ("%ld", plugin->window);
+
+ app = g_build_filename (LIBEXECDIR, "parole-media-plugin", NULL);
+
+ command[0] = app;
+ command[1] = (gchar *)"--socket-id";
+ command[2] = socket;
+ command[3] = NULL;
+
+ if ( !g_spawn_async (NULL,
+ command,
+ NULL,
+ (GSpawnFlags) 0,
+ NULL, NULL,
+ NULL,
+ &error) )
+ {
+ g_critical ("Failed to spawn command : %s", error->message);
+ g_error_free (error);
+ return NPERR_GENERIC_ERROR;
+ }
+
+ plugin->player_spawned = TRUE;
+
+ g_free (socket);
+ g_free (app);
+
+ parole_plugin_get_proxy (plugin);
+
+ return NPERR_NO_ERROR;
+}
+
+static void
+parole_plugin_send_play (ParolePlugin *plugin, const gchar *url)
+{
+ GError *error = NULL;
+ g_return_if_fail (plugin->proxy);
+
+ g_debug ("Sending play request of stream %s", url);
+ dbus_g_proxy_call (plugin->proxy, "PlayUrl", &error,
+ G_TYPE_STRING, url,
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ plugin->player_playing = TRUE;
+
+ if ( error )
+ {
+ g_critical ("Failed to play stream %s : %s", url, error->message);
+ g_error_free (error);
+ plugin->player_playing = FALSE;
+ }
+}
+
+ParolePlugin *
+parole_plugin_new (void)
+{
+ ParolePlugin *plugin = NULL;
+ plugin = g_object_new (PAROLE_TYPE_PLUGIN, NULL);
+ return plugin;
+}
+
+NPError parole_plugin_set_window (ParolePlugin *plugin, NPWindow * aWindow)
+{
+ g_debug ("SetWindow");
+
+ if ( aWindow == NULL )
+ return NPERR_NO_ERROR;
+
+ if ( plugin->window_set == FALSE)
+ {
+ plugin->window = (Window) aWindow->window;
+ plugin->window_set = TRUE;
+ return parole_plugin_run_player (plugin);
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError parole_plugin_new_stream (ParolePlugin *plugin, NPStream *stream, NPMIMEType type)
+{
+ if ( plugin->url == NULL )
+ {
+ plugin->url = g_strdup (stream->url);
+ g_debug ("NewStream=%s", plugin->url);
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+NPError parole_plugin_destroy_stream (ParolePlugin *plugin, NPStream * stream, NPError reason)
+{
+ if ( reason != NPRES_DONE )
+ {
+ g_debug ("Destroy stream %s reason %i ", stream->url, reason);
+ parole_plugin_shut (plugin);
+ }
+
+ return NPERR_NO_ERROR;
+}
+
+void parole_plugin_shut (ParolePlugin *plugin)
+{
+ g_debug ("Shut");
+
+ if ( plugin->player_ready )
+ {
+ g_debug ("Sending Stop signal");
+ dbus_g_proxy_call_no_reply (plugin->proxy, "Stop",
+ G_TYPE_INVALID,
+ G_TYPE_INVALID);
+
+ }
+}
+
+void parole_plugin_url_notify (ParolePlugin *plugin,
+ const char *url,
+ NPReason reason,
+ void *notifyData)
+{
+ g_debug ("UrlNotify=%s reason=%i", url, reason);
+
+}
+
+void parole_plugin_stream_as_file (ParolePlugin *plugin,
+ NPStream *stream,
+ const gchar *fname)
+{
+ g_debug ("StreamAsFile url=%s fname=%s", stream->url, fname);
+}
+
+int32 parole_plugin_write_ready (ParolePlugin *plugin, NPStream *stream)
+{
+ g_debug ("WriteReady url=%s", stream->url);
+
+ return plugin->player_ready ? STREAMBUFSIZE : 0;
+}
+
+int32 parole_plugin_write (ParolePlugin *plugin,
+ NPStream * stream,
+ int32 offset,
+ int32 len,
+ void *buffer)
+{
+ static int32 wrotebytes = -1;
+
+ if ( plugin->checked == FALSE )
+ {
+ /* Check if the url is a playlist */
+ g_debug ("Checking if stream is a playlist");
+ plugin->is_playlist = parole_pl_parser_can_parse_data ((const guchar*) buffer, len);
+
+ plugin->checked = TRUE;
+ }
+
+ if ( plugin->is_playlist )
+ {
+ plugin->tmp_file = g_strdup_printf ("/tmp/parole-plugin-player-%ld", plugin->window);
+
+ if (plugin->cache == NULL)
+ {
+ plugin->cache = fopen (plugin->tmp_file, "w");
+ g_warn_if_fail (plugin->cache != NULL);
+ }
+
+ if ( plugin->cache )
+ {
+ fseek (plugin->cache, offset, SEEK_SET);
+ wrotebytes += fwrite (buffer, 1, len, plugin->cache);
+ g_debug ("Wrotebytes=%d offset=%d data=%s", wrotebytes, offset, (gchar*)buffer);
+ }
+
+ if ( wrotebytes >= 0 )
+ {
+ ParoleFile *file;
+ fclose (plugin->cache);
+ plugin->cache = NULL;
+ plugin->list = parole_pl_parser_load_file (plugin->tmp_file);
+
+ if (plugin->list != NULL && g_slist_length (plugin->list) != 0 && plugin->player_playing == FALSE )
+ {
+ file = g_slist_nth_data (plugin->list, 0);
+ parole_plugin_send_play (plugin, parole_file_get_uri (file));
+ return len;
+ }
+ }
+ }
+ else if ( plugin->player_ready && plugin->player_playing == FALSE )
+ {
+ parole_plugin_send_play (plugin, stream->url);
+ return len;
+ }
+
+ return 0;
+}
diff --git a/browser-plugin/parole-plugin.h b/browser-plugin/parole-plugin.h
new file mode 100644
index 0000000..85e1afd
--- /dev/null
+++ b/browser-plugin/parole-plugin.h
@@ -0,0 +1,76 @@
+/*
+ * * 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 <npapi.h>
+#include <npruntime.h>
+#include "npupp.h"
+
+G_BEGIN_DECLS
+
+typedef struct _ParolePluginClass ParolePluginClass;
+typedef struct _ParolePlugin ParolePlugin;
+
+#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))
+
+GType parole_plugin_get_type (void) G_GNUC_CONST;
+
+ParolePlugin *parole_plugin_new (void);
+
+NPError parole_plugin_set_window (ParolePlugin *plugin,
+ NPWindow * aWindow);
+
+NPError parole_plugin_new_stream (ParolePlugin *plugin,
+ NPStream *stream,
+ NPMIMEType type);
+
+NPError parole_plugin_destroy_stream (ParolePlugin *plugin,
+ NPStream * stream,
+ NPError reason);
+
+void parole_plugin_shut (ParolePlugin *plugin);
+
+void parole_plugin_url_notify (ParolePlugin *plugin,
+ const char *url,
+ NPReason reason,
+ void *notifyData);
+
+void parole_plugin_stream_as_file (ParolePlugin *plugin,
+ NPStream *stream,
+ const gchar *fname);
+
+int32 parole_plugin_write_ready (ParolePlugin *plugin,
+ NPStream *stream);
+
+int32 parole_plugin_write (ParolePlugin *plugin,
+ NPStream * stream,
+ int32 offset,
+ int32 len,
+ void *buffer);
+
+G_END_DECLS
+
+#endif /* __PAROLE_PLUGIN_H */
diff --git a/browser-plugin/plugin.cpp b/browser-plugin/plugin.cpp
index b68859c..0ae98f0 100644
--- a/browser-plugin/plugin.cpp
+++ b/browser-plugin/plugin.cpp
@@ -70,76 +70,15 @@ CPlugin::CPlugin (NPP pNPInstance)
{
g_debug ("Constructor");
+ plugin = parole_plugin_new ();
+
mInstance = pNPInstance;
mInitialized = TRUE;
- window_set = FALSE;
- child_spawned = FALSE;
- url = NULL;
- bus = NULL;
- proxy = NULL;
- process_exiting = FALSE;
-}
-
-void CPlugin::StopPlayer()
-{
- gint num_tries = 0;
-
- if ( !proxy )
- GetProxy ();
-
- if ( proxy && !process_exiting)
- {
- do
- {
- GError *error = NULL;
- g_debug ("Sending Quit message");
- dbus_g_proxy_call (proxy, "Quit", &error,
- G_TYPE_INVALID,
- G_TYPE_INVALID);
-
- /*
- * This might happen if the browser unload the plugin quickly
- * while the process didn't get the dbus name.
- */
- if ( error )
- {
-#ifdef DEBUG
- g_debug ("Failed to stop the backend via D-Bus %s", error->message);
-#endif
- if ( g_error_matches (error, DBUS_GERROR, DBUS_GERROR_NO_REPLY ) ||
- g_error_matches (error, DBUS_GERROR, DBUS_GERROR_SERVICE_UNKNOWN) )
- {
- g_error_free (error);
- g_main_context_iteration(NULL, FALSE);
- g_usleep (100000);
- num_tries++;
- g_debug ("No reply, probably not ready, re-trying");
- }
- else
- break;
- }
- else
- break;
-
- } while (num_tries < 4 && process_exiting != TRUE);
- }
-
}
CPlugin::~CPlugin()
{
- g_debug ("Destructor");
-
- if ( ping_id != 0 )
- g_source_remove (ping_id);
-
- StopPlayer ();
-
- if ( bus )
- dbus_g_connection_unref (bus);
-
- if ( url )
- g_free (url);
+ g_object_unref (plugin);
mInstance = NULL;
}
@@ -148,7 +87,6 @@ NPBool CPlugin::init(NPWindow * pNPWindow)
if (pNPWindow == NULL)
return FALSE;
- m_Window = pNPWindow;
mInitialized = TRUE;
return mInitialized;
@@ -156,34 +94,12 @@ NPBool CPlugin::init(NPWindow * pNPWindow)
NPError CPlugin::SetWindow(NPWindow * aWindow)
{
- g_debug ("SetWindow");
-
- if ( aWindow == NULL )
- return FALSE;
-
- if ( !window_set )
- {
- window = (Window) aWindow->window;
-
- window_set = TRUE;
- }
- return NPERR_NO_ERROR;
+ return parole_plugin_set_window (plugin, aWindow);
}
void CPlugin::shut()
{
- g_debug ("shut");
-
- if ( !proxy )
- GetProxy ();
-
- if ( proxy )
- {
- g_debug ("Sending Stop signal");
- dbus_g_proxy_call_no_reply (proxy, "Stop",
- G_TYPE_INVALID,
- G_TYPE_INVALID);
- }
+ parole_plugin_shut (plugin);
}
NPBool CPlugin::isInitialized()
@@ -191,130 +107,32 @@ NPBool CPlugin::isInitialized()
return mInitialized;
}
-static gboolean
-ping_process (gpointer data)
+NPError CPlugin::NewStream (NPMIMEType type, NPStream * stream, NPBool seekable, uint16 * stype)
{
- DBusGProxy *proxy;
-
- proxy = (DBusGProxy *) data;
-
- dbus_g_proxy_call (proxy, "Ping",
- G_TYPE_INVALID,
- G_TYPE_INVALID);
-
- return TRUE;
+ return parole_plugin_new_stream (plugin, stream, type);
}
-
-static void
-process_exiting_cb (DBusGProxy *proxy, gpointer data)
+NPError CPlugin::DestroyStream(NPStream * stream, NPError reason)
{
- CPlugin *plugin;
-
- plugin = (CPlugin *) data;
- g_debug ("Process exiting");
- plugin->process_exiting = TRUE;
- g_source_remove (plugin->ping_id);
- plugin->ping_id = 0;
+ return parole_plugin_destroy_stream (plugin, stream, reason);
}
-void CPlugin::GetProxy ()
+void CPlugin::URLNotify (const char *url, NPReason reason, void *notifyData)
{
- g_return_if_fail (proxy == NULL);
-
- if ( child_spawned )
- {
- g_return_if_fail (bus != NULL);
-
- gchar *dbus_name;
- dbus_name = g_strdup_printf ("org.Parole.Media.Plugin%ld", window);
-
- proxy = dbus_g_proxy_new_for_name (bus,
- dbus_name,
- "/org/Parole/Media/Plugin",
- "org.Parole.Media.Plugin");
- if ( !proxy )
- g_critical ("Unable to create proxy for %s", dbus_name);
- else
- {
- dbus_g_proxy_add_signal (proxy, "exiting", G_TYPE_INVALID);
- dbus_g_proxy_connect_signal (proxy, "exiting",
- G_CALLBACK (process_exiting_cb), this, NULL);
- }
-
- g_free (dbus_name);
- }
+ parole_plugin_url_notify (plugin, url, reason, notifyData);
}
-NPError CPlugin::NewStream(NPMIMEType type, NPStream * stream, NPBool seekable, uint16 * stype)
+void CPlugin::StreamAsFile (NPStream * stream, const char *fname)
{
- g_debug ("New stream callback %s", stream->url);
-
- if ( !url )
- {
- gchar *command[6];
- gchar *socket;
- gchar *app;
- GError *error = NULL;
-
- url = g_strdup (stream->url);
-
- socket = g_strdup_printf ("%ld", window);
-#ifdef PAROLE_ENABLE_DEBUG
- app = g_strdup ("media-plugin/parole-media-plugin");
-#else
- app = g_build_filename (LIBEXECDIR, "parole-media-plugin", NULL);
-#endif
-
- command[0] = app;
- command[1] = (gchar *)"--socket-id";
- command[2] = socket;
- command[3] = (gchar *)"--url";
- command[4] = url;
- command[5] = NULL;
-
- if ( !g_spawn_async (NULL,
- command,
- NULL,
- (GSpawnFlags) 0,
- NULL, NULL,
- &child_pid,
- &error) )
- {
- g_critical ("Failed to spawn command : %s", error->message);
- g_error_free (error);
- return NPERR_GENERIC_ERROR;
- }
-
- child_spawned = TRUE;
-
- g_free (socket);
- g_free (app);
-
- bus = dbus_g_bus_get (DBUS_BUS_SESSION, &error);
-
- if ( error )
- {
- g_critical ("%s : ", error->message);
- g_error_free (error);
- return NPERR_GENERIC_ERROR;
- }
-
- GetProxy ();
- if ( proxy )
- ping_id = g_timeout_add_seconds (5, (GSourceFunc) ping_process, proxy);
-
- }
- return NPERR_NO_ERROR;
+ parole_plugin_stream_as_file (plugin, stream, fname);
}
-NPError CPlugin::DestroyStream(NPStream * stream, NPError reason)
+int32 CPlugin::WriteReady (NPStream * stream)
{
- if ( reason != NPRES_DONE )
- {
- g_debug ("Destroy stream %s reason %i ", stream->url, reason);
- shut ();
- }
+ return parole_plugin_write_ready (plugin, stream);
+}
- return NPERR_NO_ERROR;
+int32 CPlugin::Write (NPStream * stream, int32 offset, int32 len, void *buffer)
+{
+ return parole_plugin_write (plugin, stream, offset, len, buffer);
}
diff --git a/browser-plugin/plugin.h b/browser-plugin/plugin.h
index a89feb9..9a1bce1 100644
--- a/browser-plugin/plugin.h
+++ b/browser-plugin/plugin.h
@@ -42,18 +42,11 @@
#include <config.h>
#endif
-#include <npapi.h>
-#include <npruntime.h>
-#include "npupp.h"
-
#include <X11/Xlib.h>
-#include <dbus/dbus.h>
-#include <dbus/dbus-glib-lowlevel.h>
-
#include <glib.h>
-#include <glib/gstdio.h>
-#include <glib/gi18n.h>
+
+#include "parole-plugin.h"
class CPlugin {
private:
@@ -69,32 +62,21 @@ class CPlugin {
void shut ();
NPBool isInitialized();
- NPError GetValue (NPPVariable variable, void *value);
- NPError SetWindow (NPWindow * aWindow);
- NPError NewStream (NPMIMEType type, NPStream * stream, NPBool seekable, uint16 * stype);
- NPError DestroyStream (NPStream * stream, NPError reason);
-
+ NPError GetValue (NPPVariable variable, void *value);
- void GetProxy ();
- void StopPlayer();
-
- private:
- DBusGConnection *bus;
- DBusGProxy *proxy;
-
- gboolean window_set;
- gboolean child_spawned;
- gchar *url;
- Window window;
- GPid child_pid;
+ NPError SetWindow (NPWindow * aWindow);
+ NPError NewStream (NPMIMEType type, NPStream * stream, NPBool seekable, uint16 * stype);
+ NPError DestroyStream (NPStream * stream, NPError reason);
+ void URLNotify (const char *url, NPReason reason, void *notifyData);
+ void StreamAsFile (NPStream * stream, const char *fname);
+ int32 WriteReady (NPStream * stream);
+ int32 Write (NPStream * stream, int32 offset, int32 len, void *buffer);
public:
+ ParolePlugin *plugin;
NPP mInstance;
uint16 mode;
gchar *mimetype;
- gboolean process_exiting;
- gulong ping_id;
-
};
#endif // __PLUGIN_H__
diff --git a/gst/parole-gst.c b/gst/parole-gst.c
index c83672e..660152b 100644
--- a/gst/parole-gst.c
+++ b/gst/parole-gst.c
@@ -1514,6 +1514,9 @@ parole_gst_terminate_internal (ParoleGst *gst, gboolean fade_sound)
parole_window_busy_cursor (GTK_WIDGET (gst)->window);
+ if ( gst->priv->embedded )
+ goto out;
+
if ( fade_sound && gst->priv->state == GST_STATE_PLAYING && !playing_video )
{
gdouble volume;
@@ -1534,6 +1537,7 @@ parole_gst_terminate_internal (ParoleGst *gst, gboolean fade_sound)
}
}
+out:
parole_gst_change_state (gst, GST_STATE_NULL);
}
@@ -1738,7 +1742,6 @@ parole_gst_class_init (ParoleGstClass *klass)
{
GObjectClass *object_class = G_OBJECT_CLASS (klass);
GtkWidgetClass *widget_class = GTK_WIDGET_CLASS (klass);
- g_debug ("Class init");
object_class->finalize = parole_gst_finalize;
object_class->constructed = parole_gst_constructed;
@@ -1832,7 +1835,7 @@ static void
parole_gst_init (ParoleGst *gst)
{
gst->priv = PAROLE_GST_GET_PRIVATE (gst);
- g_debug ("Init");
+
gst->priv->state = GST_STATE_VOID_PENDING;
gst->priv->target = GST_STATE_VOID_PENDING;
gst->priv->media_state = PAROLE_MEDIA_STATE_STOPPED;
diff --git a/parole/Makefile.am b/parole/Makefile.am
index 229c7c6..86b9e2f 100644
--- a/parole/Makefile.am
+++ b/parole/Makefile.am
@@ -19,12 +19,19 @@ libparole_la_SOURCES = \
parole-provider-plugin.c \
parole-provider-player.c \
parole-file.c \
- parole-stream.c
+ parole-stream.c \
+ parole-pl-parser.c \
+ parole-pl-parser.h \
+ parole-filters.c \
+ parole-filters.h \
+ parole-debug.c \
+ parole-debug.h
libparole_la_CFLAGS = \
$(GIO_CFLAGS) \
$(GTK_CFLAGS) \
- $(TAGLIBC_CFLAGS)
+ $(TAGLIBC_CFLAGS) \
+ $(LIBXFCE4UTIL_CFLAGS)
paroleincludedir = \
$(includedir)/parole
@@ -52,7 +59,8 @@ parole-marshal.h: parole-marshal.list
parole_glib_enum_headers = \
parole-stream.h \
- parole-provider-player.h
+ parole-provider-player.h \
+ parole-pl-parser.h
parole-enum-types.h: stamp-enum-types.h
@true
@@ -72,6 +80,7 @@ parole-enum-types.c: $(parole_glib_enum_headers) Makefile
--fhead "#include \"parole-enum-types.h\"\n\n" \
--fhead "#include \"parole-stream.h\"\n\n" \
--fhead "#include \"parole-provider-player.h\"\n\n" \
+ --fhead "#include \"parole-pl-parser.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/src/parole-debug.c b/parole/parole-debug.c
similarity index 100%
rename from src/parole-debug.c
rename to parole/parole-debug.c
diff --git a/src/parole-debug.h b/parole/parole-debug.h
similarity index 100%
rename from src/parole-debug.h
rename to parole/parole-debug.h
diff --git a/parole/parole-filters.c b/parole/parole-filters.c
new file mode 100644
index 0000000..cbfab27
--- /dev/null
+++ b/parole/parole-filters.c
@@ -0,0 +1,148 @@
+/*
+ * * 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 <libxfce4util/libxfce4util.h>
+#include <glib.h>
+
+#include "parole-filters.h"
+#include "parole-pl-parser.h"
+#include "data/mime/parole-mime-types.h"
+
+static char *playlist_mime_types[] = {
+ "text/plain",
+ "audio/x-mpegurl",
+ "audio/playlist",
+ "audio/x-scpls",
+ "audio/x-ms-asx",
+ "application/xml",
+ "application/xspf+xml",
+};
+
+/*
+ * Supported Audio formats.
+ */
+GtkFileFilter *parole_get_supported_audio_filter (void)
+{
+ GtkFileFilter *filter;
+ guint i;
+
+ filter = gtk_file_filter_new ();
+
+ gtk_file_filter_set_name (filter, _("Audio"));
+
+ for ( i = 0; i < G_N_ELEMENTS (audio_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, audio_mime_types[i]);
+
+ return filter;
+}
+
+/*
+ * Supported Video formats.
+ */
+GtkFileFilter *parole_get_supported_video_filter (void)
+{
+ GtkFileFilter *filter;
+ guint i;
+
+ filter = gtk_file_filter_new ();
+
+ gtk_file_filter_set_name (filter, _("Video"));
+
+ for ( i = 0; i < G_N_ELEMENTS (video_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, video_mime_types[i]);
+
+ return filter;
+}
+
+/*
+ * Supported Audio And Video.
+ */
+GtkFileFilter *parole_get_supported_media_filter (void)
+{
+ GtkFileFilter *filter;
+ guint i;
+
+ filter = gtk_file_filter_new ();
+
+ gtk_file_filter_set_name (filter, _("Audio and video"));
+
+ for ( i = 0; i < G_N_ELEMENTS (audio_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, audio_mime_types[i]);
+
+ for ( i = 0; i < G_N_ELEMENTS (video_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, video_mime_types[i]);
+
+ return filter;
+}
+
+GtkFileFilter *parole_get_supported_files_filter (void)
+{
+ GtkFileFilter *filter;
+ guint i;
+
+ filter = parole_get_supported_media_filter ();
+
+ gtk_file_filter_set_name (filter, _("All supported files"));
+
+ for ( i = 0; i < G_N_ELEMENTS (playlist_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, playlist_mime_types[i]);
+
+ return filter;
+
+}
+
+GtkFileFilter *parole_get_supported_playlist_filter (void)
+{
+ GtkFileFilter *filter;
+ guint i;
+
+ filter = gtk_file_filter_new ();
+
+ gtk_file_filter_set_name (filter, _("Playlist files"));
+
+ for ( i = 0; i < G_N_ELEMENTS (playlist_mime_types); i++)
+ gtk_file_filter_add_mime_type (filter, playlist_mime_types[i]);
+
+ return filter;
+}
+
+gboolean parole_file_filter (GtkFileFilter *filter, ParoleFile *file)
+{
+ GtkFileFilterInfo filter_info;
+
+ gboolean ret;
+
+ filter_info.display_name = parole_file_get_display_name (file);
+ filter_info.mime_type = parole_file_get_content_type (file);
+
+ filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
+
+ ret = gtk_file_filter_filter (filter, &filter_info);
+
+ return ret;
+}
diff --git a/src/parole-filters.h b/parole/parole-filters.h
similarity index 91%
rename from src/parole-filters.h
rename to parole/parole-filters.h
index 389aa1a..f23f18f 100644
--- a/src/parole-filters.h
+++ b/parole/parole-filters.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_FILTERS_H
#define __PAROLE_FILTERS_H
@@ -51,11 +55,6 @@ gboolean parole_file_filter (GtkFileFilter *filter,
ParoleFileFormat parole_file_guess_format (ParoleFile *file);
-void parole_get_media_files (GtkFileFilter *filter,
- const gchar *path,
- gboolean recursive,
- GSList **list);
-
G_END_DECLS
#endif /* PAROLE_FILTERS_H */
diff --git a/src/parole-pl-parser.c b/parole/parole-pl-parser.c
similarity index 88%
rename from src/parole-pl-parser.c
rename to parole/parole-pl-parser.c
index 6c05936..5e7db07 100644
--- a/src/parole-pl-parser.c
+++ b/parole/parole-pl-parser.c
@@ -45,7 +45,7 @@
#include "parole-pl-parser.h"
#include "parole-filters.h"
#include "parole-debug.h"
-#include "enum-gtypes.h"
+#include "parole-enum-types.h"
typedef struct
{
@@ -254,8 +254,39 @@ parole_pl_parser_guess_format_from_extension (const gchar *filename)
static ParolePlFormat
parole_pl_parser_guess_format_from_data (const gchar *filename)
{
+ GFile *file;
+ gchar *mime_type = NULL;
+ gchar *contents;
+ gboolean result_uncertain;
+ gsize size;
- return PAROLE_PL_FORMAT_UNKNOWN;
+ ParolePlFormat format = PAROLE_PL_FORMAT_UNKNOWN;
+
+ file = g_file_new_for_path (filename);
+
+ if ( !g_file_load_contents (file, NULL, &contents, &size, NULL, NULL ) )
+ {
+ g_debug ("Unable to load content of file=%s", filename);
+ goto out;
+ }
+
+ mime_type = g_content_type_guess (NULL, (const guchar*)contents, size, &result_uncertain);
+
+
+ if ( mime_type && result_uncertain == FALSE )
+ {
+ g_debug ("mime_type %s", mime_type);
+ format = PAROLE_PL_FORMAT_PLAYLIST;
+ }
+
+ g_free (contents);
+
+out:
+ if ( mime_type )
+ g_free (mime_type);
+
+ g_object_unref (file);
+ return format;
}
static GSList *
@@ -508,6 +539,33 @@ parole_pl_parser_parse (ParolePlFormat format, const gchar *filename)
return list;
}
+gboolean parole_pl_parser_can_parse_data (const guchar *data, gint len)
+{
+ gchar *mime_type;
+ gboolean result_uncertain;
+ gboolean result = FALSE;
+
+ mime_type = g_content_type_guess (NULL, data, len, &result_uncertain);
+
+ if ( mime_type && result_uncertain == FALSE )
+ {
+ GtkFileFilter *filter = g_object_ref_sink (parole_get_supported_playlist_filter ());
+ GtkFileFilterInfo filter_info;
+ g_debug ("Mime_type=%s", mime_type);
+ filter_info.mime_type = mime_type;
+
+ filter_info.contains = GTK_FILE_FILTER_MIME_TYPE;
+
+ result = gtk_file_filter_filter (filter, &filter_info);
+ g_object_unref (filter);
+ }
+
+ if ( mime_type )
+ g_free (mime_type);
+
+ return result;
+}
+
GSList *parole_pl_parser_load_file (const gchar *filename)
{
ParolePlFormat format = PAROLE_PL_FORMAT_UNKNOWN;
@@ -517,19 +575,18 @@ GSList *parole_pl_parser_load_file (const gchar *filename)
filter = parole_get_supported_playlist_filter ();
g_object_ref_sink (filter);
- if ( (format = parole_pl_parser_guess_format_from_extension (filename)) == PAROLE_PL_FORMAT_UNKNOWN)
- if ( (format = parole_pl_parser_guess_format_from_data (filename)) == PAROLE_PL_FORMAT_UNKNOWN)
- {
- g_debug ("Unable to guess playlist format of file : %s", filename);
- goto out;
- }
-
- PAROLE_DEBUG_ENUM_FULL (format, ENUM_GTYPE_PL_FORMAT, "playlist %s ", filename);
- list = parole_pl_parser_parse (format, filename);
+ if ( (format = parole_pl_parser_guess_format_from_extension (filename)) != PAROLE_PL_FORMAT_UNKNOWN)
+ {
+ PAROLE_DEBUG_ENUM_FULL (format, PAROLE_ENUM_TYPE_PL_FORMAT, "playlist %s ", filename);
+ list = parole_pl_parser_parse (format, filename);
+ }
+ else if ( (format = parole_pl_parser_guess_format_from_data (filename)) != PAROLE_PL_FORMAT_UNKNOWN)
+ {
+ list = parole_pl_parser_parse_m3u (filename);
+ //list = g_list_concat (list, parole_pl_parser_p
+ }
-out:
g_object_unref (filter);
-
return list;
}
@@ -633,7 +690,7 @@ gboolean parole_pl_parser_save_file (GSList *files, const gchar *filename, Parol
FILE *f;
gboolean ret_val;
- PAROLE_DEBUG_ENUM_FULL (format, ENUM_GTYPE_PL_FORMAT, "Saving playlist %s ", filename);
+ PAROLE_DEBUG_ENUM_FULL (format, PAROLE_ENUM_TYPE_PL_FORMAT, "Saving playlist %s ", filename);
f = fopen (filename, "w");
diff --git a/src/parole-pl-parser.h b/parole/parole-pl-parser.h
similarity index 84%
rename from src/parole-pl-parser.h
rename to parole/parole-pl-parser.h
index 281924e..5c8dd20 100644
--- a/src/parole-pl-parser.h
+++ b/parole/parole-pl-parser.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_PL_PARSER_H
#define __PAROLE_PL_PARSER_H
@@ -31,12 +35,15 @@ typedef enum
PAROLE_PL_FORMAT_M3U,
PAROLE_PL_FORMAT_PLS,
PAROLE_PL_FORMAT_ASX,
- PAROLE_PL_FORMAT_XSPF
+ PAROLE_PL_FORMAT_XSPF,
+ PAROLE_PL_FORMAT_PLAYLIST
} ParolePlFormat;
ParolePlFormat parole_pl_parser_guess_format_from_extension (const gchar *filename);
+gboolean parole_pl_parser_can_parse_data (const guchar *data, gint len);
+
GSList *parole_pl_parser_load_file (const gchar *filename);
gboolean parole_pl_parser_save_file (GSList *files,
diff --git a/parole/parole.h.in b/parole/parole.h.in
index 19c5ad7..a84dcfe 100644
--- a/parole/parole.h.in
+++ b/parole/parole.h.in
@@ -29,6 +29,9 @@
#include <parole/parole-provider-player.h>
#include <parole/parole-file.h>
#include <parole/parole-stream.h>
+#include <parole/parole-pl-parser.h>
+#include <parole/parole-filters.h>
+#include <parole/parole-debug.h>
#define PAROLE_MAJOR_VERSION @PAROLE_VERSION_MAJOR@
#define PAROLE_MINOR_VERSION @PAROLE_VERSION_MINOR@
diff --git a/src/Makefile.am b/src/Makefile.am
index e95a8df..973ef3a 100644
--- a/src/Makefile.am
+++ b/src/Makefile.am
@@ -35,17 +35,14 @@ NOINST_HFILES = \
parole-vis.h \
parole-statusbar.h \
parole-mediachooser.h \
- parole-filters.h \
parole-conf.h \
parole-conf-dialog.h \
parole-rc-utils.h \
parole-utils.h \
parole-disc.h \
parole-medialist.h \
- parole-debug.h \
parole-plugins-manager.h \
parole-module.h \
- parole-pl-parser.h \
parole-about.h \
parole-builder.h \
parole-subtitle-encoding.h \
@@ -64,16 +61,13 @@ parole_SOURCES = \
parole-statusbar.c \
parole-medialist.c \
parole-mediachooser.c \
- parole-filters.c \
parole-conf.c \
parole-conf-dialog.c \
parole-disc.c \
parole-rc-utils.c \
parole-utils.c \
- parole-debug.c \
parole-plugins-manager.c \
parole-module.c \
- parole-pl-parser.c \
parole-about.c \
parole-builder.c \
parole-subtitle-encoding.c \
@@ -99,7 +93,6 @@ parole_LDADD = \
$(TAGLIBC_LIBS)
parole_glib_enum_headers = \
- parole-pl-parser.h \
parole-conf.h \
parole-button.h
@@ -131,7 +124,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-pl-parser.h\"\n\n" \
--fhead "#include \"parole-conf.h\"\n\n" \
--fhead "#include \"parole-button.h\"\n\n" \
--fprod "\n/* enumerations from \"@filename@\" */" \
diff --git a/src/parole-filters.c b/src/parole-filters.c
deleted file mode 100644
index f59c778..0000000
--- a/src/parole-filters.c
+++ /dev/null
@@ -1,225 +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 <libxfce4util/libxfce4util.h>
-#include <glib.h>
-
-#include "parole-filters.h"
-#include "parole-utils.h"
-#include "parole-pl-parser.h"
-#include "data/mime/parole-mime-types.h"
-
-static char *playlist_mime_types[] = {
- "text/plain",
- "audio/x-mpegurl",
- "audio/playlist",
- "audio/x-scpls",
- "audio/x-ms-asx",
- "application/xml",
- "application/xspf+xml",
-};
-
-/*
- * Supported Audio formats.
- */
-GtkFileFilter *parole_get_supported_audio_filter (void)
-{
- GtkFileFilter *filter;
- guint i;
-
- filter = gtk_file_filter_new ();
-
- gtk_file_filter_set_name (filter, _("Audio"));
-
- for ( i = 0; i < G_N_ELEMENTS (audio_mime_types); i++)
- gtk_file_filter_add_mime_type (filter, audio_mime_types[i]);
-
- return filter;
-}
-
-/*
- * Supported Video formats.
- */
-GtkFileFilter *parole_get_supported_video_filter (void)
-{
- GtkFileFilter *filter;
- guint i;
-
- filter = gtk_file_filter_new ();
-
- gtk_file_filter_set_name (filter, _("Video"));
-
- for ( i = 0; i < G_N_ELEMENTS (video_mime_types); i++)
- gtk_file_filter_add_mime_type (filter, video_mime_types[i]);
-
- return filter;
-}
-
-/*
- * Supported Audio And Video.
- */
-GtkFileFilter *parole_get_supported_media_filter (void)
-{
- GtkFileFilter *filter;
- guint i;
-
- filter = gtk_file_filter_new ();
-
- gtk_file_filter_set_name (filter, _("Audio and video"));
-
- for ( i = 0; i < G_N_ELEMENTS (audio_mime_types); i++)
- gtk_file_filter_add_mime_type (filter, audio_mime_types[i]);
-
- for ( i = 0; i < G_N_ELEMENTS (video_mime_types); i++)
- gtk_file_filter_add_mime_type (filter, video_mime_types[i]);
-
- return filter;
-}
-
-GtkFileFilter *parole_get_supported_files_filter (void)
-{
- GtkFileFilter *filter;
- guint i;
-
- filter = parole_get_supported_media_filter ();
-
- gtk_file_filter_set_name (filter, _("All supported files"));
-
- for ( i = 0; i < G_N_ELEMENTS (playlist_mime_types); i++)
- gtk_file_filter_add_mime_type (filter, playlist_mime_types[i]);
-
- return filter;
-
-}
-
-GtkFileFilter *parole_get_supported_playlist_filter (void)
-{
- GtkFileFilter *filter;
- guint i;
-
- filter = gtk_file_filter_new ();
-
- gtk_file_filter_set_name (filter, _("Playlist files"));
-
- for ( i = 0; i < G_N_ELEMENTS (playlist_mime_types); i++)
- gtk_file_filter_add_mime_type (filter, playlist_mime_types[i]);
-
- return filter;
-}
-
-gboolean parole_file_filter (GtkFileFilter *filter, ParoleFile *file)
-{
- GtkFileFilterInfo filter_info;
-
- gboolean ret;
-
- filter_info.display_name = parole_file_get_display_name (file);
- filter_info.mime_type = parole_file_get_content_type (file);
-
- filter_info.contains = GTK_FILE_FILTER_DISPLAY_NAME | GTK_FILE_FILTER_MIME_TYPE;
-
- ret = gtk_file_filter_filter (filter, &filter_info);
-
- return ret;
-}
-
-void parole_get_media_files (GtkFileFilter *filter, const gchar *path,
- gboolean recursive, GSList **list)
-{
- GtkFileFilter *playlist_filter;
- GSList *list_internal = NULL;
- GSList *playlist = NULL;
- GDir *dir;
- const gchar *name;
- ParoleFile *file;
-
- playlist_filter = parole_get_supported_playlist_filter ();
- g_object_ref_sink (playlist_filter);
-
- if ( g_file_test (path, G_FILE_TEST_IS_REGULAR ) )
- {
- file = parole_file_new (path);
- if ( parole_file_filter (playlist_filter, file) &&
- parole_pl_parser_guess_format_from_extension (path) != PAROLE_PL_FORMAT_UNKNOWN )
- {
- playlist = parole_pl_parser_load_file (path);
- g_object_unref (file);
- if ( playlist)
- {
- *list = g_slist_concat (*list, playlist);
- }
- }
- else if ( parole_file_filter (filter, file) )
- {
- *list = g_slist_append (*list, file);
- }
- else
- g_object_unref (file);
- }
- else if ( g_file_test (path, G_FILE_TEST_IS_DIR ) )
- {
- dir = g_dir_open (path, 0, NULL);
-
- if ( G_UNLIKELY (dir == NULL) )
- return;
-
- while ( (name = g_dir_read_name (dir)) )
- {
- gchar *path_internal = g_strdup_printf ("%s/%s", path, name);
- if ( g_file_test (path_internal, G_FILE_TEST_IS_DIR) && recursive)
- {
- parole_get_media_files (filter, path_internal, TRUE, list);
- }
- else if ( g_file_test (path_internal, G_FILE_TEST_IS_REGULAR) )
- {
- file = parole_file_new (path_internal);
- if ( parole_file_filter (playlist_filter, file) &&
- parole_pl_parser_guess_format_from_extension (path) != PAROLE_PL_FORMAT_UNKNOWN)
- {
- playlist = parole_pl_parser_load_file (path_internal);
- g_object_unref (file);
- if ( playlist)
- {
- *list = g_slist_concat (*list, playlist);
- }
- }
- else if ( parole_file_filter (filter, file) )
- {
- list_internal = g_slist_append (list_internal, file);
- }
- else
- g_object_unref (file);
- }
- g_free (path_internal);
- }
- list_internal = g_slist_sort (list_internal, (GCompareFunc) thunar_file_compare_by_name);
- g_dir_close (dir);
- *list = g_slist_concat (*list, list_internal);
- }
- g_object_unref (playlist_filter);
-}
diff --git a/src/parole-utils.c b/src/parole-utils.c
index e429d65..112eb65 100644
--- a/src/parole-utils.c
+++ b/src/parole-utils.c
@@ -31,6 +31,8 @@
#include <libxfce4util/libxfce4util.h>
+#include <parole/parole.h>
+
#include "parole-utils.h"
/* List from xine-lib's demux_sputext.c */
@@ -335,3 +337,79 @@ GdkPixbuf *parole_icon_load (const gchar *icon_name, gint size)
return pix;
}
+
+void parole_get_media_files (GtkFileFilter *filter, const gchar *path,
+ gboolean recursive, GSList **list)
+{
+ GtkFileFilter *playlist_filter;
+ GSList *list_internal = NULL;
+ GSList *playlist = NULL;
+ GDir *dir;
+ const gchar *name;
+ ParoleFile *file;
+
+ playlist_filter = parole_get_supported_playlist_filter ();
+ g_object_ref_sink (playlist_filter);
+
+ if ( g_file_test (path, G_FILE_TEST_IS_REGULAR ) )
+ {
+ file = parole_file_new (path);
+ if ( parole_file_filter (playlist_filter, file) &&
+ parole_pl_parser_guess_format_from_extension (path) != PAROLE_PL_FORMAT_UNKNOWN )
+ {
+ playlist = parole_pl_parser_load_file (path);
+ g_object_unref (file);
+ if ( playlist)
+ {
+ *list = g_slist_concat (*list, playlist);
+ }
+ }
+ else if ( parole_file_filter (filter, file) )
+ {
+ *list = g_slist_append (*list, file);
+ }
+ else
+ g_object_unref (file);
+ }
+ else if ( g_file_test (path, G_FILE_TEST_IS_DIR ) )
+ {
+ dir = g_dir_open (path, 0, NULL);
+
+ if ( G_UNLIKELY (dir == NULL) )
+ return;
+
+ while ( (name = g_dir_read_name (dir)) )
+ {
+ gchar *path_internal = g_strdup_printf ("%s/%s", path, name);
+ if ( g_file_test (path_internal, G_FILE_TEST_IS_DIR) && recursive)
+ {
+ parole_get_media_files (filter, path_internal, TRUE, list);
+ }
+ else if ( g_file_test (path_internal, G_FILE_TEST_IS_REGULAR) )
+ {
+ file = parole_file_new (path_internal);
+ if ( parole_file_filter (playlist_filter, file) &&
+ parole_pl_parser_guess_format_from_extension (path) != PAROLE_PL_FORMAT_UNKNOWN)
+ {
+ playlist = parole_pl_parser_load_file (path_internal);
+ g_object_unref (file);
+ if ( playlist)
+ {
+ *list = g_slist_concat (*list, playlist);
+ }
+ }
+ else if ( parole_file_filter (filter, file) )
+ {
+ list_internal = g_slist_append (list_internal, file);
+ }
+ else
+ g_object_unref (file);
+ }
+ g_free (path_internal);
+ }
+ list_internal = g_slist_sort (list_internal, (GCompareFunc) thunar_file_compare_by_name);
+ g_dir_close (dir);
+ *list = g_slist_concat (*list, list_internal);
+ }
+ g_object_unref (playlist_filter);
+}
diff --git a/src/parole-utils.h b/src/parole-utils.h
index a26d66d..a7e216e 100644
--- a/src/parole-utils.h
+++ b/src/parole-utils.h
@@ -39,4 +39,9 @@ gboolean parole_is_uri_disc (const gchar *uri);
GdkPixbuf *parole_icon_load (const gchar *icon_name,
gint size);
+void parole_get_media_files (GtkFileFilter *filter,
+ const gchar *path,
+ gboolean recursive,
+ GSList **list);
+
#endif /* __PAROLE_UTILS_ */
More information about the Xfce4-commits
mailing list