diff options
-rw-r--r-- | Makefile.am | 9 | ||||
-rw-r--r-- | configure.ac | 15 | ||||
-rw-r--r-- | deadbeef.h | 7 | ||||
-rw-r--r-- | main.c | 309 | ||||
-rw-r--r-- | plugins/gtkui/Makefile.am | 15 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.c (renamed from callbacks.c) | 0 | ||||
-rw-r--r-- | plugins/gtkui/callbacks.h (renamed from callbacks.h) | 0 | ||||
-rw-r--r-- | plugins/gtkui/deadbeef.glade (renamed from deadbeef.glade) | 0 | ||||
-rw-r--r-- | plugins/gtkui/deadbeef.gladep (renamed from deadbeef.gladep) | 0 | ||||
-rw-r--r-- | plugins/gtkui/drawing.h (renamed from drawing.h) | 0 | ||||
-rw-r--r-- | plugins/gtkui/gdkdrawing.c (renamed from gdkdrawing.c) | 0 | ||||
-rw-r--r-- | plugins/gtkui/gtkplaylist.c (renamed from gtkplaylist.c) | 0 | ||||
-rw-r--r-- | plugins/gtkui/gtkplaylist.h (renamed from gtkplaylist.h) | 0 | ||||
-rw-r--r-- | plugins/gtkui/gtksession.c (renamed from gtksession.c) | 0 | ||||
-rw-r--r-- | plugins/gtkui/gtkui.c | 343 | ||||
-rw-r--r-- | plugins/gtkui/interface.c (renamed from interface.c) | 0 | ||||
-rw-r--r-- | plugins/gtkui/interface.h (renamed from interface.h) | 0 |
17 files changed, 438 insertions, 260 deletions
diff --git a/Makefile.am b/Makefile.am index 0bf99b0e..b1e67241 100644 --- a/Makefile.am +++ b/Makefile.am @@ -16,7 +16,8 @@ SUBDIRS = gme/Game_Music_Emu-0.5.2\ ${WAVPACK_DIR}\ ${SNDFILE_DIR}\ ${VFS_CURL_DIR}\ - ${CDDA_DIR} + ${CDDA_DIR}\ + ${GTKUI_DIR} dumbpath=@top_srcdir@/dumb sidpath=@top_srcdir@/sid/sidplay-libs-2.1.0 @@ -27,8 +28,7 @@ bin_PROGRAMS = deadbeef deadbeef_SOURCES =\ main.c common.h deadbeef.h\ plugins.c plugins.h moduleconf.h\ - callbacks.c interface.c support.c callbacks.h interface.h support.h\ - playlist.c playlist.h gtkplaylist.c gtkplaylist.h\ + playlist.c playlist.h \ streamer.c streamer.h\ progress.c progress.h\ codec.c codec.h\ @@ -40,8 +40,7 @@ deadbeef_SOURCES =\ threading_pthread.c threading.h\ md5/md5.c md5/md5.h md5/md5_loc.h\ volume.c volume.h\ - drawing.h gdkdrawing.c\ - session.h session.c gtksession.c\ + session.h session.c \ junklib.h junklib.c utf8.c utf8.h\ optmath.h\ vfs.c vfs.h vfs_stdio.c\ diff --git a/configure.ac b/configure.ac index 9613e33c..b55e861e 100644 --- a/configure.ac +++ b/configure.ac @@ -39,7 +39,8 @@ test "x$prefix" = xNONE && prefix=$ac_default_prefix CFLAGS="$CFLAGS -D_GNU_SOURCE -DLIBDIR=\\\"$libdir\\\" -DPREFIX=\\\"$prefix\\\"" CPPFLAGS="$CFLAGS" -PKG_CHECK_MODULES(DEPS, gtk+-2.0 >= 2.12 gthread-2.0 glib-2.0 samplerate alsa) +PKG_CHECK_MODULES(DEPS, samplerate alsa) +PKG_CHECK_MODULES(GTKUI_DEPS, gtk+-2.0 >= 2.12 gthread-2.0 glib-2.0, HAVE_GTK=1) AX_CHECK_COMPILER_FLAGS(-msse2, SIMD_FLAGS="$SIMD_FLAGS -msse2";HAVE_SSE2=1, []) if test ${HAVE_SSE2}; then @@ -143,6 +144,16 @@ if test ${HAVE_CDIO} && test ${HAVE_CDDB}; then AC_SUBST(CDDA_DIR) fi +dnl gtkui plugin +AM_CONDITIONAL(HAVE_GTK, test $HAVE_GTK) +if test ${HAVE_GTK}; then + GTKUI_DIR="plugins/gtkui" + AC_SUBST(GTKUI_DEPS_CFLAGS) + AC_SUBST(GTKUI_DEPS_LIBS) + AC_SUBST(GTKUI_DIR) +fi + + dnl print summary echo echo "plugin summary:" @@ -172,6 +183,7 @@ PRINT_PLUGIN_INFO([sndfile],[PCM (wav,aiff,etc) player based on libsndfile],[tes PRINT_PLUGIN_INFO([vfs_curl],[http/ftp streaming support],[test $HAVE_CURL]) dnl PRINT_PLUGIN_INFO([faad2],[aac/mp4 player],[test $HAVE_FAAD && test $HAVE_MP4FF]) PRINT_PLUGIN_INFO([cdda],[cd audio player],[test $HAVE_CDIO && test $HAVE_CDDB]) +PRINT_PLUGIN_INFO([gtkui],[GTK user interface],[test $HAVE_GTK]) echo AC_OUTPUT([ @@ -192,6 +204,7 @@ plugins/wavpack/Makefile plugins/sndfile/Makefile plugins/vfs_curl/Makefile plugins/cdda/Makefile +plugins/gtkui/Makefile deadbeef.desktop ]) @@ -412,6 +412,13 @@ typedef struct DB_vfs_s { unsigned streaming : 1; } DB_vfs_t; +// gui plugin +// implements pretty much anything it wants +// works mostly like misc plugin, except we need separate type for that +typedef struct DB_gui_s { + DB_plugin_t plugin; +} DB_gui_t; + #ifdef __cplusplus } #endif @@ -15,7 +15,6 @@ You should have received a copy of the GNU General Public License along with this program. If not, see <http://www.gnu.org/licenses/>. */ -#include <gtk/gtk.h> #include <stdio.h> #include <stdint.h> #include <string.h> @@ -33,19 +32,13 @@ #ifdef HAVE_CONFIG_H # include <config.h> #endif -#include "interface.h" -#include "callbacks.h" -#include "support.h" #include "playlist.h" #include "playback.h" #include "unistd.h" #include "threading.h" #include "messagepump.h" -#include "gtkplaylist.h" #include "codec.h" #include "streamer.h" -#include "search.h" -#include "progress.h" #include "conf.h" #include "volume.h" #include "session.h" @@ -61,116 +54,6 @@ char dbconfdir[1024]; // $HOME/.config/deadbeef char defpl[1024]; // $HOME/.config/deadbeef/default.dbpl char sessfile[1024]; // $HOME/.config/deadbeef/session -// main widgets -GtkWidget *mainwin; -GtkWidget *searchwin; -GtkStatusIcon *trayicon; -GtkWidget *traymenu; - -// playlist configuration structures -gtkplaylist_t main_playlist; -gtkplaylist_t search_playlist; - -// update status bar and window title -static int sb_context_id = -1; -static char sb_text[512]; -static float last_songpos = -1; - -void -update_songinfo (void) { - char sbtext_new[512] = "-"; - float songpos = last_songpos; - - int daystotal = (int)pl_totaltime / (3600*24); - int hourtotal = ((int)pl_totaltime / 3600) % 24; - int mintotal = ((int)pl_totaltime/60) % 60; - int sectotal = ((int)pl_totaltime) % 60; - - char totaltime_str[512] = ""; - if (daystotal == 0) - snprintf (totaltime_str, sizeof (totaltime_str), "%d:%02d:%02d", hourtotal, mintotal, sectotal); - - else if (daystotal == 1) - snprintf (totaltime_str, sizeof (totaltime_str), "1 day %d:%02d:%02d", hourtotal, mintotal, sectotal); - - else - snprintf (totaltime_str, sizeof (totaltime_str), "%d days %d:%02d:%02d", daystotal, hourtotal, mintotal, sectotal); - - if (p_isstopped ()) { - snprintf (sbtext_new, sizeof (sbtext_new), "Stopped | %s total playtime", totaltime_str); - songpos = 0; - } - else if (str_playing_song.decoder) { -// codec_lock (); - DB_decoder_t *c = str_playing_song.decoder; - float playpos = streamer_get_playpos (); - int minpos = playpos / 60; - int secpos = playpos - minpos * 60; - int mindur = str_playing_song._duration / 60; - int secdur = str_playing_song._duration - mindur * 60; - - const char *mode = c->info.channels == 1 ? "Mono" : "Stereo"; - int samplerate = c->info.samplerate; - int bitspersample = c->info.bps; - songpos = playpos; -// codec_unlock (); - - char t[100]; - if (str_playing_song._duration >= 0) { - snprintf (t, sizeof (t), "%d:%02d", mindur, secdur); - } - else { - strcpy (t, "-:--"); - } - - char sbitrate[20] = ""; -#if 0 // NOTE: do not enable that for stable branch yet - int bitrate = streamer_get_bitrate (); - if (bitrate > 0) { - snprintf (sbitrate, sizeof (sbitrate), "%d kbps ", bitrate); - } -#endif - const char *spaused = p_ispaused () ? "Paused | " : ""; - snprintf (sbtext_new, sizeof (sbtext_new), "%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d songs | %s total playtime", spaused, str_playing_song.filetype ? str_playing_song.filetype:"-", sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, pl_getcount (), totaltime_str); - } - - if (strcmp (sbtext_new, sb_text)) { - strcpy (sb_text, sbtext_new); - - // form statusline - GDK_THREADS_ENTER(); - // FIXME: don't update if window is not visible - GtkStatusbar *sb = GTK_STATUSBAR (lookup_widget (mainwin, "statusbar")); - if (sb_context_id == -1) { - sb_context_id = gtk_statusbar_get_context_id (sb, "msg"); - } - - gtk_statusbar_pop (sb, sb_context_id); - gtk_statusbar_push (sb, sb_context_id, sb_text); - - GDK_THREADS_LEAVE(); - } - - if (songpos != last_songpos) { - void seekbar_draw (GtkWidget *widget); - void seekbar_expose (GtkWidget *widget, int x, int y, int w, int h); - if (mainwin) { - GtkWidget *widget = lookup_widget (mainwin, "seekbar"); - // translate volume to seekbar pixels - songpos /= str_playing_song._duration; - songpos *= widget->allocation.width; - if ((int)(songpos*2) != (int)(last_songpos*2)) { - GDK_THREADS_ENTER(); - seekbar_draw (widget); - seekbar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height); - GDK_THREADS_LEAVE(); - last_songpos = songpos; - } - } - } -} - - // -1 error, program must exit with error code -1 // 0 proceed normally as nothing happened // 1 no error, but program must exit with error code 0 @@ -236,7 +119,9 @@ exec_command_line (const char *cmdline, int len, int filter) { // add files if (!queue) { pl_free (); - main_playlist.row = -1; + // <placeholder> + // reset selection in playlist + guiplug_reset_selection (); } while (parg < pend) { char resolved[PATH_MAX]; @@ -316,17 +201,17 @@ server_update (void) { int size; if ((size = recv (s2, str, 2048, 0)) >= 0) { if (size == 1 && str[0] == 0) { - GDK_THREADS_ENTER(); - gtk_widget_show (mainwin); - gtk_window_present (GTK_WINDOW (mainwin)); - GDK_THREADS_LEAVE(); + // <placeholder> + // should notify gui plugin that user tried to run + // application while already running + guiplug_showwindow (); } else { int res = exec_command_line (str, size, 0); if (res == 2) { - GDK_THREADS_ENTER(); - gtkpl_playsong (&main_playlist); - GDK_THREADS_LEAVE(); + // <placeholder> + // play a song, notify gui plugin + guiplug_play_current_song (); } } } @@ -369,60 +254,47 @@ player_thread (uintptr_t ctx) { } break; case M_TERMINATE: - GDK_THREADS_ENTER(); - gtk_widget_hide (mainwin); - gtk_main_quit (); - GDK_THREADS_LEAVE(); + // <placeholder> + // tell gui plugin to shut down + // FIXME: cleanup properly on main thread + guiplug_shutdown (); return; case M_SONGCHANGED: { int from = p1; int to = p2; - gtkpl_songchanged_wrapper (from, to); + // <placeholder> + // notify gui that song was changed + // probably using DB_EV_SONGCHANGED + guiplug_songchanged (from, to); plug_trigger_event (DB_EV_SONGCHANGED, 0); } break; case M_PLAYSONG: - gtkpl_playsong (&main_playlist); - if (playlist_current_ptr) { - GDK_THREADS_ENTER(); - gtkpl_redraw_pl_row (&main_playlist, pl_get_idx_of (playlist_current_ptr), playlist_current_ptr); - GDK_THREADS_LEAVE(); - } + // <placeholder> + // start a track + guiplug_start_current_track (); break; case M_TRACKCHANGED: - { - playItem_t *it = pl_get_for_idx (p1); - if (it) { - GDK_THREADS_ENTER(); - gtkpl_redraw_pl_row (&main_playlist, p1, it); - if (it == playlist_current_ptr) { - gtkpl_current_track_changed (it); - } - GDK_THREADS_LEAVE(); - } - } + // <placeholder> + // notify gui that track information was changed + guiplug_track_changed (p1); break; case M_PLAYSONGNUM: - GDK_THREADS_ENTER(); - gtkpl_playsongnum (p1); - GDK_THREADS_LEAVE(); + // <placeholder> + // start track by number in p1 + guiplug_start_track (p1); break; case M_STOPSONG: - //p_stop (); streamer_set_nextsong (-2, 0); break; case M_NEXTSONG: - GDK_THREADS_ENTER(); p_stop (); pl_nextsong (1); - GDK_THREADS_LEAVE(); break; case M_PREVSONG: - GDK_THREADS_ENTER(); p_stop (); pl_prevsong (); - GDK_THREADS_LEAVE(); break; case M_PAUSESONG: if (p_ispaused ()) { @@ -431,52 +303,50 @@ player_thread (uintptr_t ctx) { else { p_pause (); } - - GDK_THREADS_ENTER(); + // <placeholder> + // notify that current track was paused if (playlist_current_ptr) { - gtkpl_redraw_pl_row (&main_playlist, pl_get_idx_of (playlist_current_ptr), playlist_current_ptr); + guiplug_track_paused (pl_get_idx_of (playlist_current_ptr)); } - GDK_THREADS_LEAVE(); break; case M_PLAYRANDOM: - GDK_THREADS_ENTER(); - gtkpl_randomsong (); - GDK_THREADS_LEAVE(); + // <placeholder> + // play random song + guiplug_start_random (); break; case M_ADDDIR: - { - // long time processing -// float t1 = (float)clock () / CLOCKS_PER_SEC; - gtkpl_add_dir (&main_playlist, (char *)ctx); -// float t2 = (float)clock () / CLOCKS_PER_SEC; -// printf ("time: %f\n", t2-t1); - } + // <placeholder> + // * let guiplug know that addition is in progress + // * call it back on every file + // * let guiplug know that addition is done + guiplug_add_dir ((char *)ctx); break; case M_ADDDIRS: - { - // long time processing -// float t1 = (float)clock () / CLOCKS_PER_SEC; - gtkpl_add_dirs (&main_playlist, (GSList *)ctx); -// float t2 = (float)clock () / CLOCKS_PER_SEC; -// printf ("time: %f\n", t2-t1); - } + // <placeholder> + // same as above, but for many folders + guiplug_add_dirs ((GSList *)ctx); break; case M_ADDFILES: - gtkpl_add_files (&main_playlist, (GSList *)ctx); + // <placeholder> + // same as above but for many files + guiplug_add_files ((GSList *)ctx); break; case M_OPENFILES: p_stop (); - gtkpl_add_files (&main_playlist, (GSList *)ctx); - gtkpl_playsong (&main_playlist); + // <placeholder> + // open many files and start 1st of them + guiplug_open_files ((GSList *)ctx); break; case M_FMDRAGDROP: - gtkpl_add_fm_dropped_files (&main_playlist, (char *)ctx, p1, p2); + // <placeholder> + // handle drag-n-drop from filemanager + // that should be handled internally in ui plugin + guiplug_add_fm_dropped_files ((char *)ctx, p1, p2) break; case M_PLAYLISTREFRESH: - GDK_THREADS_ENTER(); - playlist_refresh (); - search_refresh (); - GDK_THREADS_LEAVE(); + // <placeholder> + // refresh all playlist windows + guiplug_refresh_playlist (); break; case M_CONFIGCHANGED: palsa_configchanged (); @@ -486,77 +356,8 @@ player_thread (uintptr_t ctx) { } } usleep(50000); - update_songinfo (); - } -} - -gboolean -on_trayicon_scroll_event (GtkWidget *widget, - GdkEventScroll *event, - gpointer user_data) -{ - float vol = volume_get_db (); - if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT) { - vol += 1; - } - else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT) { - vol -= 1; + guiplug_frameupdate (); } - if (vol > 0) { - vol = 0; - } - else if (vol < -60) { - vol = -60; - } - volume_set_db (vol); - GtkWidget *volumebar = lookup_widget (mainwin, "volumebar"); - volumebar_draw (volumebar); - volumebar_expose (volumebar, 0, 0, volumebar->allocation.width, volumebar->allocation.height); - return FALSE; -} - -#if GTK_MINOR_VERSION<=14 -gboolean -on_trayicon_activate (GtkWidget *widget, - GdkEvent *event, - gpointer user_data) -{ - if (GTK_WIDGET_VISIBLE (mainwin)) { - gtk_widget_hide (mainwin); - } - else { - gtk_widget_show (mainwin); - gtk_window_present (GTK_WINDOW (mainwin)); - } - return FALSE; -} -#endif - -gboolean -on_trayicon_button_press_event (GtkWidget *widget, - GdkEventButton *event, - gpointer user_data) -{ - if (event->button == 1) { - if (GTK_WIDGET_VISIBLE (mainwin)) { - gtk_widget_hide (mainwin); - } - else { - gtk_widget_show (mainwin); - gtk_window_present (GTK_WINDOW (mainwin)); - } - } - return FALSE; -} - -gboolean -on_trayicon_popup_menu (GtkWidget *widget, - guint button, - guint time, - gpointer user_data) -{ - gtk_menu_popup (GTK_MENU (traymenu), NULL, NULL, gtk_status_icon_position_menu, trayicon, button, time); - return FALSE; } void diff --git a/plugins/gtkui/Makefile.am b/plugins/gtkui/Makefile.am new file mode 100644 index 00000000..13ace983 --- /dev/null +++ b/plugins/gtkui/Makefile.am @@ -0,0 +1,15 @@ +#if HAVE_GTK +#gtkuidir = $(libdir)/$(PACKAGE) +#pkglib_LTLIBRARIES = gtkui.la +#gtkui_la_SOURCES = gtkui.c\ +# callbacks.c interface.c support.c callbacks.h interface.h support.h\ +# gtkplaylist.c gtkplaylist.h\ +# drawing.h gdkdrawing.c\ +# gtksession.c +# +# +#gtkui_la_LDFLAGS = -module +# +#gtkui_la_LIBADD = $(LDADD) $(GTKUI_DEPS_LIBS) +#AM_CFLAGS = -std=c99 $(GTKUI_DEPS_CFLAGS) +#endif diff --git a/callbacks.c b/plugins/gtkui/callbacks.c index 8d6d9bbf..8d6d9bbf 100644 --- a/callbacks.c +++ b/plugins/gtkui/callbacks.c diff --git a/callbacks.h b/plugins/gtkui/callbacks.h index d2e3f61a..d2e3f61a 100644 --- a/callbacks.h +++ b/plugins/gtkui/callbacks.h diff --git a/deadbeef.glade b/plugins/gtkui/deadbeef.glade index c71e3a65..c71e3a65 100644 --- a/deadbeef.glade +++ b/plugins/gtkui/deadbeef.glade diff --git a/deadbeef.gladep b/plugins/gtkui/deadbeef.gladep index 22ea860c..22ea860c 100644 --- a/deadbeef.gladep +++ b/plugins/gtkui/deadbeef.gladep diff --git a/drawing.h b/plugins/gtkui/drawing.h index 23c350b6..23c350b6 100644 --- a/drawing.h +++ b/plugins/gtkui/drawing.h diff --git a/gdkdrawing.c b/plugins/gtkui/gdkdrawing.c index 621ee92e..621ee92e 100644 --- a/gdkdrawing.c +++ b/plugins/gtkui/gdkdrawing.c diff --git a/gtkplaylist.c b/plugins/gtkui/gtkplaylist.c index cef45ea4..cef45ea4 100644 --- a/gtkplaylist.c +++ b/plugins/gtkui/gtkplaylist.c diff --git a/gtkplaylist.h b/plugins/gtkui/gtkplaylist.h index 2e827839..2e827839 100644 --- a/gtkplaylist.h +++ b/plugins/gtkui/gtkplaylist.h diff --git a/gtksession.c b/plugins/gtkui/gtksession.c index e24706b6..e24706b6 100644 --- a/gtksession.c +++ b/plugins/gtkui/gtksession.c diff --git a/plugins/gtkui/gtkui.c b/plugins/gtkui/gtkui.c new file mode 100644 index 00000000..c5a87056 --- /dev/null +++ b/plugins/gtkui/gtkui.c @@ -0,0 +1,343 @@ +/* + DeaDBeeF - ultimate music player for GNU/Linux systems with X11 + Copyright (C) 2009 Alexey Yakovenko + + This program is free software; you can redistribute it and/or + modify it under the terms of the GNU General Public License + as published by the Free Software Foundation; either version 2 + of the License, or (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program; if not, write to the Free Software + Foundation, Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. +*/ +#include "../../deadbeef.h" +#include <gtk/gtk.h> +#include "gtkplaylist.h" +#include "search.h" +#include "progress.h" +#include "interface.h" +#include "callbacks.h" +#include "support.h" + +// main widgets +GtkWidget *mainwin; +GtkWidget *searchwin; +GtkStatusIcon *trayicon; +GtkWidget *traymenu; + +// playlist configuration structures +gtkplaylist_t main_playlist; +gtkplaylist_t search_playlist; + +// update status bar and window title +static int sb_context_id = -1; +static char sb_text[512]; +static float last_songpos = -1; + +static void +update_songinfo (void) { + char sbtext_new[512] = "-"; + float songpos = last_songpos; + + int daystotal = (int)pl_totaltime / (3600*24); + int hourtotal = ((int)pl_totaltime / 3600) % 24; + int mintotal = ((int)pl_totaltime/60) % 60; + int sectotal = ((int)pl_totaltime) % 60; + + char totaltime_str[512] = ""; + if (daystotal == 0) + snprintf (totaltime_str, sizeof (totaltime_str), "%d:%02d:%02d", hourtotal, mintotal, sectotal); + + else if (daystotal == 1) + snprintf (totaltime_str, sizeof (totaltime_str), "1 day %d:%02d:%02d", hourtotal, mintotal, sectotal); + + else + snprintf (totaltime_str, sizeof (totaltime_str), "%d days %d:%02d:%02d", daystotal, hourtotal, mintotal, sectotal); + + if (p_isstopped ()) { + snprintf (sbtext_new, sizeof (sbtext_new), "Stopped | %s total playtime", totaltime_str); + songpos = 0; + } + else if (str_playing_song.decoder) { +// codec_lock (); + DB_decoder_t *c = str_playing_song.decoder; + float playpos = streamer_get_playpos (); + int minpos = playpos / 60; + int secpos = playpos - minpos * 60; + int mindur = str_playing_song._duration / 60; + int secdur = str_playing_song._duration - mindur * 60; + + const char *mode = c->info.channels == 1 ? "Mono" : "Stereo"; + int samplerate = c->info.samplerate; + int bitspersample = c->info.bps; + songpos = playpos; +// codec_unlock (); + + char t[100]; + if (str_playing_song._duration >= 0) { + snprintf (t, sizeof (t), "%d:%02d", mindur, secdur); + } + else { + strcpy (t, "-:--"); + } + + char sbitrate[20] = ""; +#if 0 // NOTE: do not enable that for stable branch yet + int bitrate = streamer_get_bitrate (); + if (bitrate > 0) { + snprintf (sbitrate, sizeof (sbitrate), "%d kbps ", bitrate); + } +#endif + const char *spaused = p_ispaused () ? "Paused | " : ""; + snprintf (sbtext_new, sizeof (sbtext_new), "%s%s %s| %dHz | %d bit | %s | %d:%02d / %s | %d songs | %s total playtime", spaused, str_playing_song.filetype ? str_playing_song.filetype:"-", sbitrate, samplerate, bitspersample, mode, minpos, secpos, t, pl_getcount (), totaltime_str); + } + + if (strcmp (sbtext_new, sb_text)) { + strcpy (sb_text, sbtext_new); + + // form statusline + GDK_THREADS_ENTER(); + // FIXME: don't update if window is not visible + GtkStatusbar *sb = GTK_STATUSBAR (lookup_widget (mainwin, "statusbar")); + if (sb_context_id == -1) { + sb_context_id = gtk_statusbar_get_context_id (sb, "msg"); + } + + gtk_statusbar_pop (sb, sb_context_id); + gtk_statusbar_push (sb, sb_context_id, sb_text); + + GDK_THREADS_LEAVE(); + } + + if (songpos != last_songpos) { + void seekbar_draw (GtkWidget *widget); + void seekbar_expose (GtkWidget *widget, int x, int y, int w, int h); + if (mainwin) { + GtkWidget *widget = lookup_widget (mainwin, "seekbar"); + // translate volume to seekbar pixels + songpos /= str_playing_song._duration; + songpos *= widget->allocation.width; + if ((int)(songpos*2) != (int)(last_songpos*2)) { + GDK_THREADS_ENTER(); + seekbar_draw (widget); + seekbar_expose (widget, 0, 0, widget->allocation.width, widget->allocation.height); + GDK_THREADS_LEAVE(); + last_songpos = songpos; + } + } + } +} + +gboolean +on_trayicon_scroll_event (GtkWidget *widget, + GdkEventScroll *event, + gpointer user_data) +{ + float vol = volume_get_db (); + if (event->direction == GDK_SCROLL_UP || event->direction == GDK_SCROLL_RIGHT) { + vol += 1; + } + else if (event->direction == GDK_SCROLL_DOWN || event->direction == GDK_SCROLL_LEFT) { + vol -= 1; + } + if (vol > 0) { + vol = 0; + } + else if (vol < -60) { + vol = -60; + } + volume_set_db (vol); + GtkWidget *volumebar = lookup_widget (mainwin, "volumebar"); + volumebar_draw (volumebar); + volumebar_expose (volumebar, 0, 0, volumebar->allocation.width, volumebar->allocation.height); + return FALSE; +} + +#if GTK_MINOR_VERSION<=14 +gboolean +on_trayicon_activate (GtkWidget *widget, + GdkEvent *event, + gpointer user_data) +{ + if (GTK_WIDGET_VISIBLE (mainwin)) { + gtk_widget_hide (mainwin); + } + else { + gtk_widget_show (mainwin); + gtk_window_present (GTK_WINDOW (mainwin)); + } + return FALSE; +} +#endif + +gboolean +on_trayicon_button_press_event (GtkWidget *widget, + GdkEventButton *event, + gpointer user_data) +{ + if (event->button == 1) { + if (GTK_WIDGET_VISIBLE (mainwin)) { + gtk_widget_hide (mainwin); + } + else { + gtk_widget_show (mainwin); + gtk_window_present (GTK_WINDOW (mainwin)); + } + } + return FALSE; +} + +gboolean +on_trayicon_popup_menu (GtkWidget *widget, + guint button, + guint time, + gpointer user_data) +{ + gtk_menu_popup (GTK_MENU (traymenu), NULL, NULL, gtk_status_icon_position_menu, trayicon, button, time); + return FALSE; +} + +void +guiplug_showwindow (void) { + GDK_THREADS_ENTER(); + gtk_widget_show (mainwin); + gtk_window_present (GTK_WINDOW (mainwin)); + GDK_THREADS_LEAVE(); +} + +void +guiplug_play_current_song (void) { + GDK_THREADS_ENTER(); + gtkpl_playsong (&main_playlist); + GDK_THREADS_LEAVE(); +} + +void +guiplug_shutdown (void) { + GDK_THREADS_ENTER(); + gtk_widget_hide (mainwin); + gtk_main_quit (); + GDK_THREADS_LEAVE(); +} + +void +guiplug_songchanged (int from, int to) { + gtkpl_songchanged_wrapper (from, to); +} + +void +guiplug_start_current_track (void) { + gtkpl_playsong (&main_playlist); + if (playlist_current_ptr) { + GDK_THREADS_ENTER(); + gtkpl_redraw_pl_row (&main_playlist, pl_get_idx_of (playlist_current_ptr), playlist_current_ptr); + GDK_THREADS_LEAVE(); + } +} +void +guiplug_track_changed (int idx) { + playItem_t *it = pl_get_for_idx (idx); + if (it) { + GDK_THREADS_ENTER(); + gtkpl_redraw_pl_row (&main_playlist, idx, it); + if (it == playlist_current_ptr) { + gtkpl_current_track_changed (it); + } + GDK_THREADS_LEAVE(); + } +} + +void +guiplug_start_track (int idx) { + GDK_THREADS_ENTER(); + gtkpl_playsongnum (idx); + GDK_THREADS_LEAVE(); +} + +void +guiplug_track_paused (int idx) { + GDK_THREADS_ENTER(); + gtkpl_redraw_pl_row (&main_playlist, idx, pl_get_for_idx (idx)); + GDK_THREADS_LEAVE(); +} + +void +guiplug_start_random (void) { + GDK_THREADS_ENTER(); + gtkpl_randomsong (); + GDK_THREADS_LEAVE(); +} + +void +guiplug_add_dir (const char *dir) { + // long time processing + // float t1 = (float)clock () / CLOCKS_PER_SEC; + gtkpl_add_dir (&main_playlist, dir); + // float t2 = (float)clock () / CLOCKS_PER_SEC; + // printf ("time: %f\n", t2-t1); +} + +void +guiplug_add_dirs (GSList *dirs) { + // long time processing + // float t1 = (float)clock () / CLOCKS_PER_SEC; + gtkpl_add_dirs (&main_playlist, dirs); + // float t2 = (float)clock () / CLOCKS_PER_SEC; + // printf ("time: %f\n", t2-t1); +} + +void +guiplug_add_files (GSList *files) { + gtkpl_add_files (&main_playlist, files); +} + +void +guiplug_open_files (GSList *files) { + gtkpl_add_files (&main_playlist, files); + gtkpl_playsong (&main_playlist); +} + +void +guiplug_refresh_playlist (void) { + GDK_THREADS_ENTER(); + playlist_refresh (); + search_refresh (); + GDK_THREADS_LEAVE(); +} + +void +guiplug_add_fm_dropped_files (char *files, int p1, int p2) { + gtkpl_add_fm_dropped_files (&main_playlist, (char *)ctx, p1, p2); +} + +void +guiplug_frameupdate (void) { + update_songinfo (); +} + +void +guiplug_reset_selection (void) { + search_playlist.row = -1; + main_playlist.row = -1; +} + +// define plugin interface +static DB_gui_t plugin = { + DB_PLUGIN_SET_API_VERSION + .plugin.version_major = 0, + .plugin.version_minor = 1, + .plugin.type = DB_PLUGIN_MISC, + .plugin.name = "Standard GTK2 user interface", + .plugin.descr = "", + .plugin.author = "Alexey Yakovenko", + .plugin.email = "waker@users.sourceforge.net", + .plugin.website = "http://deadbeef.sf.net", + .plugin.start = gtkui_start, + .plugin.stop = gtkui_stop +}; diff --git a/interface.c b/plugins/gtkui/interface.c index 88acb8d0..88acb8d0 100644 --- a/interface.c +++ b/plugins/gtkui/interface.c diff --git a/interface.h b/plugins/gtkui/interface.h index f9b470ff..f9b470ff 100644 --- a/interface.h +++ b/plugins/gtkui/interface.h |