Commit 8e2554a6 authored by Ali Abdallah's avatar Ali Abdallah

* parole-gst.c Implement a timeout handler to check state change

	failure, can potentially happen on live streams.
	* Change the about dialog.
	* Change the version from 0.1 to 0.1.90 as the first stable
	version should be 0.2
	* parole-disc.c code to correctly checks if cd drive has a cdda,
	this is a Linux specific thing.
	* parole-gst.c the buffering bit when we force a stop state while
	stream is buffering.
	* parole-openlocation.c button to clear history of open locations.
	* plugins/ Added a simple window title plugin to change
	the title of the main window to the current playing stream.
	* Set All the popup pos to be always center on parent.
	* parole-plugin.c get rid of some useless code+properly
	free the plugin data in finalize.
	* parole-module.c fix a small memory leak.
	* parole.h Support for site in the description of the plugin.
	* parole-statusbar.c hide the separator when going to 
	fullscreen mode.
	* Update the POTFILES.in and the .pot files.

(Old svn revision: 7893)
parent d2d8f025
2009-08-06: 14:30 Ali aliov@xfce.org
* parole-gst.c Implement a timeout handler to check state change
failure, can potentially happen on live streams.
* Change the about dialog.
* Change the version from 0.1 to 0.1.90 as the first stable
version should be 0.2
* parole-disc.c code to correctly checks if cd drive has a cdda,
this is a Linux specific thing.
* parole-gst.c the buffering bit when we force a stop state while
stream is buffering.
* parole-openlocation.c button to clear history of open locations.
* plugins/ Added a simple window title plugin to change
the title of the main window to the current playing stream.
* Set All the popup pos to be always center on parent.
* parole-plugin.c get rid of some useless code+properly
free the plugin data in finalize.
* parole-module.c fix a small memory leak.
* parole.h Support for site in the description of the plugin.
* parole-statusbar.c hide the separator when going to
fullscreen mode.
* Update the POTFILES.in and the .pot files.
2009-08-04: 18:00 Ali aliov@xfce.org
* Added option to remember the currently loaded media
files in the playlist view.
......
What's this file about?
-----------------------
This file lists external open source projects that were the starting point of learning how to
write a GStreamer based media player.
1) GStreamer itself, gstreamer plugins base.
2) Totem, The gnome media player.
3) Aldegonde, This tiny media player was a starting point of Totem, the code is very clear
and minimal, ideal to read before starting.
Thanks to all the people that contributed/ing to these projects, without, Parole whouldn't be possible.
m4_define([intltool_minimum_version], [0.31])
m4_define([parole_verinfo], [0:1:0])
m4_define([parole_verinfo], [0:2:0])
m4_define([parole_version_api], [0])
m4_define([parole_version_major], [0])
m4_define([parole_version_minor], [1])
m4_define([parole_version_micro], [0])
m4_define([parole_version_micro], [90])
m4_define([parole_version_build], [r@REVISION@])
m4_define([parole_version_tag], [svn])
m4_define([parole_version], [parole_version_major().parole_version_minor().parole_version_micro()ifelse(parole_version_tag(), [svn], [parole_version_tag().parole_version_build()], [parole_version_tag()])])
AC_INIT([parole-media-player], [parole_version], [aliov@xfce.org])
AC_PREREQ(2.50)
AC_PREREQ(2.59c)
AM_INIT_AUTOMAKE([1.8 dist-bzip2 tar-ustar])
AM_CONFIG_HEADER([config.h])
AM_MAINTAINER_MODE
# ===================================================== #
# Check for UNIX variants #
# ===================================================== #
AC_AIX
AC_ISC_POSIX
AC_MINIX
AC_USE_SYSTEM_EXTENSIONS
# ===================================================== #
# Basic compiler settings #
......@@ -55,7 +50,7 @@ AC_SUBST([PAROLE_VERSION_MICRO])
# Check for headers needed for standard interfaces #
# ==================================================== #
AC_HEADER_STDC
AC_CHECK_HEADERS([errno.h signal.h stddef.h \
AC_CHECK_HEADERS([errno.h signal.h stddef.h sys/ioctl.h fcntl.h\
string.h sys/stat.h sys/types.h sys/wait.h time.h \
unistd.h])
......@@ -149,6 +144,14 @@ if test x"$ac_tray_plugin" = x"yes"; then
[libnotify library], [yes])
fi
# Window title plugin.
#--------------------------
AC_ARG_ENABLE([window-title-plugin], AC_HELP_STRING([--disable-window-title-plugin], [Don't build the window title plugin]),
[ac_window_title_plugin=$enableval], [ac_window_title_plugin=yes])
AC_MSG_CHECKING([whether to build the window title plugin])
AM_CONDITIONAL([WINDOW_TITLE_PLUGIN], [test x"$ac_window_title_plugin" = x"yes"])
AC_MSG_RESULT([$ac_window_title_plugin])
#=======================================================#
# Check for debugging support #
#=======================================================#
......@@ -174,6 +177,7 @@ parole/Makefile
plugins/Makefile
plugins/properties/Makefile
plugins/tray/Makefile
plugins/window-title/Makefile
docs/Makefile
docs/plugin-api/version.xml
docs/plugin-api/Makefile
......@@ -194,7 +198,8 @@ echo "
Plugins to build:
=================
Stream Properties: ${ac_properties_plugin}
System Tray icon: ${ac_tray_plugin} (With notification $LIBNOTIFY_FOUND).
System Tray icon: ${ac_tray_plugin} (With notification $LIBNOTIFY_FOUND)
Window title: ${ac_window_title_plugin}
------------------------------------------------------
Configuration finished, type make to compile"
......@@ -559,7 +559,9 @@
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="no_show_all">True</property>
<property name="tooltip_text" translatable="yes">Hide playlist</property>
<property name="image">image18</property>
<property name="relief">none</property>
<signal name="clicked" handler="parole_player_show_hide_playlist"/>
</object>
<packing>
......@@ -643,7 +645,16 @@
</packing>
</child>
<child>
<object class="GtkAlignment" id="alignment1">
<object class="GtkHSeparator" id="status-sep">
<property name="visible">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
</packing>
</child>
<child>
<object class="GtkAlignment" id="statusalign">
<property name="visible">True</property>
<property name="left_padding">5</property>
<property name="right_padding">5</property>
......@@ -660,7 +671,7 @@
</object>
<packing>
<property name="expand">False</property>
<property name="position">2</property>
<property name="position">3</property>
</packing>
</child>
</object>
......
......@@ -15,6 +15,7 @@
<object class="GtkDialog" id="dialog">
<property name="border_width">5</property>
<property name="title" translatable="yes">Parole Plugins Preferences</property>
<property name="window_position">center-on-parent</property>
<property name="default_width">300</property>
<property name="default_height">220</property>
<property name="destroy_with_parent">True</property>
......@@ -83,124 +84,84 @@
<property name="orientation">vertical</property>
<property name="spacing">10</property>
<child>
<object class="GtkVBox" id="vbox2">
<object class="GtkTable" id="table1">
<property name="visible">True</property>
<property name="orientation">vertical</property>
<property name="spacing">6</property>
<property name="n_rows">3</property>
<property name="n_columns">2</property>
<property name="column_spacing">4</property>
<property name="row_spacing">4</property>
<child>
<object class="GtkHBox" id="hbox5">
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="spacing">4</property>
<child>
<object class="GtkLabel" id="label1">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Description:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="description">
<property name="visible">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<property name="label" translatable="yes">&lt;b&gt;Description:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="position">0</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox4">
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="spacing">4</property>
<child>
<object class="GtkLabel" id="label2">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Author:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="author">
<property name="visible">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<property name="label" translatable="yes">&lt;b&gt;Author:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="position">1</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox3">
<object class="GtkLabel" id="description">
<property name="visible">True</property>
<property name="spacing">4</property>
<child>
<object class="GtkLabel" id="label3">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Copyright:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="copyright">
<property name="visible">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<property name="use_markup">True</property>
</object>
<packing>
<property name="position">2</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
</packing>
</child>
<child>
<object class="GtkHBox" id="hbox2">
<object class="GtkLabel" id="author">
<property name="visible">True</property>
<property name="spacing">4</property>
<child>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Site:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkLabel" id="site">
<property name="visible">True</property>
</object>
<packing>
<property name="position">1</property>
</packing>
</child>
<property name="use_markup">True</property>
</object>
<packing>
<property name="position">3</property>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">1</property>
<property name="bottom_attach">2</property>
</packing>
</child>
<child>
<placeholder/>
<object class="GtkLabel" id="label4">
<property name="visible">True</property>
<property name="label" translatable="yes">&lt;b&gt;Site:&lt;/b&gt;</property>
<property name="use_markup">True</property>
</object>
<packing>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
<property name="x_options"></property>
<property name="y_options"></property>
</packing>
</child>
<child>
<object class="GtkHBox" id="site-box">
<property name="visible">True</property>
<child>
<placeholder/>
</child>
</object>
<packing>
<property name="left_attach">1</property>
<property name="right_attach">2</property>
<property name="top_attach">2</property>
<property name="bottom_attach">3</property>
</packing>
</child>
</object>
<packing>
......@@ -221,21 +182,12 @@
<signal name="clicked" handler="parole_plugins_manager_show_configure"/>
</object>
<packing>
<property name="expand">False</property>
<property name="position">0</property>
</packing>
</child>
<child>
<object class="GtkButton" id="about">
<property name="label" translatable="yes">gtk-about</property>
<property name="visible">True</property>
<property name="can_focus">True</property>
<property name="receives_default">True</property>
<property name="use_stock">True</property>
<signal name="clicked" handler="parole_plugins_manager_show_about"/>
</object>
<packing>
<property name="position">1</property>
</packing>
<placeholder/>
</child>
</object>
<packing>
......
......@@ -21,6 +21,7 @@
</object>
<object class="GtkFileChooserDialog" id="filechooserdialog">
<property name="border_width">5</property>
<property name="window_position">center-on-parent</property>
<property name="type_hint">normal</property>
<property name="has_separator">False</property>
<property name="action">save</property>
......
......@@ -27,54 +27,53 @@
#include <string.h>
#include <libxfce4util/libxfce4util.h>
#include <libxfcegui4/libxfcegui4.h>
#include "parole-about.h"
static void
parole_link_browser (GtkAboutDialog *about, const gchar *link, gpointer data)
{
gchar *cmd = g_strdup_printf ("%s %s", "xdg-open", link);
g_spawn_command_line_async (cmd, NULL);
g_free (cmd);
}
static void
parole_link_mailto (GtkAboutDialog *about, const gchar *link, gpointer data)
{
gchar *cmd = g_strdup_printf( "%s %s", "xdg-email", link);
g_spawn_command_line_async (cmd, NULL);
g_free (cmd);
}
void parole_about (const gchar *package)
{
const gchar* authors[3] =
XfceAboutInfo *info;
GtkWidget *dialog;
gint x, y;
GdkPixbuf *icon;
guint n;
static const struct
{
"Ali Abdallah <aliov@xfce.org>",
NULL
};
static const gchar *documenters[] =
gchar *name, *email, *language;
}
translators[] =
{
"Ali Abdallah <aliov@xfce.org>",
NULL,
{"", "", "",},
};
gtk_about_dialog_set_url_hook (parole_link_browser, NULL, NULL);
gtk_about_dialog_set_email_hook (parole_link_mailto, NULL, NULL);
info = xfce_about_info_new ("Parole", VERSION, _("Parole Media Player"),
XFCE_COPYRIGHT_TEXT ("2009", "Ali Abdallah"),
XFCE_LICENSE_GPL);
xfce_about_info_set_homepage (info, "http://goodies.xfce.org/projects/applications/parole-media-player");
xfce_about_info_add_credit (info, "Ali Abdallah", "aliov@xfce.org", _("Author/Maintainer"));
for (n = 0; n < G_N_ELEMENTS (translators); ++n)
{
gchar *s;
s = g_strdup_printf (_("Translator (%s)"), translators[n].language);
xfce_about_info_add_credit (info, translators[n].name, translators[n].email, s);
g_free (s);
}
gtk_icon_size_lookup (GTK_ICON_SIZE_DIALOG, &x, &y);
icon = xfce_themed_icon_load ("parole", x);
gtk_show_about_dialog (NULL,
"authors", authors,
"copyright", "Copyright \302\251 2009 Ali Abdallah",
"destroy-with-parent", TRUE,
"documenters", documenters,
"license", XFCE_LICENSE_GPL,
"name", package,
"translator-credits", _("translator-credits"),
"version", PACKAGE_VERSION,
"website", "http://goodies.xfce.org",
NULL);
dialog = xfce_about_dialog_new_with_values (NULL, info, icon);
if (icon)
g_object_unref (G_OBJECT (icon));
gtk_dialog_run (GTK_DIALOG (dialog));
gtk_widget_destroy (dialog);
xfce_about_info_free (info);
}
......@@ -26,6 +26,15 @@
#include <stdlib.h>
#include <string.h>
#include <fcntl.h>
#include <unistd.h>
#include <sys/stat.h>
#include <sys/ioctl.h>
#if defined(__linux__)
#include <linux/cdrom.h>
#endif
#include <gio/gio.h>
#include <gtk/gtk.h>
......@@ -178,6 +187,53 @@ got_cdda:
g_object_unref (file);
}
static void
parole_disc_check_cdrom (ParoleDisc *disc, GVolume *volume)
{
#if defined(__linux__)
gint fd;
gchar *device;
gint drive;
device = g_volume_get_identifier (volume, G_VOLUME_IDENTIFIER_KIND_UNIX_DEVICE);
TRACE ("device : %s", device);
if ( (fd = open (device, O_RDONLY)) < 0 )
{
g_debug ("Failed to open device : %s", device);
disc->priv->needs_update = TRUE;
goto out;
}
if ( (drive = ioctl (fd, CDROM_DRIVE_STATUS, NULL)) )
{
if ( drive == CDS_DRIVE_NOT_READY )
{
g_print ("Drive :%s is not yet ready\n", device);
disc->priv->needs_update = TRUE;
goto out;
}
if ( drive == CDS_DISC_OK )
{
if ( (drive = ioctl (fd, CDROM_DISC_STATUS, NULL)) > 0 )
{
if ( drive == CDS_AUDIO || drive == CDS_MIXED )
{
MountData *data;
data = parole_disc_get_mount_data (disc, g_volume_get_name (volume), "cdda:/", PAROLE_DISC_CDDA);
g_ptr_array_add (disc->priv->array, data);
}
}
}
}
close (fd);
out:
g_free (device);
#endif /* if defined(__linux__) */
}
static void
parole_disc_add_drive (ParoleDisc *disc, GDrive *drive)
{
......@@ -203,6 +259,11 @@ parole_disc_add_drive (ParoleDisc *disc, GDrive *drive)
parole_disc_add_mount_to_menu (disc, mount);
g_object_unref (mount);
}
else
{
/* Could be a cdda?*/
parole_disc_check_cdrom (disc, volume);
}
}
g_list_foreach (list, (GFunc) g_object_unref, NULL);
......@@ -219,6 +280,12 @@ parole_disc_get_drives (ParoleDisc *disc)
list = g_volume_monitor_get_connected_drives (disc->priv->monitor);
len = g_list_length (list);
/*
* Set the update flag here because it can be set later to TRUE
* in case a device is not yet ready.
*/
disc->priv->needs_update = FALSE;
for ( i = 0; i < len; i++)
{
......@@ -231,7 +298,6 @@ parole_disc_get_drives (ParoleDisc *disc)
g_list_foreach (list, (GFunc) g_object_unref, NULL);
g_list_free (list);
disc->priv->needs_update = FALSE;
}
static void
......@@ -246,6 +312,7 @@ parole_disc_monitor_changed_cb (GVolumeMonitor *monitor, gpointer *device, Parol
{
guint i;
TRACE ("Changed");
for ( i = 0 ; i < disc->priv->array->len; i++)
{
MountData *data;
......@@ -304,6 +371,12 @@ parole_disc_init (ParoleDisc *disc)
g_signal_connect (G_OBJECT (disc->priv->monitor), "mount-removed",
G_CALLBACK (parole_disc_monitor_changed_cb), disc);
g_signal_connect (G_OBJECT (disc->priv->monitor), "drive-disconnected",
G_CALLBACK (parole_disc_monitor_changed_cb), disc);
g_signal_connect (G_OBJECT (disc->priv->monitor), "drive-eject-button",
G_CALLBACK (parole_disc_monitor_changed_cb), disc);
disc->priv->media_menu = GTK_WIDGET (gtk_builder_get_object (builder, "media-menu"));
g_signal_connect (gtk_builder_get_object (builder, "media-menu-item"), "select",
......
......@@ -55,9 +55,12 @@ static void parole_gst_play_file_internal (ParoleGst *gst);
static void parole_gst_change_state (ParoleGst *gst,
GstState new);
static void parole_gst_terminate_internal (ParoleGst *gst,
gboolean fade_sound);
static void parole_gst_seek_cdda_track (ParoleGst *gst,
gint track) G_GNUC_UNUSED;
gint track);
struct ParoleGstPrivate
{
......@@ -83,6 +86,7 @@ struct ParoleGstPrivate
gboolean update_color_balance;
ParoleAspectRatio aspect_ratio;
gulong state_change_id;
/*
* xvimage sink has brightness+hue+aturation+contrast.
......@@ -564,29 +568,6 @@ parole_gst_query_capabilities (ParoleGst *gst)
gst_query_unref (query);
}
static void
parole_gst_query_cdda_tracks (ParoleGst *gst)
{
GstFormat format;
gint64 duration;
gint tracks;
format = gst_format_get_by_nick ("track");
if ( format != GST_FORMAT_UNDEFINED )
{
gst_element_query_duration (gst->priv->playbin, &format, &duration);
tracks = (gint) duration;
TRACE ("CDDA source has %d tacks", tracks);
g_object_set (G_OBJECT (gst->priv->stream),
"num-tracks", tracks,
NULL);
}
}
static void
parole_gst_query_duration (ParoleGst *gst)
{
......@@ -601,9 +582,6 @@ parole_gst_query_duration (ParoleGst *gst)
"media-type", &media_type,
NULL);
if ( media_type == PAROLE_MEDIA_TYPE_CDDA )
parole_gst_query_cdda_tracks (gst);
gst_time = GST_FORMAT_TIME;
gst_element_query_duration (gst->priv->playbin,
......@@ -718,6 +696,9 @@ parole_gst_get_pad_capabilities (GObject *object, GParamSpec *pspec, ParoleGst *
pad = GST_PAD (object);
if ( !GST_IS_PAD (pad) || !GST_PAD_CAPS (pad) )
return;
st = gst_caps_get_structure (GST_PAD_CAPS (pad), 0);
if ( st )
......@@ -735,7 +716,7 @@ parole_gst_get_pad_capabilities (GObject *object, GParamSpec *pspec, ParoleGst *
{