commit ce154a9da9f290972f31b9623f902ce736fdea10 Author: phantomjinx <p.g.richard...@phantomjinx.co.uk> Date: Sun Jul 25 14:59:10 2010 +0100
Initial inclusion of media player plugin .gitignore | 2 + TODO | 29 +- configure.in | 43 ++ plugins/Makefile.am | 3 +- plugins/media_player/Makefile.am | 114 +++++ plugins/media_player/icons/Makefile.am | 14 + .../media_player/icons/hicolor/16x16/Makefile.am | 1 + .../icons/hicolor/16x16/places/Makefile.am | 4 + .../16x16/places/media_player-volume-control.png | Bin 0 -> 765 bytes .../media_player/icons/hicolor/22x22/Makefile.am | 1 + .../icons/hicolor/22x22/places/Makefile.am | 4 + .../22x22/places/media_player-volume-control.png | Bin 0 -> 1196 bytes .../media_player/icons/hicolor/24x24/Makefile.am | 1 + .../icons/hicolor/24x24/places/Makefile.am | 4 + .../24x24/places/media_player-volume-control.png | Bin 0 -> 1021 bytes .../media_player/icons/hicolor/32x32/Makefile.am | 1 + .../icons/hicolor/32x32/places/Makefile.am | 4 + .../32x32/places/media_player-volume-control.png | Bin 0 -> 1921 bytes .../media_player/icons/hicolor/48x48/Makefile.am | 1 + .../icons/hicolor/48x48/places/Makefile.am | 4 + .../48x48/places/media_player-volume-control.png | Bin 0 -> 3618 bytes plugins/media_player/icons/hicolor/Makefile.am | 1 + plugins/media_player/media_player.c | 503 ++++++++++++++++++++ plugins/media_player/media_player.glade | 152 ++++++ plugins/media_player/media_player.h | 62 +++ plugins/media_player/media_player.plugin | 4 + plugins/media_player/media_player.ui | 7 + plugins/media_player/plugin.c | 164 +++++++ plugins/media_player/plugin.h | 61 +++ 29 files changed, 1165 insertions(+), 19 deletions(-) --- diff --git a/.gitignore b/.gitignore index 35da214..2015993 100644 --- a/.gitignore +++ b/.gitignore @@ -74,6 +74,7 @@ cscope.out /data/glade/playlist_display.glade /data/glade/core_prefs.xml /data/glade/photo_editor.glade +/data/glade/media_player.glade /data/ui/details_editor.ui /data/ui/coverweb.ui @@ -86,4 +87,5 @@ cscope.out /data/ui/playlist_display.ui /data/ui/core_prefs.ui /data/ui/photo_editor.ui +/data/ui/media_player.ui diff --git a/TODO b/TODO index 67204d6..a9d326d 100644 --- a/TODO +++ b/TODO @@ -5,8 +5,8 @@ Prospective Plugins: play tracks now # info window synchronizer - download coverart plugin - photo panel +# download coverart plugin +# photo panel # export plugin # - provides window and export functions # - other plugins simply emit a signal that tells the plugin to export the @@ -70,7 +70,7 @@ Help Menu # prefsdlg.c - Refactor preferences dialog to appear as pages anjuta preferences dialog # plugin remaining -display_photo.* +# display_photo.* # info.* / infodlg.* # help.* @@ -101,21 +101,14 @@ Notes on trial build using ubuntu 910 3) Added localmusic -** Message: TODO signal all things such as conversions to cancel +Gstreamer +* display.c + * media player gui referenced in glade xml -(lt-gtkpod:12130): GLib-GObject-WARNING **: invalid unclassed pointer in cast to `GtkFileChooser' +* display_playlists / display_sorttabs + * context menu trips tools_play_tracks (selected_tracks); -(lt-gtkpod:12130): Gtk-CRITICAL **: gtk_file_chooser_get_current_folder: assertion `GTK_IS_FILE_CHOOSER (chooser)' failed - -** (lt-gtkpod:12130): WARNING **: busy push XXX -** Message: TODO load photodb handle - -** Message: TODO signal all things such as conversions to cancel - -** (lt-gtkpod:12130): CRITICAL **: coverart_select_cover: assertion `key' failed -** Message: TODO - update smart playlists before writing - - -(lt-gtkpod:12130): GLib-GObject-CRITICAL **: g_object_ref: assertion `G_IS_OBJECT (object)' failed -** Message: TODO - cleanup gphoto_window on shutdown +* player.c / player.h + * thing that does all the work +Fix anjuta about icon diff --git a/configure.in b/configure.in index 2ceed3b..71310b7 100644 --- a/configure.in +++ b/configure.in @@ -200,6 +200,30 @@ fi AM_CONDITIONAL(HAVE_PLUGIN_COVERWEB, [test x$coverweb = xyes]) +dnl Check for gstreamer +dnl ------------------------------------------------------------- + +AC_ARG_ENABLE(plugin-media-player, + AC_HELP_STRING([--disable-plugin-media-player],[Disable media player plugin for playing tracks in gtkpod]), + [ if test "$enableval" = "no"; then + user_disabled_media_player=1 + fi ], + [ user_disabled_media_player=0 ]) +AC_MSG_CHECKING(if media player plugin is disabled) +if test "$user_disabled_media_player" = 1; then + AC_MSG_RESULT(yes) + media_player="no" +else + AC_MSG_RESULT(no) + + PKG_CHECK_MODULES(GSTREAMER, + [gstreamer-0.10 >= 0.10.25], + [media_player="yes"], + [media_player="no"]) +fi + +AM_CONDITIONAL(HAVE_PLUGIN_MEDIA_PLAYER, [test x$media_player = xyes]) + dnl Check for libvorbisfile and libvorbis AC_ARG_WITH(ogg, AC_HELP_STRING([--without-ogg], [Disable Ogg/Vorbis support])) if test "x$with_ogg" != "xno"; then @@ -414,6 +438,19 @@ plugins/coverweb/icons/hicolor/48x48/Makefile plugins/coverweb/icons/hicolor/48x48/places/Makefile plugins/coverweb/icons/hicolor/128x128/Makefile plugins/coverweb/icons/hicolor/128x128/places/Makefile +plugins/media_player/Makefile +plugins/media_player/icons/Makefile +plugins/media_player/icons/hicolor/Makefile +plugins/media_player/icons/hicolor/16x16/Makefile +plugins/media_player/icons/hicolor/16x16/places/Makefile +plugins/media_player/icons/hicolor/22x22/Makefile +plugins/media_player/icons/hicolor/22x22/places/Makefile +plugins/media_player/icons/hicolor/24x24/Makefile +plugins/media_player/icons/hicolor/24x24/places/Makefile +plugins/media_player/icons/hicolor/32x32/Makefile +plugins/media_player/icons/hicolor/32x32/places/Makefile +plugins/media_player/icons/hicolor/48x48/Makefile +plugins/media_player/icons/hicolor/48x48/places/Makefile ]) echo " @@ -443,6 +480,12 @@ else echo " CoverWeb Browser .....: No" fi +if [ $HAVE_PLUGIN_COVERWEB ]; then + echo " Media Player .....: Yes" +else + echo " Media Player .....: No" +fi + echo " Now type 'make' to build $PACKAGE $VERSION, and then 'make install' for installation. diff --git a/plugins/Makefile.am b/plugins/Makefile.am index d2e965d..4fdaa09 100644 --- a/plugins/Makefile.am +++ b/plugins/Makefile.am @@ -11,6 +11,7 @@ SUBDIRS = . \ info_display \ cover_display \ coverweb \ - photo_editor + photo_editor \ + media_player # indent diff --git a/plugins/media_player/Makefile.am b/plugins/media_player/Makefile.am new file mode 100644 index 0000000..5fb021e --- /dev/null +++ b/plugins/media_player/Makefile.am @@ -0,0 +1,114 @@ +if HAVE_PLUGIN_MEDIA_PLAYER + +plugin_name = media_player +plugin_lib = lib$(plugin_name).so +plugin_file = $(plugin_name).plugin + +# Plugin description file +plugin_in_files = $(plugin_file) + +# Plugin UI file +media_player_uidir = $(gtkpod_ui_dir) +media_player_ui_DATA = $(plugin_name).ui + +# Plugin Glade file +media_player_gladedir = $(gtkpod_glade_dir) +media_player_glade_DATA = $(plugin_name).glade + +# Plugin Icon file +media_player_pixmapsdir = $(gtkpod_image_dir) +media_player_pixmaps_DATA = + +# Where to install the plugin +plugindir = $(gtkpod_plugin_dir) +media_player_plugindir = $(gtkpod_plugin_dir) +media_player_plugin_DATA = $(plugin_file) + +SUBDIRS = icons + +# The plugin +plugin_LTLIBRARIES = libmedia_player.la + +AM_CPPFLAGS = \ + -DPACKAGE_LOCALE_DIR=\""$(prefix)/$(DATADIRNAME)/locale"\" \ + -DGTKPOD_DATA_DIR=\"$(gtkpod_data_dir)\" \ + -DGTKPOD_PLUGIN_DIR=\"$(gtkpod_plugin_dir)\" \ + -DGTKPOD_IMAGE_DIR=\"$(gtkpod_image_dir)\" \ + -DGTKPOD_GLADE_DIR=\"$(gtkpod_glade_dir)\" \ + -DGTKPOD_UI_DIR=\"$(gtkpod_ui_dir)\" \ + -DPACKAGE_DATA_DIR=\"$(datadir)\" \ + -DPACKAGE_SRC_DIR=\"$(srcdir)\" \ + $(GTKPOD_CFLAGS) \ + $(GSTREAMER_CFLAGS) + +# Plugin sources +libmedia_player_la_SOURCES = plugin.c plugin.h \ + media_player.c media_player.h + +libmedia_player_la_LDFLAGS = $(GTKPOD_PLUGIN_LDFLAGS) + +# Plugin dependencies +libmedia_player_la_LIBADD = \ + $(LIBGTKPOD_LIBS) \ + $(LIBANJUTA_LIBS) \ + $(GSTREAMER_LIBS) + +all-local: create-plugin-links create-ui-link create-glade-link + +# Creating symbolic links in plugin root directory +create-plugin-links: + echo "Creating plugin links" + if [ ! -e ../$(plugin_lib) ]; then \ + ln -s `pwd`/.libs/$(plugin_lib) ../$(plugin_lib); \ + fi; \ + if [ ! -e ../$(plugin_file) ]; then \ + ln -s `pwd`/$(plugin_file) ../$(plugin_file); \ + fi; + +# Creating symbolic link to ui file in installed ui directory +create-ui-link: + if [ ! -e ../../data/ui/$(plugin_name).ui ]; then \ + ln -s `pwd`/$(plugin_name).ui ../../data/ui/$(plugin_name).ui; \ + fi; + +create-glade-link: + if [ -e `pwd`/$(plugin_name).glade ]; then \ + if [ ! -e ../../data/glade/$(plugin_name).glade ]; then \ + ln -s `pwd`/$(plugin_name).glade ../../data/glade/$(plugin_name).glade; \ + fi; \ + fi; \ + if [ -e `pwd`/$(plugin_name).xml ]; then \ + if [ ! -e ../../data/glade/$(plugin_name).xml ]; then \ + ln -s `pwd`/$(plugin_name).xml ../../data/glade/$(plugin_name).xml; \ + fi; \ + fi; + +# Clean up the links and files created purely for dev [ing +clean-local: clean-plugin-files clean-ui-dir clean-glade-dir + +clean-plugin-files: + if [ -h ../$(plugin_file) ]; then \ + rm -f ../$(plugin_lib) ../$(plugin_file); \ + fi; + +clean-ui-dir: + if [ -h ../../data/ui/$(plugin_name).ui ]; then \ + rm -f ../../data/ui/$(plugin_name).ui; \ + fi; + +clean-glade-dir: + if [ -h ../../data/glade/$(plugin_name).glade ]; then \ + rm -f ../../data/glade/$(plugin_name).glade; \ + fi; \ + if [ -h $(gtkpod_glade_dir)/$(plugin_name).xml ]; then \ + rm -f ../../data/glade/$(plugin_name).xml; \ + fi; + +endif + +EXTRA_DIST = \ + $(plugin_in_files) \ + $(media_player_plugin_DATA) \ + $(media_player_ui_DATA) \ + $(media_player_glade_DATA) \ + $(media_player_pixmaps_DATA) diff --git a/plugins/media_player/icons/Makefile.am b/plugins/media_player/icons/Makefile.am new file mode 100644 index 0000000..ebb4895 --- /dev/null +++ b/plugins/media_player/icons/Makefile.am @@ -0,0 +1,14 @@ +SUBDIRS = hicolor + +gtk_update_icon_cache = gtk-update-icon-cache -f -t $(gtkpod_image_dir)/hicolor + +install-data-hook: update-icon-cache +uninstall-hook: update-icon-cache +update-icon-cache: + @-if test -z "$(DESTDIR)"; then \ + echo "Updating Gtk icon cache."; \ + $(gtk_update_icon_cache); \ + else \ + echo "*** Icon cache not updated. After (un)install, run this:"; \ + echo "*** $(gtk_update_icon_cache)"; \ + fi \ No newline at end of file diff --git a/plugins/media_player/icons/hicolor/16x16/Makefile.am b/plugins/media_player/icons/hicolor/16x16/Makefile.am new file mode 100644 index 0000000..ab9924d --- /dev/null +++ b/plugins/media_player/icons/hicolor/16x16/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = places diff --git a/plugins/media_player/icons/hicolor/16x16/places/Makefile.am b/plugins/media_player/icons/hicolor/16x16/places/Makefile.am new file mode 100644 index 0000000..5880098 --- /dev/null +++ b/plugins/media_player/icons/hicolor/16x16/places/Makefile.am @@ -0,0 +1,4 @@ +placesdir = $(pkgdatadir)/icons/hicolor/16x16/places +places_DATA = media_player-volume-control.png + +EXTRA_DIST = $(places_DATA) diff --git a/plugins/media_player/icons/hicolor/16x16/places/media_player-volume-control.png b/plugins/media_player/icons/hicolor/16x16/places/media_player-volume-control.png new file mode 100644 index 0000000..a34518a Binary files /dev/null and b/plugins/media_player/icons/hicolor/16x16/places/media_player-volume-control.png differ diff --git a/plugins/media_player/icons/hicolor/22x22/Makefile.am b/plugins/media_player/icons/hicolor/22x22/Makefile.am new file mode 100644 index 0000000..ab9924d --- /dev/null +++ b/plugins/media_player/icons/hicolor/22x22/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = places diff --git a/plugins/media_player/icons/hicolor/22x22/places/Makefile.am b/plugins/media_player/icons/hicolor/22x22/places/Makefile.am new file mode 100644 index 0000000..4e74d8d --- /dev/null +++ b/plugins/media_player/icons/hicolor/22x22/places/Makefile.am @@ -0,0 +1,4 @@ +placesdir = $(pkgdatadir)/icons/hicolor/22x22/places +places_DATA = media_player-volume-control.png + +EXTRA_DIST = $(places_DATA) diff --git a/plugins/media_player/icons/hicolor/22x22/places/media_player-volume-control.png b/plugins/media_player/icons/hicolor/22x22/places/media_player-volume-control.png new file mode 100644 index 0000000..ed6a9d4 Binary files /dev/null and b/plugins/media_player/icons/hicolor/22x22/places/media_player-volume-control.png differ diff --git a/plugins/media_player/icons/hicolor/24x24/Makefile.am b/plugins/media_player/icons/hicolor/24x24/Makefile.am new file mode 100644 index 0000000..ab9924d --- /dev/null +++ b/plugins/media_player/icons/hicolor/24x24/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = places diff --git a/plugins/media_player/icons/hicolor/24x24/places/Makefile.am b/plugins/media_player/icons/hicolor/24x24/places/Makefile.am new file mode 100644 index 0000000..9dc4456 --- /dev/null +++ b/plugins/media_player/icons/hicolor/24x24/places/Makefile.am @@ -0,0 +1,4 @@ +placesdir = $(pkgdatadir)/icons/hicolor/24x24/places +places_DATA = media_player-volume-control.png + +EXTRA_DIST = $(places_DATA) diff --git a/plugins/media_player/icons/hicolor/24x24/places/media_player-volume-control.png b/plugins/media_player/icons/hicolor/24x24/places/media_player-volume-control.png new file mode 100644 index 0000000..8d899cf Binary files /dev/null and b/plugins/media_player/icons/hicolor/24x24/places/media_player-volume-control.png differ diff --git a/plugins/media_player/icons/hicolor/32x32/Makefile.am b/plugins/media_player/icons/hicolor/32x32/Makefile.am new file mode 100644 index 0000000..ab9924d --- /dev/null +++ b/plugins/media_player/icons/hicolor/32x32/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = places diff --git a/plugins/media_player/icons/hicolor/32x32/places/Makefile.am b/plugins/media_player/icons/hicolor/32x32/places/Makefile.am new file mode 100644 index 0000000..40b3a69 --- /dev/null +++ b/plugins/media_player/icons/hicolor/32x32/places/Makefile.am @@ -0,0 +1,4 @@ +placesdir = $(pkgdatadir)/icons/hicolor/32x32/places +places_DATA = media_player-volume-control.png + +EXTRA_DIST = $(places_DATA) diff --git a/plugins/media_player/icons/hicolor/32x32/places/media_player-volume-control.png b/plugins/media_player/icons/hicolor/32x32/places/media_player-volume-control.png new file mode 100644 index 0000000..a26afac Binary files /dev/null and b/plugins/media_player/icons/hicolor/32x32/places/media_player-volume-control.png differ diff --git a/plugins/media_player/icons/hicolor/48x48/Makefile.am b/plugins/media_player/icons/hicolor/48x48/Makefile.am new file mode 100644 index 0000000..ab9924d --- /dev/null +++ b/plugins/media_player/icons/hicolor/48x48/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = places diff --git a/plugins/media_player/icons/hicolor/48x48/places/Makefile.am b/plugins/media_player/icons/hicolor/48x48/places/Makefile.am new file mode 100644 index 0000000..6cd9e1a --- /dev/null +++ b/plugins/media_player/icons/hicolor/48x48/places/Makefile.am @@ -0,0 +1,4 @@ +placesdir = $(pkgdatadir)/icons/hicolor/48x48/places +places_DATA = media_player-volume-control.png + +EXTRA_DIST = $(places_DATA) diff --git a/plugins/media_player/icons/hicolor/48x48/places/media_player-volume-control.png b/plugins/media_player/icons/hicolor/48x48/places/media_player-volume-control.png new file mode 100644 index 0000000..5260b9d Binary files /dev/null and b/plugins/media_player/icons/hicolor/48x48/places/media_player-volume-control.png differ diff --git a/plugins/media_player/icons/hicolor/Makefile.am b/plugins/media_player/icons/hicolor/Makefile.am new file mode 100644 index 0000000..4f161aa --- /dev/null +++ b/plugins/media_player/icons/hicolor/Makefile.am @@ -0,0 +1 @@ +SUBDIRS = 16x16 22x22 24x24 32x32 48x48 diff --git a/plugins/media_player/media_player.c b/plugins/media_player/media_player.c new file mode 100644 index 0000000..ed91a1d --- /dev/null +++ b/plugins/media_player/media_player.c @@ -0,0 +1,503 @@ +/* Time-stamp: <2008-01-07 07:07:33 Sonic1> + | + | Copyright (C) 2002-2003 Ryan Houdek <Sonicadvance1 at users.sourceforge.net> + | Modified by Paul Richardson <phantom_sf at users.sourceforge.net> + | Part of the gtkpod project. + | + | URL: http://gtkpod.sourceforge.net/ + | + | 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + | + | iTunes and iPod are trademarks of Apple + | + | This product is not supported/written/published by Apple! + */ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <math.h> +#include <gst/gst.h> +#include <gst/interfaces/xoverlay.h> +#include <gdk/gdkx.h> +#include <gtk/gtk.h> +#include "libgtkpod/itdb.h" +#include "libgtkpod/file.h" +#include "libgtkpod/directories.h" +#include "libgtkpod/misc.h" +#include "plugin.h" +#include "media_player.h" + +static MediaPlayer *player; + +GMainLoop *loop; +GstElement *pipeline, *audio, *audiomixer, *volume; +GstElement *src, *dec, *conv, *sink; +GstPad *audiopad; + +GstElement *video, *videosink, *videoconv; +GstPad *videopad; + +GstBus *bus; +static gboolean prevbut = FALSE; +static gboolean stopall = FALSE; +static gboolean shuffle = TRUE; +static GThread *thread = NULL; +gboolean hasvideo = FALSE; + +static int my_bus_callback(GstBus *bus, GstMessage *msg, gpointer data) { + switch (GST_MESSAGE_TYPE (msg)) { + case GST_MESSAGE_EOS: + gtk_range_set_range(GTK_RANGE(player->song_scale), 0, 1); + gtk_range_set_value(GTK_RANGE(player->song_scale), 0); + gtk_label_set_text(GTK_LABEL(player->song_label), ""); + g_main_loop_quit(data); + break; + case GST_MESSAGE_ERROR: { + gchar *debug; + GError *err; + + gst_message_parse_error(msg, &err, &debug); + g_free(debug); + + g_print("Error: %s\n", err->message); + g_error_free(err); + + g_main_loop_quit(data); + break; + } + default: + break; + } + + return TRUE; +} + +static gboolean set_scale_range(GstElement *pipeline) { + GstFormat fmt = GST_FORMAT_TIME; + gint64 len; + + if (loop == NULL || GST_OBJECT_IS_DISPOSING(pipeline)) + return FALSE; + + if (loop != NULL || g_main_loop_is_running(loop)) { + if (gst_element_query_duration(pipeline, &fmt, &len)) { + gtk_range_set_range(GTK_RANGE(player->song_scale), 0, (((GstClockTime) (len)) / GST_SECOND)); + // if (icon) + // gtk_status_icon_set_tooltip(icon, (gchar *) g_object_get_data(G_OBJECT (song_label), "tr_title")); + return FALSE; + } + } + else + return FALSE; + + return TRUE; +} +static gboolean set_scale_position(GstElement *pipeline) { + GstFormat fmt = GST_FORMAT_TIME; + gint64 pos; + gint64 len; + + if (loop == NULL || thread == NULL || !g_main_loop_is_running(loop)) + return FALSE; + + if (loop != NULL || g_main_loop_is_running(loop)) { + if (gst_element_query_position(pipeline, &fmt, &pos)) { + gint seconds = ((GstClockTime) pos) / GST_SECOND; + gint length; + gchar *label; + + gst_element_query_duration(pipeline, &fmt, &len); + length = ((GstClockTime) len) / GST_SECOND; + + label + = g_strdup_printf(_("%s (%d:%02d of %d:%02d)"), (gchar *) g_object_get_data(G_OBJECT (player->song_label), "tr_title"), seconds + / 60, seconds % 60, length / 60, length % 60); + gtk_range_set_value(GTK_RANGE(player->song_scale), seconds); + gtk_label_set_text(GTK_LABEL(player->song_label), label); + g_free(label); + return TRUE; + } + } + + return FALSE; +} +#ifndef M_LN10 +#define M_LN10 (log(10.0)) +#endif + +static void volume_changed_callback(GtkWidget *widget, GstElement* volume) { + gdouble value; + gdouble level; + + value = gtk_range_get_value(GTK_RANGE(widget)); + level = exp(value / 20.0 * M_LN10); + g_object_set(volume, "volume", level, NULL); +} +static void cb_newpad(GstElement *decodebin, GstPad *pad, gboolean last, gpointer data) { + GstCaps *caps; + GstStructure *str; + GstPad *audiopad2, *videopad2; + + /* check media type */ + caps = gst_pad_get_caps(pad); + str = gst_caps_get_structure(caps, 0); + printf("string = %s\n", gst_structure_get_name(str)); + const gchar *name = gst_structure_get_name(str); + if (g_strrstr(name, "audio")) { + /* only link once */ + audiopad2 = gst_element_get_pad(audio, "sink"); + if (GST_PAD_IS_LINKED (audiopad2)) { + printf("audio pad is linked!unreffing\n"); + g_object_unref(audiopad2); + return; + } + + /* link'n'play */ + gst_pad_link(pad, audiopad2); // Link audiopad to pad or other way around, dunno + //gst_element_link (volume, dec); //Doesn't seem to work... + //volume_changed_callback (vol_scale, volume); //Change volume to default + } + + if (g_strrstr(name, "video")) { + // only link once + + videopad2 = gst_element_get_pad(videoconv, "sink"); + if (GST_PAD_IS_LINKED (videopad2)) { + printf("video pad is linked!unreffing\n"); + g_object_unref(videopad2); + return; + } + // link'n'play + gst_pad_link(pad, videopad2); + //set_video_mode (TRUE);//Not needed since We can't actually SEE the video + } + + gst_caps_unref(caps); + +} + +static void playsong_real() { + GstStateChangeReturn sret; + GstState state; + gchar *str; + + while (player->tracks) { + Track *tr = player->tracks->data; + g_return_if_fail(tr); + str = get_file_name_from_source(tr, SOURCE_PREFER_LOCAL); + if (str) { + gtk_label_set_text(GTK_LABEL(player->song_label), tr->title); // set label to title + g_object_set_data(G_OBJECT (player->song_label), "tr_title", tr->title); // set label to title...again?wtf? + g_object_set_data(G_OBJECT (player->song_label), "tr_artist", tr->artist); // set label to title...again?wtf? + gtk_widget_set_sensitive(player->volume_scale, TRUE); //set volume scale sensitivity to true + + /* init GStreamer */ + loop = g_main_loop_new(NULL, FALSE); // make new loop + /* setup */ + pipeline = gst_pipeline_new("pipeline"); //Create our pipeline + volume = gst_element_factory_make("volume", "volume"); // Create volume element + bus = gst_pipeline_get_bus(GST_PIPELINE (pipeline)); // get pipeline's bus + gst_bus_add_watch(bus, my_bus_callback, loop); //Add a watch to the bus + gst_object_unref(bus); //unref the bus + + src = gst_element_factory_make("filesrc", "source"); //create the file source + g_object_set(G_OBJECT (src), "location", str, NULL); //set location to the file location + dec = gst_element_factory_make("decodebin", "decoder"); //create our decodebing + g_signal_connect (dec, "new-decoded-pad", G_CALLBACK (cb_newpad), NULL); //signal to the new-decoded-pad(same as new-pad) + gst_bin_add_many(GST_BIN (pipeline), src, dec, NULL); //add src and dec to pipeline + gst_element_link(src, dec); //link src and dec together + + /* create audio output */ + audio = gst_bin_new("audiobin"); //create our audio bin + conv = gst_element_factory_make("audioconvert", "aconv"); //Create audioconvert element + audiopad = gst_element_get_pad(conv, "sink"); //get the audioconvert pad + sink = gst_element_factory_make("alsasink", "sink"); //create our alsasink + + gst_bin_add_many(GST_BIN (audio), conv, sink, volume, NULL); //add volume, conv, and sink to audio + gst_element_link(conv, sink); // link sink and conv + gst_element_add_pad(audio, gst_ghost_pad_new("sink", audiopad)); // add pad to audio...? + gst_object_unref(audiopad); //unref audiopad + gst_bin_add(GST_BIN (pipeline), audio); //add audio to pipeline + + /*create video output*/ + + video = gst_bin_new("videobin"); //create videobin + videoconv = gst_element_factory_make("ffmpegcolorspace", "vconv"); //make ffmpegcolorspace + //videopad = gst_element_get_pad (videoconv, "sink"); //get videoconv pad, why the hell am I getting + //videosink = gst_element_factory_make ("ximagesink", "sink"); //create video sink + //g_object_set (G_OBJECT (videosink), "force-aspect-ratio", TRUE, NULL); //force aspect ratio + // gst_x_overlay_set_xwindow_id (GST_X_OVERLAY (videosink), gdk_x11_drawable_get_xid (drawing_area->window)); //set the overlay to our drawing area + //gst_element_link (videoconv, videosink); //link videoconv and videosink + //gst_bin_add_many (GST_BIN (video),videoconv, videosink, NULL); //add videoconv and videosink to video + gst_bin_add(GST_BIN (video), videoconv); + //gst_object_unref (videopad); //unref videopad + gst_bin_add(GST_BIN (pipeline), video); + //[NOTE] If file doesn't contain video, it crashes the program, so commented out + + /* Volume Control */ + + //volume_changed_callback (vol_scale, volume); + //g_signal_connect (vol_scale, "value-changed", G_CALLBACK (volume_changed_callback), volume); //connect volume-changed signal + + /* run */ + gst_element_set_state(pipeline, GST_STATE_PLAYING);// set state + g_timeout_add(250, (GSourceFunc) set_scale_range, GST_PIPELINE (pipeline)); + g_timeout_add(1000, (GSourceFunc) set_scale_position, GST_PIPELINE (pipeline)); + //g_timeout_add (500, (GSourceFunc) checkinfo, gst_pipeline_get_bus (GST_PIPELINE (pipeline))); + g_main_loop_run(loop); + + /* cleanup */ + sret = gst_element_set_state(pipeline, GST_STATE_NULL); +#ifndef NEW_PIPE_PER_FILE + printf("New_pipe_per_file is NOT defined\n"); + if (GST_STATE_CHANGE_ASYNC == sret) { + if (gst_element_get_state(GST_ELEMENT (pipeline), &state, NULL, GST_CLOCK_TIME_NONE) + == GST_STATE_CHANGE_FAILURE) { + g_print("State change failed. Aborting"); + break; + } + } +#endif + gst_element_set_state(pipeline, GST_STATE_NULL); + g_free(str);//Free it since it is no longer needed. + } + if (stopall) + break; + if (!prevbut) + player->tracks = g_list_next(player->tracks); + else + prevbut = FALSE; + } + thread = NULL; + stopall = FALSE; + g_thread_exit(0); +} + +void seek_to_time(gint64 time_seconds) { + if (loop == NULL || pipeline == NULL || thread == NULL || !g_main_loop_is_running(loop)) + return; + if (!gst_element_seek(pipeline, 1.0, GST_FORMAT_TIME, GST_SEEK_FLAG_FLUSH, GST_SEEK_TYPE_SET, time_seconds + * 1000000000, GST_SEEK_TYPE_NONE, GST_CLOCK_TIME_NONE)) + g_print("Seek failed!\n"); +} + +static void waitforpipeline(int state) { + if (pipeline == NULL || thread == NULL) + return; + + GstState istate, ipending; + gst_element_get_state(pipeline, &istate, &ipending, GST_CLOCK_TIME_NONE); + + if (istate == GST_STATE_VOID_PENDING) { + return; + } + gst_element_set_state(pipeline, state); + + do { + gst_element_get_state(pipeline, &istate, &ipending, GST_CLOCK_TIME_NONE); + + if (istate == GST_STATE_VOID_PENDING) { + return; + } + } + while (istate != state); + + return; +} + +static void stop_song() { + stopall = FALSE; + if (loop != NULL && g_main_loop_is_running(loop)) + g_main_loop_quit(loop); + waitforpipeline(1); + gtk_range_set_range(GTK_RANGE(player->song_scale), 0, 1); + gtk_range_set_value(GTK_RANGE(player->song_scale), 0); + gtk_label_set_text(GTK_LABEL(player->song_label), ""); +} + +void stop_all_songs() { + stopall = TRUE; + if (loop != NULL && g_main_loop_is_running(loop)) { + g_main_loop_quit(loop); + } + else + stopall = FALSE; + waitforpipeline(1); + gtk_range_set_range(GTK_RANGE(player->song_scale), 0, 1); + gtk_range_set_value(GTK_RANGE(player->song_scale), 0); + gtk_label_set_text(GTK_LABEL(player->song_label), ""); + gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(player->play_button), GTK_STOCK_MEDIA_PLAY); + gtk_widget_set_sensitive(player->song_scale, FALSE); +} + +void previous_song() { + prevbut = TRUE; + player->tracks = g_list_previous (player->tracks); + stop_song(); + //waitforpipeline (1); +} + +void next_song() { + stop_song(); + //waitforpipeline (1); +} + +int play_song() { + stop_all_songs(); + GError *err1 = NULL; + if (!g_thread_supported ()) { + g_thread_init(NULL); + gdk_threads_init(); + } + thread = g_thread_create ((GThreadFunc)playsong_real, NULL, TRUE, &err1); + if (!thread) { + printf("GStreamer thread creation failed: %s\n", err1->message); + g_error_free(err1); + } + gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(player->play_button), GTK_STOCK_MEDIA_PAUSE); + return 0; +} + +void pause_song() { + if (loop == NULL || pipeline == NULL || thread == NULL || !g_main_loop_is_running(loop)) { + play_song(); + } + + GstState state, pending; + gst_element_get_state(pipeline, &state, &pending, GST_CLOCK_TIME_NONE); + + if (state == GST_STATE_PLAYING) { + gst_element_set_state(pipeline, GST_STATE_PAUSED); + gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(player->play_button), GTK_STOCK_MEDIA_PLAY); + } + else if (state == GST_STATE_PAUSED) { + gst_element_set_state(pipeline, GST_STATE_PLAYING); + gtk_tool_button_set_stock_id(GTK_TOOL_BUTTON(player->play_button), GTK_STOCK_MEDIA_PAUSE); + } +} + +void set_selected_tracks(GList *tracks) { + if (!player) + return; + + if (player->tracks) { + g_list_free(player->tracks); + player->tracks = NULL; + } + + GList *l = g_list_copy(tracks); + //Does the same thing as generate_random_playlist() + if (shuffle) { + GRand *grand = g_rand_new(); + while (l || (g_list_length(l) != 0)) { + /* get random number between 0 and g_list_length()-1 */ + gint rn = g_rand_int_range(grand, 0, g_list_length(l)); + GList *random = g_list_nth(l, rn); + player->tracks = g_list_append(player->tracks, random->data); + l = g_list_delete_link(l, random); + } + g_rand_free(grand); + } + else + player->tracks = l; + + Track *tr = player->tracks->data; + gchar *str = get_file_name_from_source(tr, SOURCE_PREFER_LOCAL); + if (str) { + gtk_label_set_text(GTK_LABEL(player->song_label), tr->title); // set label to title + g_object_set_data(G_OBJECT (player->song_label), "tr_title", tr->title); // set label to title...again?wtf? + g_object_set_data(G_OBJECT (player->song_label), "tr_artist", tr->artist); // set label to title...again?wtf? + gtk_widget_set_sensitive(player->volume_scale, TRUE); //set volume scale sensitivity to true + } + g_free(str); +} + +void init_media_player(GtkWidget *parent) { + GtkWidget *window; + gst_init_check(0, NULL, NULL); + srand(time(NULL)); + + gchar *glade_path = g_build_filename(get_glade_dir(), "media_player.glade", NULL); + player = g_new0(MediaPlayer, 1); + + player->xml = glade_xml_new(glade_path, "media_window", NULL); + + window = gtkpod_xml_get_widget(player->xml, "media_window"); + player->video_widget = gtkpod_xml_get_widget(player->xml, "video_widget"); + player->media_panel = gtkpod_xml_get_widget(player->xml, "media_panel"); + player->song_label = gtkpod_xml_get_widget(player->xml, "song_label"); + player->media_toolbar = gtkpod_xml_get_widget(player->xml, "media_toolbar"); + + player->play_button = gtkpod_xml_get_widget(player->xml, "play_button"); + player->stop_button = gtkpod_xml_get_widget(player->xml, "stop_button"); + player->previous_button = gtkpod_xml_get_widget(player->xml, "previous_button"); + player->next_button = gtkpod_xml_get_widget(player->xml, "next_button"); + player->song_scale = gtkpod_xml_get_widget(player->xml, "song_scale"); + player->volume_scale = gtkpod_xml_get_widget(player->xml, "volume_scale"); + + g_object_ref(player->media_panel); + gtk_container_remove(GTK_CONTAINER (window), player->media_panel); + gtk_widget_destroy(window); + + if (GTK_IS_SCROLLED_WINDOW(parent)) + gtk_scrolled_window_add_with_viewport(GTK_SCROLLED_WINDOW(parent), player->media_panel); + else + gtk_container_add(GTK_CONTAINER (parent), player->media_panel); + + gtk_widget_show(player->song_label); + gtk_widget_show_all(player->media_toolbar); + + g_free(glade_path); +} + +void destroy_media_player() { + gtk_widget_destroy(player->media_panel); + player = NULL; +} + +void media_player_track_removed_cb(GtkPodApp *app, gpointer tk, gpointer data) { + Track *old_track = tk; + if (!player) + return; + + if (g_list_index(player->tracks, old_track) == -1) + return; + + set_selected_tracks(gtkpod_get_selected_tracks()); +} + +void media_player_set_tracks_cb(GtkPodApp *app, gpointer tks, gpointer data) { + GList *tracks = tks; + + if (!player) + return; + + set_selected_tracks(tracks); +} + +void media_player_track_updated_cb(GtkPodApp *app, gpointer tk, gpointer data) { + Track *track = tk; + + if (!player) + return; + + if (g_list_index(player->tracks, track) == -1) + return; + + set_selected_tracks(gtkpod_get_selected_tracks()); +} + diff --git a/plugins/media_player/media_player.glade b/plugins/media_player/media_player.glade new file mode 100644 index 0000000..67cf218 --- /dev/null +++ b/plugins/media_player/media_player.glade @@ -0,0 +1,152 @@ +<?xml version="1.0"?> +<glade-interface> + <!-- interface-requires gtk+ 2.12 --> + <!-- interface-naming-policy toplevel-contextual --> + <widget class="GtkWindow" id="media_window"> + <property name="window_position">mouse</property> + <signal name="delete_event" handler="on_gtkpod_delete_event"/> + <child> + <widget class="GtkVBox" id="media_panel"> + <property name="visible">True</property> + <property name="orientation">vertical</property> + <child> + <widget class="GtkDrawingArea" id="video_widget"/> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkLabel" id="song_label"> + <property name="visible">True</property> + <property name="xalign">0</property> + <property name="xpad">6</property> + </widget> + <packing> + <property name="expand">False</property> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="media_toolbar"> + <property name="visible">True</property> + <property name="spacing">30</property> + <child> + <widget class="GtkHBox" id="button_box"> + <property name="visible">True</property> + <property name="homogeneous">True</property> + <child> + <widget class="GtkToolButton" id="previous_button"> + <property name="visible">True</property> + <property name="label" translatable="yes">Previous</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-media-previous</property> + <signal name="clicked" handler="on_Previous_button_clicked"/> + </widget> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkToolButton" id="play_button"> + <property name="visible">True</property> + <property name="label" translatable="yes">Play</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-media-play</property> + <signal name="clicked" handler="on_Play_button_clicked"/> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkToolButton" id="stop_button"> + <property name="visible">True</property> + <property name="label" translatable="yes">Stop</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-media-stop</property> + <signal name="clicked" handler="on_Stop_button_clicked"/> + </widget> + <packing> + <property name="position">2</property> + </packing> + </child> + <child> + <widget class="GtkToolButton" id="next_button"> + <property name="visible">True</property> + <property name="label" translatable="yes">Next</property> + <property name="use_underline">True</property> + <property name="stock_id">gtk-media-next</property> + <signal name="clicked" handler="on_Forward_button_clicked"/> + </widget> + <packing> + <property name="position">3</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkHScale" id="song_scale"> + <property name="width_request">150</property> + <property name="visible">True</property> + <property name="can_focus">True</property> + <property name="adjustment">0 0 100 1 10 10</property> + <property name="digits">0</property> + <property name="draw_value">False</property> + <property name="value_pos">left</property> + <signal name="change_value" handler="on_song_scale_change_value"/> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + <child> + <widget class="GtkHBox" id="volume_box"> + <property name="visible">True</property> + <child> + <widget class="GtkImage" id="volume_icon"> + <property name="visible">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="stock">media_player-volume-control-icon</property> + <property name="icon-size">3</property> + </widget> + <packing> + <property name="position">0</property> + </packing> + </child> + <child> + <widget class="GtkHScale" id="volume_scale"> + <property name="width_request">75</property> + <property name="visible">True</property> + <property name="sensitive">False</property> + <property name="can_focus">True</property> + <property name="events">GDK_POINTER_MOTION_MASK | GDK_POINTER_MOTION_HINT_MASK | GDK_BUTTON_PRESS_MASK | GDK_BUTTON_RELEASE_MASK</property> + <property name="adjustment">0 -90 10 0.20000000000000001 2 2</property> + <property name="draw_value">False</property> + </widget> + <packing> + <property name="position">1</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </widget> + <packing> + <property name="expand">False</property> + <property name="fill">False</property> + <property name="position">2</property> + </packing> + </child> + </widget> + </child> + </widget> +</glade-interface> diff --git a/plugins/media_player/media_player.h b/plugins/media_player/media_player.h new file mode 100644 index 0000000..16af085 --- /dev/null +++ b/plugins/media_player/media_player.h @@ -0,0 +1,62 @@ +/* Time-stamp: <2008-01-07 07:07:33 Sonic1> +| +| Copyright (C) 2002-2010 Ryan Houdek <Sonicadvance1 at users.sourceforge.net> +| Modified by Paul Richardson <phantom_sf at users.sourceforge.net> +| Part of the gtkpod project. +| +| URL: http://gtkpod.sourceforge.net/ +| +| 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +| +| iTunes and iPod are trademarks of Apple +| +| This product is not supported/written/published by Apple! +| +| $Id: oggfile.h 954 2007-01-16 09:45:00Z jcsjcs $ +*/ + +#ifndef __MEDIA_PLAYER_H__ +#define __MEDIA_PLAYER_H__ + +#include "glade/glade.h" + +typedef struct { + GtkWidget *media_panel; + GtkWidget *video_widget; + GtkWidget *song_label; + GtkWidget *media_toolbar; + + GtkWidget *previous_button; + GtkWidget *play_button; + GtkWidget *stop_button; + GtkWidget *next_button; + GtkWidget *song_scale; + GtkWidget *volume_scale; + + + GladeXML *xml; + + GList *tracks; + +} MediaPlayer; + +void init_media_player (GtkWidget *parent); +void destroy_media_player(); + +void media_player_track_removed_cb(GtkPodApp *app, gpointer tk, gpointer data); +void media_player_set_tracks_cb(GtkPodApp *app, gpointer tks, gpointer data); +void media_player_track_updated_cb(GtkPodApp *app, gpointer tk, gpointer data); + +#endif diff --git a/plugins/media_player/media_player.plugin b/plugins/media_player/media_player.plugin new file mode 100644 index 0000000..4b07c17 --- /dev/null +++ b/plugins/media_player/media_player.plugin @@ -0,0 +1,4 @@ +[Anjuta Plugin] +Location=media_player:MediaPlayerPlugin +Name=Media Player Plugin +Description=Controls for playing tracks and videos diff --git a/plugins/media_player/media_player.ui b/plugins/media_player/media_player.ui new file mode 100644 index 0000000..b141558 --- /dev/null +++ b/plugins/media_player/media_player.ui @@ -0,0 +1,7 @@ +<!--*- xml -*--> +<ui> + <menubar name="MenuMain"> + </menubar> + <toolbar name="ToolbarMain"> + </toolbar> +</ui> diff --git a/plugins/media_player/plugin.c b/plugins/media_player/plugin.c new file mode 100644 index 0000000..eb4f6df --- /dev/null +++ b/plugins/media_player/plugin.c @@ -0,0 +1,164 @@ +/* + | Copyright (C) 2002-2010 Jorg Schuler <jcsjcs at users sourceforge net> + | Paul Richardson <phantom_sf at users.sourceforge.net> + | Part of the gtkpod project. + | + | URL: http://www.gtkpod.org/ + | URL: http://gtkpod.sourceforge.net/ + | + | 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA + | + | iTunes and iPod are trademarks of Apple + | + | This product is not supported/written/published by Apple! + | + | $Id$ + */ +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <glib.h> +#include <libanjuta/anjuta-utils.h> +#include "libgtkpod/gtkpod_app_iface.h" +#include "libgtkpod/directories.h" +#include "libgtkpod/stock_icons.h" +#include "plugin.h" +#include "media_player.h" + +#define PLAYER_VOLUME_ICON "media_player-volume-control" +#define PLAYER_VOLUME_ICON_STOCK_ID "media_player-volume-control-icon" + +/* Parent class. Part of standard class definition */ +static gpointer parent_class; + +static GtkActionEntry cover_actions[] = + { }; + +static gboolean activate_plugin(AnjutaPlugin *plugin) { + AnjutaUI *ui; + MediaPlayerPlugin *media_player_plugin; + GtkActionGroup* action_group; + + register_icon_path(get_plugin_dir(), "media_player"); + register_stock_icon(PLAYER_VOLUME_ICON, PLAYER_VOLUME_ICON_STOCK_ID); + + media_player_plugin = (MediaPlayerPlugin*) plugin; + ui = anjuta_shell_get_ui(plugin->shell, NULL); + + /* Add our cover_actions */ + action_group + = anjuta_ui_add_action_group_entries(ui, "ActionGroupMediaPlayer", _("Cover Display"), cover_actions, G_N_ELEMENTS (cover_actions), GETTEXT_PACKAGE, TRUE, plugin); + media_player_plugin->action_group = action_group; + + /* Merge UI */ + gchar *uipath = g_build_filename(get_ui_dir(), "media_player.ui", NULL); + media_player_plugin->uiid = anjuta_ui_merge(ui, uipath); + g_free(uipath); + + /* Add widget in Shell. Any number of widgets can be added */ + media_player_plugin->media_player_window = gtk_scrolled_window_new(NULL, NULL); + gtk_widget_ref(media_player_plugin->media_player_window); + gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW (media_player_plugin->media_player_window), GTK_POLICY_NEVER, GTK_POLICY_NEVER); + gtk_scrolled_window_set_shadow_type(GTK_SCROLLED_WINDOW (media_player_plugin->media_player_window), GTK_SHADOW_IN); + + g_signal_connect (gtkpod_app, SIGNAL_TRACKS_DISPLAYED, G_CALLBACK (media_player_set_tracks_cb), NULL); + g_signal_connect (gtkpod_app, SIGNAL_TRACK_REMOVED, G_CALLBACK (media_player_track_removed_cb), NULL); + g_signal_connect (gtkpod_app, SIGNAL_TRACKS_SELECTED, G_CALLBACK (media_player_set_tracks_cb), NULL); + g_signal_connect (gtkpod_app, SIGNAL_TRACK_UPDATED, G_CALLBACK (media_player_track_updated_cb), NULL); + + init_media_player(media_player_plugin->media_player_window); + + // Do not show all as video widget is initially invisible + gtk_widget_show(media_player_plugin->media_player_window); + anjuta_shell_add_widget(plugin->shell, media_player_plugin->media_player_window, "MediaPlayerPlugin", "Media Player", NULL, ANJUTA_SHELL_PLACEMENT_BOTTOM, NULL); + + return TRUE; /* FALSE if activation failed */ +} + +static gboolean deactivate_plugin(AnjutaPlugin *plugin) { + AnjutaUI *ui; + MediaPlayerPlugin *media_player_plugin; + + media_player_plugin = (MediaPlayerPlugin*) plugin; + ui = anjuta_shell_get_ui(plugin->shell, NULL); + + /* Destroy the browser */ + destroy_media_player(); + + /* Remove widgets from Shell */ + anjuta_shell_remove_widget(plugin->shell, media_player_plugin->media_player_window, NULL); + + /* Unmerge UI */ + anjuta_ui_unmerge(ui, media_player_plugin->uiid); + + /* Remove Action groups */ + anjuta_ui_remove_action_group(ui, media_player_plugin->action_group); + + /* FALSE if plugin doesn't want to deactivate */ + return TRUE; +} + +static void media_player_plugin_instance_init(GObject *obj) { + MediaPlayerPlugin *plugin = (MediaPlayerPlugin*) obj; + plugin->uiid = 0; + plugin->media_player_window = NULL; + plugin->action_group = NULL; +} + +static void media_player_plugin_class_init(GObjectClass *klass) { + AnjutaPluginClass *plugin_class = ANJUTA_PLUGIN_CLASS (klass); + + parent_class = g_type_class_peek_parent(klass); + + plugin_class->activate = activate_plugin; + plugin_class->deactivate = deactivate_plugin; +} + +//static void ipreferences_merge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e) { +// GdkPixbuf *pixbuf; +// GError *error = NULL; +// +// MediaPlayerPlugin* plugin = MEDIA_PLAYER_PLUGIN(ipref); +// plugin->prefs = init_media_player_preferences(plugin->glade_path); +// if (plugin->prefs == NULL) +// return; +// +// pixbuf = gtk_icon_theme_load_icon(gtk_icon_theme_get_default(), PREFERENCE_ICON, 48, 0, &error); +// +// if (!pixbuf) { +// g_warning ("Couldn't load icon: %s", error->message); +// g_error_free(error); +// } +// anjuta_preferences_dialog_add_page(ANJUTA_PREFERENCES_DIALOG (anjuta_preferences_get_dialog (prefs)), "gtkpod-media_player-settings", _(TAB_NAME), pixbuf, plugin->prefs); +// g_object_unref(pixbuf); +//} +// +//static void ipreferences_unmerge(IAnjutaPreferences* ipref, AnjutaPreferences* prefs, GError** e) { +// anjuta_preferences_remove_page(prefs, _(TAB_NAME)); +// MediaPlayerPlugin* plugin = MEDIA_PLAYER_PLUGIN(ipref); +// gtk_widget_destroy(plugin->prefs); +//} +// +//static void ipreferences_iface_init(IAnjutaPreferencesIface* iface) { +// iface->merge = ipreferences_merge; +// iface->unmerge = ipreferences_unmerge; +//} + +ANJUTA_PLUGIN_BEGIN (MediaPlayerPlugin, media_player_plugin); +// ANJUTA_PLUGIN_ADD_INTERFACE(ipreferences, IANJUTA_TYPE_PREFERENCES); +ANJUTA_PLUGIN_END; + +ANJUTA_SIMPLE_PLUGIN (MediaPlayerPlugin, media_player_plugin); diff --git a/plugins/media_player/plugin.h b/plugins/media_player/plugin.h new file mode 100644 index 0000000..ecb5006 --- /dev/null +++ b/plugins/media_player/plugin.h @@ -0,0 +1,61 @@ +/* +| Copyright (C) 2002-2010 Jorg Schuler <jcsjcs at users sourceforge net> +| Paul Richardson <phantom_sf at users.sourceforge.net> +| Part of the gtkpod project. +| +| URL: http://www.gtkpod.org/ +| URL: http://gtkpod.sourceforge.net/ +| +| 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., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA +| +| iTunes and iPod are trademarks of Apple +| +| This product is not supported/written/published by Apple! +| +| $Id$ +*/ + +#ifndef PLUGIN_H_ +#define PLUGIN_H_ + +#ifdef HAVE_CONFIG_H +# include <config.h> +#endif + +#include <libanjuta/anjuta-plugin.h> + +extern GType media_player_plugin_get_type (GTypeModule *module); +#define MEDIA_PLAYER_TYPE_PLUGIN (media_player_plugin_get_type (NULL)) +#define MEDIA_PLAYER_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_CAST ((o), MEDIA_PLAYER_TYPE_PLUGIN, MediaPlayerPlugin)) +#define MEDIA_PLAYER_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_CAST ((k), MEDIA_PLAYER_TYPE_PLUGIN, MediaPlayerPluginClass)) +#define MEDIA_PLAYER_IS_PLUGIN(o) (G_TYPE_CHECK_INSTANCE_TYPE ((o), MEDIA_PLAYER_TYPE_PLUGIN)) +#define MEDIA_PLAYER_IS_PLUGIN_CLASS(k) (G_TYPE_CHECK_CLASS_TYPE ((k), MEDIA_PLAYER_TYPE_PLUGIN)) +#define MEDIA_PLAYER_PLUGIN_GET_CLASS(o) (G_TYPE_INSTANCE_GET_CLASS ((o), MEDIA_PLAYER_TYPE_PLUGIN, MediaPlayerPluginClass)) + +typedef struct _MediaPlayerPlugin MediaPlayerPlugin; +typedef struct _MediaPlayerPluginClass MediaPlayerPluginClass; + +struct _MediaPlayerPlugin { + AnjutaPlugin parent; + GtkWidget *media_player_window; + gint uiid; + GtkActionGroup *action_group; +}; + +struct _MediaPlayerPluginClass { + AnjutaPluginClass parent_class; +}; + +#endif /* PLUGIN_H_ */ ------------------------------------------------------------------------------ The Palm PDK Hot Apps Program offers developers who use the Plug-In Development Kit to bring their C/C++ apps to Palm for a share of $1 Million in cash or HP Products. Visit us here for more details: http://ad.doubleclick.net/clk;226879339;13503038;l? http://clk.atdmt.com/CRS/go/247765532/direct/01/ _______________________________________________ gtkpod-cvs2 mailing list gtkpod-cvs2@lists.sourceforge.net https://lists.sourceforge.net/lists/listinfo/gtkpod-cvs2