[xiph-commits] r11081 - in trunk/maemo/OggPlay: . debian src

mgrimme at svn.xiph.org mgrimme at svn.xiph.org
Sun Apr 2 09:29:27 PDT 2006


Author: mgrimme
Date: 2006-04-02 09:29:16 -0700 (Sun, 02 Apr 2006)
New Revision: 11081

Modified:
   trunk/maemo/OggPlay/ChangeLog
   trunk/maemo/OggPlay/README
   trunk/maemo/OggPlay/TODO
   trunk/maemo/OggPlay/debian/changelog
   trunk/maemo/OggPlay/debian/copyright
   trunk/maemo/OggPlay/debian/files
   trunk/maemo/OggPlay/src/Makefile.am
   trunk/maemo/OggPlay/src/decoder.c
   trunk/maemo/OggPlay/src/decoder.h
   trunk/maemo/OggPlay/src/gui.c
   trunk/maemo/OggPlay/src/gui.h
   trunk/maemo/OggPlay/src/main.c
   trunk/maemo/OggPlay/src/stream.c
   trunk/maemo/OggPlay/src/stream.h
Log:
added some support for playlists and cover art

Modified: trunk/maemo/OggPlay/ChangeLog
===================================================================
--- trunk/maemo/OggPlay/ChangeLog	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/ChangeLog	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1,3 +1,14 @@
+2006-04-02  Martin Grimme  <martin.grimme at lintegra.de>
+
+	* src/*: Added playlist and playlist widget.
+	Added support for freedesktop.org compliant CD covers (.directory
+	files) as "albumart" can create them for instance.
+	
+2006-03-20  Martin Grimme  <martin.grimme at lintegra.de>
+
+	* src/audio.h: Added a simple switch to simulate audio playback in
+	the scratchbox SDK environment, where I don't have sound.
+
 2005-11-21  Martin Grimme  <martin at pycage.de>
 
 	* src/gui.c: Implemented fullscreen mode.

Modified: trunk/maemo/OggPlay/README
===================================================================
--- trunk/maemo/OggPlay/README	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/README	2006-04-02 16:29:16 UTC (rev 11081)
@@ -2,11 +2,10 @@
 =====================
 
 This music player began as a proof-of-concept for Ogg Vorbis playback on the
-Nokia 770 device. As such, there are not many features at the moment, but that
-might change in the near future.
+Nokia 770 device.
 
 Enjoy Ogg Vorbis on your nifty Nokia 770!
 
 
 ---
-(c) 2005, Martin Grimme  <martin.grimme at lintegra.de>
+(c) 2005, 2006 Martin Grimme  <martin.grimme at lintegra.de>

Modified: trunk/maemo/OggPlay/TODO
===================================================================
--- trunk/maemo/OggPlay/TODO	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/TODO	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1,5 +1,11 @@
-- add some buttons such as PLAY, STOP, PAUSE, PREVIOUS, NEXT
 - add playlist support
+
 - implement an additional backend so that MP3 and other formats can be played
-  as well
+  as well (this has to use the libraries already present on the Nokia 770 as
+  Xiph.org does not allow including proprietary codecs)
+
 - integrate well with the maemo look'n feel
+
+- Lyrics lookup in the internet
+
+- Cover art lookup in the internet

Modified: trunk/maemo/OggPlay/debian/changelog
===================================================================
--- trunk/maemo/OggPlay/debian/changelog	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/debian/changelog	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1,3 +1,9 @@
+oggplay (0.30) unstable; urgency=low
+
+  * see ChangeLog for details
+
+ -- Martin Grimme <martin.grimme at lintegra.de>  Son, 2 Apr 2006 17:31:00 +0200
+
 oggplay (0.20) unstable; urgency=low
 
   * see ChangeLog for details

Modified: trunk/maemo/OggPlay/debian/copyright
===================================================================
--- trunk/maemo/OggPlay/debian/copyright	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/debian/copyright	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1,3 +1,3 @@
-Copyright (c) 2005 Martin Grimme
+Copyright (c) 2005, 2006 Martin Grimme
 
 OggPlay is licensed under the terms of the GNU GPL.

Modified: trunk/maemo/OggPlay/debian/files
===================================================================
--- trunk/maemo/OggPlay/debian/files	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/debian/files	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1 +1 @@
-oggplay_0.20_arm.deb unknown optional
+oggplay_0.30_arm.deb unknown optional

Modified: trunk/maemo/OggPlay/src/Makefile.am
===================================================================
--- trunk/maemo/OggPlay/src/Makefile.am	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/src/Makefile.am	2006-04-02 16:29:16 UTC (rev 11081)
@@ -5,7 +5,10 @@
                   decoder.c decoder.h \
                   audio.c audio.h \
                   stream.c stream.h \
-                  ringbuffer.c ringbuffer.h
+                  ringbuffer.c ringbuffer.h \
+                  playlist.c playlist.h \
+                  playlistwidget.c playlistwidget.h \
+                  version.h
 
 oggplay_CFLAGS = $(GTK_CFLAGS) $(OSSO_CFLAGS)
 

Modified: trunk/maemo/OggPlay/src/decoder.c
===================================================================
--- trunk/maemo/OggPlay/src/decoder.c	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/src/decoder.c	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1,6 +1,6 @@
 /*
  *    Ogg vorbis decoder using the Tremor library
- *    Copyright (c) 2005 Martin Grimme  <martin.grimme at lintegra.de>
+ *    Copyright (c) 2005, 2006 Martin Grimme  <martin.grimme at lintegra.de>
  *
  *  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
@@ -50,10 +50,11 @@
 
     if (dec->is_playing) {
       ret = ov_read(&(dec->vf), pcmout, sizeof(pcmout), &current_section);
-
+      dec->has_finished = FALSE;
       if (ret == 0) {
 	fprintf(stderr, "End of stream.\n");
 	dec->is_playing = FALSE;
+	dec->has_finished = TRUE;
 	audio_play(dec->audio, pcmout, 0, 0);
       } else if (ret < 0) {
 	//fprintf(stderr, "Error in stream %d.\n", current_section);
@@ -147,6 +148,7 @@
   dec->vf.datasource = NULL;
   dec->audio = audio_new();
   dec->is_playing = FALSE;
+  dec->has_finished = FALSE;
   
   /* spawn decoder thread */
   pthread_create(&th, NULL, decoder_thread, (void *) dec);
@@ -168,15 +170,17 @@
   ov_cb.tell_func = &tell_func;
   ov_cb.close_func = &close_func;
 
-
   pthread_mutex_lock(&mutex);
-
-  if (ov_open_callbacks((void *) stream, &(dec->vf), NULL, 0, ov_cb) > 0) {
+  if (ov_open_callbacks((void *) stream, &(dec->vf), NULL, 0, ov_cb) < 0) {
+    /* close stream if it's not an OGG Vorbis or does not exist */
+    stream_free(stream);
+    pthread_mutex_unlock(&mutex);
     fprintf(stderr, "Could not open stream.\n");
     return FALSE;
   }
 
   pthread_mutex_lock(&cmdmutex);
+
   vi = ov_info(&(dec->vf), -1);
   dec->channels = vi->channels;
   dec->rate = vi->rate;
@@ -244,6 +248,14 @@
 }
 
 
+gboolean
+decoder_has_finished(Decoder *dec) {
+
+  return dec->has_finished;
+
+}
+
+
 void
 decoder_play(Decoder *dec) {
 

Modified: trunk/maemo/OggPlay/src/decoder.h
===================================================================
--- trunk/maemo/OggPlay/src/decoder.h	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/src/decoder.h	2006-04-02 16:29:16 UTC (rev 11081)
@@ -43,6 +43,7 @@
   int channels;
   int rate;
   gboolean is_playing;
+  gboolean has_finished;
 
   /* Ogg comment tags */
   char *tag_title;
@@ -63,6 +64,7 @@
 long decoder_get_position(Decoder *dec);
 void decoder_set_volume(Decoder *dec, int volume);
 gboolean decoder_is_playing(Decoder *dec);
+gboolean decoder_has_finished(Decoder *dec);
 void decoder_play(Decoder *dec);
 void decoder_stop(Decoder *dec);
 void decoder_seek(Decoder *dec, long millisecs);

Modified: trunk/maemo/OggPlay/src/gui.c
===================================================================
--- trunk/maemo/OggPlay/src/gui.c	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/src/gui.c	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1,6 +1,6 @@
 /*
  *    Graphical user interface for OggPlay
- *    Copyright (c) 2005 Martin Grimme  <martin.grimme at lintegra.de>
+ *    Copyright (c) 2005, 2006 Martin Grimme  <martin.grimme at lintegra.de>
  *
  *  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
@@ -98,15 +98,27 @@
 	Gui *gui) {
 
   GtkWidget *dialog;
-  char *filename;
+  GtkFileFilter *filter;
+  GSList *filenames;
 
+  filter = gtk_file_filter_new();
+  gtk_file_filter_set_name(filter, "Ogg Vorbis");
+  /* TODO: better use the MIME type instead of a bunch of patterns, but then
+           the Nokia 770 doesn't recognize Ogg files... */
+  gtk_file_filter_add_pattern(filter, "*.ogg");
+  gtk_file_filter_add_pattern(filter, "*.Ogg");
+  gtk_file_filter_add_pattern(filter, "*.OGG");
+
   dialog = hildon_file_chooser_dialog_new(GTK_WINDOW(gui->appwindow),
 					  GTK_FILE_CHOOSER_ACTION_OPEN);
+  gtk_file_chooser_set_select_multiple(GTK_FILE_CHOOSER(dialog), TRUE);
+  gtk_file_chooser_set_filter(GTK_FILE_CHOOSER(dialog), filter);
   gtk_widget_show_all(dialog);
 
   if (gtk_dialog_run(GTK_DIALOG(dialog)) == GTK_RESPONSE_OK) {
-    filename = gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(dialog));
-    (gui->open_cb)(gui->open_cb_data, filename);
+    filenames = gtk_file_chooser_get_filenames(GTK_FILE_CHOOSER(dialog));
+    (gui->open_cb)(gui->open_cb_data, filenames);
+    g_slist_free(filenames);
   }
 
   gtk_widget_destroy(dialog);
@@ -115,6 +127,24 @@
 
 
 static void
+prev_cb(GtkWidget *src,
+	Gui *gui) {
+
+  (gui->control_cb)(gui->control_cb_data, PREVIOUS);
+
+}
+
+
+static void
+next_cb(GtkWidget *src,
+	Gui *gui) {
+
+  (gui->control_cb)(gui->control_cb_data, NEXT);
+
+}
+
+
+static void
 play_cb(GtkWidget *src,
 	Gui *gui) {
 
@@ -134,43 +164,82 @@
 
 
 Gui *
-gui_new() {
+gui_new(Playlist *playlist) {
 
   Gui *gui = g_new(Gui, 1);
   GtkWidget *hbox;
+  GtkWidget *hbox2;
+  GtkWidget *vbox;
+  GtkWidget *hrule;
+  GtkWidget *scroller;
+  PLWidget *plw;
   GtkWidget *toolbar;
   GtkToolItem *tb_open;
+  GtkToolItem *tb_prev;
+  GtkToolItem *tb_next;
   GtkToolItem *tb_play;
   GtkToolItem *tb_stop;
   GtkToolItem *tb_seekbar;
   GtkToolItem *tb_timelabel;
 
+  gui->coverpath = g_strdup("");
 
   gui->appwindow = HILDON_APP(hildon_app_new());
-  hildon_app_set_title(gui->appwindow, "OggPlay");
+  hildon_app_set_title(gui->appwindow, FULLNAME);
   hildon_app_set_two_part_title(gui->appwindow, FALSE);
 
   gui->appview = HILDON_APPVIEW(hildon_appview_new(NULL));
   hildon_app_set_appview(gui->appwindow, gui->appview);
 
+  /* vbox containing everything */
+  vbox = gtk_vbox_new(FALSE, 6);
+  gtk_container_add(GTK_CONTAINER(gui->appview), vbox);
+  
+  /* cover and tags */
   hbox = gtk_hbox_new(FALSE, 0);
-  gtk_container_add(GTK_CONTAINER(gui->appview), hbox);
+  gtk_box_pack_start(GTK_BOX(vbox), hbox, FALSE, FALSE, 6);
 
-  gui->volumebar = hildon_vvolumebar_new();
-  gtk_box_pack_start(GTK_BOX(hbox), gui->volumebar, FALSE, FALSE, 0);
+  gui->albumcover = gtk_image_new();
+  gtk_box_pack_start(GTK_BOX(hbox), gui->albumcover, FALSE, FALSE, 6);
 
   gui->songlabel = gtk_label_new("");
-  gtk_box_pack_start(GTK_BOX(hbox), gui->songlabel, TRUE, TRUE, 0);
+  gtk_box_pack_start(GTK_BOX(hbox), gui->songlabel, FALSE, FALSE, 6);
 
+  /* separator */
+  hrule = gtk_hseparator_new();
+  gtk_box_pack_start(GTK_BOX(vbox), hrule, FALSE, FALSE, 0);
+
+  /* volume bar and playlist */
+  hbox2 = gtk_hbox_new(FALSE, 0);
+  gtk_container_add(GTK_CONTAINER(vbox), hbox2);
+
+  gui->volumebar = hildon_vvolumebar_new();
+  gtk_box_pack_start(GTK_BOX(hbox2), gui->volumebar, FALSE, FALSE, 0);
+
+  scroller = gtk_scrolled_window_new(NULL, NULL);
+  gtk_scrolled_window_set_policy(GTK_SCROLLED_WINDOW(scroller), 
+				 GTK_POLICY_AUTOMATIC,
+				 GTK_POLICY_AUTOMATIC);
+  gtk_box_pack_start(GTK_BOX(hbox2), scroller,
+		     TRUE, TRUE, 0);
+  
+  plw = plwidget_new();
+  plwidget_set_playlist(plw, playlist);
+  gtk_container_add(GTK_CONTAINER(scroller), plwidget_get_widget(plw));
+
+  /* toolbar */
   toolbar = gtk_toolbar_new();
   gtk_box_pack_end(GTK_BOX(gui->appview->vbox), toolbar, TRUE, TRUE, 0);
 
+  tb_prev = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PREVIOUS);
+  tb_next = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_NEXT);
+
   tb_open = gtk_tool_button_new_from_stock(GTK_STOCK_OPEN);
   gui->tb_play = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_PLAY);
   tb_stop = gtk_tool_button_new_from_stock(GTK_STOCK_MEDIA_STOP);
 
   gui->seekbar = hildon_seekbar_new();
-  gtk_widget_set_size_request(gui->seekbar, 400, -1);
+  gtk_widget_set_size_request(gui->seekbar, 240, -1);
   tb_seekbar = gtk_tool_item_new();
   gtk_container_add(GTK_CONTAINER(tb_seekbar), gui->seekbar);
 
@@ -179,8 +248,10 @@
   gtk_container_add(GTK_CONTAINER(tb_timelabel), gui->timelabel);
 
   gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tb_open, -1);
+  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tb_prev, -1);
   gtk_toolbar_insert(GTK_TOOLBAR(toolbar), gui->tb_play, -1);
   gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tb_stop, -1);
+  gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tb_next, -1);
   gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tb_seekbar, -1);
   gtk_toolbar_insert(GTK_TOOLBAR(toolbar), tb_timelabel, -1);
 
@@ -198,6 +269,12 @@
   g_signal_connect(G_OBJECT(gui->seekbar), "value-changed",
 		   G_CALLBACK(seek_cb), gui);
 
+  g_signal_connect(G_OBJECT(tb_prev), "clicked",
+		   G_CALLBACK(prev_cb), gui);
+
+  g_signal_connect(G_OBJECT(tb_next), "clicked",
+		   G_CALLBACK(next_cb), gui);
+
   g_signal_connect(G_OBJECT(tb_open), "clicked",
 		   G_CALLBACK(open_cb), gui);
 
@@ -295,7 +372,7 @@
 	     int seconds,
 	     int total) {
 
-  int mins, secs;
+  int mins, secs, tmins, tsecs;
   char *time;
 
   gui->seek_position = seconds;
@@ -306,7 +383,11 @@
   secs = seconds % 60;
   seconds /= 60;
   mins = seconds;
-  time = g_strdup_printf("   %2d:%02d", mins, secs);
+  tsecs = total % 60;
+  total /= 60;
+  tmins = total;
+
+  time = g_strdup_printf("   %2d:%02d / %2d:%02d", mins, secs, tmins, tsecs);
   gtk_label_set_text(GTK_LABEL(gui->timelabel), time);
   g_free(time);
 
@@ -325,3 +406,47 @@
 				 GTK_STOCK_MEDIA_PLAY);
       
 }
+
+
+void
+gui_load_cover(Gui *gui,
+	       const char *path) {
+
+  GdkPixbuf *pbuf;
+
+  if (g_ascii_strcasecmp(path, gui->coverpath) == 0) {
+
+    return;
+
+  } else if (g_file_test(path, G_FILE_TEST_EXISTS)) {
+
+    pbuf = gdk_pixbuf_new_from_file_at_scale(path, COVERSIZE, COVERSIZE,
+					     TRUE, NULL);
+    g_object_ref(G_OBJECT(pbuf));
+    gtk_image_set_from_pixbuf(GTK_IMAGE(gui->albumcover), pbuf);
+    g_object_unref(G_OBJECT(pbuf));
+    gtk_widget_show(gui->albumcover);
+
+    g_free(gui->coverpath);
+    gui->coverpath = g_strdup(path);
+
+  } else {
+
+    gtk_widget_hide(gui->albumcover);
+
+    g_free(gui->coverpath);
+    gui->coverpath = g_strdup("");
+
+  }
+
+}
+
+
+void
+gui_show_error(Gui *gui,
+	       const char *message) {
+
+  gtk_infoprint_with_icon_stock(GTK_WINDOW(gui->appwindow),
+				message, GTK_STOCK_DIALOG_ERROR);
+  
+}

Modified: trunk/maemo/OggPlay/src/gui.h
===================================================================
--- trunk/maemo/OggPlay/src/gui.h	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/src/gui.h	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1,6 +1,6 @@
 /*
  *    Graphical user interface for OggPlay
- *    Copyright (c) 2005 Martin Grimme  <martin.grimme at lintegra.de>
+ *    Copyright (c) 2005, 2006 Martin Grimme  <martin.grimme at lintegra.de>
  *
  *  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
@@ -27,19 +27,28 @@
 #include <hildon-widgets/hildon-file-chooser-dialog.h>
 #include <hildon-widgets/hildon-seekbar.h>
 #include <hildon-widgets/hildon-vvolumebar.h>
+#include <hildon-widgets/gtk-infoprint.h>
 #include <gtk/gtk.h>
 #include <gdk/gdkkeysyms.h>
+#include <glib.h>
 
+#include "version.h"
 #include "stream.h"
 #include "decoder.h"
+#include "playlistwidget.h"
+#include "playlist.h"
 
 
-#define OPEN_CB    void (*open_cb)    (void *userdata, const char *uri)
+/* size of the cover image */
+#define COVERSIZE 112
+
+/* callback handlers */
+#define OPEN_CB    void (*open_cb)    (void *userdata, GSList *filenames)
 #define SEEK_CB    void (*seek_cb)    (void *userdata, int seconds)
 #define VOLUME_CB  void (*volume_cb)  (void *userdata, int volume)
 #define CONTROL_CB void (*control_cb) (void *userdata, int command)
 
-enum Command { PLAY, STOP };
+enum Command { PLAY, STOP, PREVIOUS, NEXT };
 
 
 struct _Gui {
@@ -53,12 +62,13 @@
   CONTROL_CB;
   void *control_cb_data;
 
-
+  char *coverpath;
   int seek_position;
 
   HildonApp *appwindow;
   HildonAppView *appview;
   GtkWidget *volumebar;
+  GtkWidget *albumcover;
   GtkWidget *songlabel;
   GtkWidget *seekbar;
   GtkWidget *timelabel;
@@ -68,7 +78,7 @@
 typedef struct _Gui Gui;
 
 
-Gui *gui_new();
+Gui *gui_new(Playlist *playlist);
 void gui_run();
 void gui_quit();
 
@@ -82,4 +92,8 @@
 void gui_set_time(Gui *gui, int seconds, int total);
 void gui_set_paused(Gui *gui, gboolean value);
 
+void gui_load_cover(Gui *gui, const char *path);
+
+void gui_show_error(Gui *gui, const char *message);
+
 #endif

Modified: trunk/maemo/OggPlay/src/main.c
===================================================================
--- trunk/maemo/OggPlay/src/main.c	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/src/main.c	2006-04-02 16:29:16 UTC (rev 11081)
@@ -1,6 +1,6 @@
 /*
  *    Ogg Vorbis player for the Nokia 770
- *    Copyright (c) 2005 Martin Grimme  <martin.grimme at lintegra.de>
+ *    Copyright (c) 2005, 2006 Martin Grimme  <martin.grimme at lintegra.de>
  *
  *  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
@@ -19,18 +19,23 @@
  */
 
 
+#include "version.h"
 #include "gui.h"
+#include "playlist.h"
 #include "decoder.h"
 #include "stream.h"
 #include <libosso.h>
+#include <unistd.h>
 
 
-#define SERVICE_NAME "oggplay"
-#define VERSION "0.20"
 
+enum RunMode { GUI, CMDLINE };
 
+
 struct _AppData {
 
+  enum RunMode runmode;
+  Playlist *playlist;
   Decoder *decoder;
   Stream *stream;
   Gui *gui;
@@ -41,29 +46,54 @@
 
 
 
+/* Looks up a freedesktop.org compliant cover for the given path. */
+char *
+lookup_cover(const char *path) {
 
-/* callback for updating status information */
-static int
-status_cb(AppData *appdata) {
+  GKeyFile *keyfile;
+  char *keyfilepath;
+  char *value;
+  char *coverpath;
 
-  int p, t;
+  /* build path to the .directory desktop file */
+  keyfilepath = g_build_path("/", path, ".directory", NULL);
+
+  if (g_file_test(keyfilepath, G_FILE_TEST_EXISTS)) {
   
-  if (decoder_is_playing(appdata->decoder)) {
-    p = decoder_get_position(appdata->decoder);
-    t = decoder_get_total(appdata->decoder);
-    gui_set_time(appdata->gui, p, t);
+    /* read desktop file */
+    keyfile = g_key_file_new();
+    g_key_file_load_from_file(keyfile, keyfilepath, G_KEY_FILE_NONE, NULL);
+
+    /* read icon entry */
+    value = g_key_file_get_string(keyfile, "Desktop Entry", "Icon", NULL);
+
+    if (g_path_is_absolute(value))
+      coverpath = g_strdup(value);
+    else
+      coverpath = g_build_path("/", path, value, NULL);
+
+    g_free(value);
+    g_key_file_free(keyfile);
+
+  } else {
+
+    coverpath = NULL;
+
   }
 
-  return TRUE;
+  g_free(keyfilepath);  
 
+  return coverpath;
+  
 }
 
 
+void
+open_uri(AppData *appdata,
+	 const char *uri) {
 
-/* callback for opening a file */
-static void
-open_cb(AppData *appdata,
-	const char *uri) {
+  char *dirname;
+  char *cover;
 
   /* close old stream */
   if (appdata->stream)
@@ -71,18 +101,91 @@
 
   /* open new stream */
   appdata->stream = stream_new_from_uri(uri);
-  decoder_open_stream(appdata->decoder, appdata->stream);
-  decoder_play(appdata->decoder);
+  if (! decoder_open_stream(appdata->decoder, appdata->stream)) {
+    appdata->stream = NULL;
+    gui_show_error(appdata->gui, "Could not open file");
+  } else {
+    decoder_play(appdata->decoder);
+  }
 
+  /* look for cover art */
+  dirname = g_path_get_dirname(uri);
+  cover = lookup_cover(dirname);
+  gui_load_cover(appdata->gui, cover);
+  g_free(dirname);
+  g_free(cover);
+
+  /* set song label */
   gui_set_title(appdata->gui,
 		appdata->decoder->tag_title,
 		appdata->decoder->tag_artist,
 		appdata->decoder->tag_album);
 
+}
 
+
+
+
+/* callback for updating status information */
+static int
+status_cb(AppData *appdata) {
+
+  int p, t;
+
+  if (! appdata->stream) {
+
+    return TRUE;
+
+  }
+  
+  else if (decoder_is_playing(appdata->decoder)) {
+
+    p = decoder_get_position(appdata->decoder);
+    t = decoder_get_total(appdata->decoder);
+    gui_set_time(appdata->gui, p, t);
+
+  } else if (decoder_has_finished(appdata->decoder)) {
+
+    playlist_next(appdata->playlist);
+
+  }
+
+  return TRUE;
+
 }
 
 
+/* callback for playing URIs */
+static void
+play_cb(AppData *appdata,
+	const char *uri) {
+
+  open_uri(appdata, uri);
+  //gui_set_title(appdata->gui,
+  //	appdata->decoder->tag_title,
+  //	appdata->decoder->tag_artist,
+  //	appdata->decoder->tag_album);
+
+}
+
+
+
+/* callback for opening a file */
+static void
+open_cb(AppData *appdata,
+	GSList *filenames) {
+
+  GSList *iter;
+
+  for (iter = filenames; iter != NULL; iter = iter->next) {
+    playlist_append(appdata->playlist, (char *) iter->data);
+  }
+  
+  //open_uri(appdata, uri);
+
+}
+
+
 /* callback for seeking */
 static void
 seek_cb(AppData *appdata,
@@ -129,6 +232,15 @@
     gui_set_paused(appdata->gui, FALSE);
     break;
 
+  case (PREVIOUS):
+    playlist_previous(appdata->playlist);
+    break;
+
+  case (NEXT):
+    decoder_stop(appdata->decoder);
+    playlist_next(appdata->playlist);
+    break;
+
   default:
     break;
   }
@@ -137,26 +249,37 @@
 
 
 
-int
-main(int argc,
-     char *argv[]) {
 
+void
+gui_mode(int argc,
+	 char *argv[]) {
+
   osso_context_t *osso_context;
+  char *versionstring;
   AppData *appdata = g_new(AppData, 1);
+  appdata->runmode = GUI;
 
 
   gtk_init(&argc, &argv);
 
   /* register OSSO service */
-  osso_context = osso_initialize(SERVICE_NAME, VERSION, TRUE, NULL);
+  osso_context = osso_initialize(NAME, VERSION, TRUE, NULL);
   if (! osso_context)
     fprintf(stderr, "Could not initialize OSSO.");
 
+  appdata->playlist = playlist_new();
   appdata->decoder = decoder_new();
   appdata->stream = NULL;
+  appdata->gui = gui_new(appdata->playlist);
 
+  versionstring = g_strconcat(FULLNAME, " ", VERSION, NULL);
+  gui_set_title(appdata->gui, "", versionstring, "");
+  g_free(versionstring);
+
+  /* setup callbacks */
+  playlist_set_play_cb(appdata->playlist, play_cb, (void *) appdata);
+
   /* setup GUI callbacks */
-  appdata->gui = gui_new();
   gui_set_open_cb(appdata->gui, open_cb, (void *) appdata);
   gui_set_volume_cb(appdata->gui, volume_cb, (void *) appdata);
   gui_set_seek_cb(appdata->gui, seek_cb, (void *) appdata);
@@ -166,7 +289,51 @@
 
   gui_run();
 
+}
 
+
+void
+cmdline_mode(int argc,
+	     char *argv[]) {
+
+  int p, t;
+
+  AppData *appdata = g_new(AppData, 1);
+  appdata->runmode = CMDLINE;
+  appdata->playlist = playlist_new();
+  appdata->decoder = decoder_new();
+  appdata->stream = NULL;
+
+
+  /* setup callbacks */
+  playlist_set_play_cb(appdata->playlist, play_cb, (void *) appdata);
+  playlist_next(appdata->playlist);
+
+  while (TRUE) {
+    if (decoder_is_playing(appdata->decoder)) {
+      
+      p = decoder_get_position(appdata->decoder);
+      t = decoder_get_total(appdata->decoder);
+      printf("%s: %d / %d\n", appdata->decoder->tag_title, p, t);
+
+    } else if (decoder_has_finished(appdata->decoder)) {
+
+      playlist_next(appdata->playlist);
+    }
+
+    usleep(500);
+  }
+
+}
+
+
+
+int
+main(int argc,
+     char *argv[]) {
+
+  gui_mode(argc, argv);
+
   return 0;
 
 }

Modified: trunk/maemo/OggPlay/src/stream.c
===================================================================
--- trunk/maemo/OggPlay/src/stream.c	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/src/stream.c	2006-04-02 16:29:16 UTC (rev 11081)
@@ -49,6 +49,9 @@
       if (result == GNOME_VFS_OK) {
 	is_open = TRUE;
 	position = 0;
+      } else {
+	printf("Error: '%s' %d\n", stream->uri, result);
+	stream->error = result;
       }
       break;
     case (STREAM_CLOSE):
@@ -70,6 +73,7 @@
 	result = gnome_vfs_seek(handle, vfswhence,
 				(GnomeVFSFileOffset) stream->seek_position);
 	ringbuffer_clear(stream->buffer);
+
 	gnome_vfs_tell(handle, &bytes_read);
 	position = (long) bytes_read;
 	stream->positiontag = position;
@@ -84,10 +88,11 @@
 
     if (is_open && ! ringbuffer_is_full(stream->buffer)) {
       result = gnome_vfs_read(handle, buffer, sizeof(buffer), &bytes_read);
-      if (result == GNOME_VFS_OK) {
+      if (! stream->error && result == GNOME_VFS_OK) {
 
 	position += (long) bytes_read;
 	((long *) tmp)[0] = position;
+
 	ringbuffer_put(stream->buffer, tmp, 8);
 	ringbuffer_put(stream->buffer, buffer, (int) bytes_read);
 
@@ -117,7 +122,9 @@
   if (! gnome_vfs_initialized())
     gnome_vfs_init();
 
-  stream->uri = (char *) uri;
+  stream->error = 0;
+
+  stream->uri = g_strdup(uri);
   stream->buffer = ringbuffer_new(10, BUFFER_SIZE);
   stream->cmd = STREAM_OPEN;
   stream->positiontag = 0;
@@ -148,8 +155,11 @@
 	    char *buffer,
 	    int size) {
 
+  if (stream->error) return 0;
+
   pthread_mutex_lock(&cmdmutex);
   stream->cmd = STREAM_READ;  /* just to ensure the correct order */
+
   ringbuffer_get(stream->buffer, buffer);
   stream->positiontag = ((long *) buffer)[0];
 
@@ -161,6 +171,8 @@
 long
 stream_tell(Stream *stream) {
 
+  //if (stream->error) return 0;
+
   pthread_mutex_lock(&cmdmutex);
   printf("Tell %d\n", stream->positiontag);
   return stream->positiontag;
@@ -173,6 +185,8 @@
 	    long position,
 	    int whence) {
 
+  //if (stream->error) return;
+
   pthread_mutex_lock(&cmdmutex);
 
   if (whence == SEEK_CUR) {

Modified: trunk/maemo/OggPlay/src/stream.h
===================================================================
--- trunk/maemo/OggPlay/src/stream.h	2006-04-02 10:04:47 UTC (rev 11080)
+++ trunk/maemo/OggPlay/src/stream.h	2006-04-02 16:29:16 UTC (rev 11081)
@@ -36,6 +36,8 @@
   GnomeVFSHandle *handle;
   enum streamcommand cmd;
 
+  int error;
+
   long positiontag;
   long seek_position;
   int seek_whence;



More information about the commits mailing list