From 50253414092b1aba7922e186817f9a25b02ab477 Mon Sep 17 00:00:00 2001 From: waker Date: Sun, 23 Aug 2009 18:25:33 +0200 Subject: some basic session management --- Makefile.am | 27 ++++--- callbacks.c | 45 +++++++++++- callbacks.h | 5 ++ common.h | 6 ++ deadbeef.glade | 1 + gtksession.c | 41 +++++++++++ interface.c | 3 + main.c | 7 ++ session.c | 227 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ session.h | 48 ++++++++++++ volume.c | 3 + 11 files changed, 398 insertions(+), 15 deletions(-) create mode 100644 gtksession.c create mode 100644 session.c create mode 100644 session.h diff --git a/Makefile.am b/Makefile.am index 03d9ff3e..d0d082ec 100644 --- a/Makefile.am +++ b/Makefile.am @@ -8,19 +8,24 @@ gmepath=@top_srcdir@/gme/Game_Music_Emu-0.5.2 bin_PROGRAMS = deadbeef -deadbeef_SOURCES = callbacks.c csid.cpp interface.c playlist.c streamer.c\ - cdumb.c cmp3.c cvorbis.c main.c progress.c support.c\ - cflac.c codec.c messagepump.c\ - cgme.c conf.c gtkplaylist.c palsa.c search.c threading_pthread.c\ - md5/md5.c\ - callbacks.h cmod.h conf.h messages.h progress.h support.h\ - cdumb.h cmp3.h gtkplaylist.h palsa.h threading.h\ - cflac.h codec.h csid.h interface.h playback.h search.h\ - cgme.h common.h cvorbis.h messagepump.h playlist.h streamer.h\ +deadbeef_SOURCES =\ + main.c common.h\ + callbacks.c interface.c support.c callbacks.h interface.h support.h\ + playlist.c playlist.h gtkplaylist.c gtkplaylist.h\ + streamer.c streamer.h\ + progress.c progress.h\ + codec.c codec.h\ + messagepump.c messagepump.h messages.h\ + conf.c conf.h\ + search.c search.h\ + csid.cpp cdumb.c cmp3.c cvorbis.c cflac.c cgme.c \ + palsa.c palsa.h playback.h\ + threading_pthread.c threading.h\ + md5/md5.c md5/md5.h md5/md5_loc.h\ + csid.h cdumb.h cmp3.h cvorbis.h cflac.h cgme.h\ volume.c volume.h\ drawing.h gdkdrawing.c\ - md5/md5.h md5/md5_loc.h - + session.h session.c gtksession.c deadbeef_LDADD = $(LDADD) $(DEPS_LIBS) gme/Game_Music_Emu-0.5.2/gme/libgme.a sid/sidplay-libs-2.1.0/libsidplay2.a dumb/libdumb.a diff --git a/callbacks.c b/callbacks.c index 712f2feb..3bc07513 100644 --- a/callbacks.c +++ b/callbacks.c @@ -43,6 +43,7 @@ #include "streamer.h" #include "progress.h" #include "volume.h" +#include "session.h" #include "cvorbis.h" #include "cdumb.h" @@ -201,8 +202,16 @@ on_open_activate (GtkMenuItem *menuitem, gtk_file_filter_add_pattern (flt, "*"); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE); - - if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_OK) + // restore folder + gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), session_get_directory ()); + int response = gtk_dialog_run (GTK_DIALOG (dlg)); + // store folder + gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg)); + if (folder) { + session_set_directory (folder); + g_free (folder); + } + if (response == GTK_RESPONSE_OK) { pl_free (); GSList *lst = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dlg)); @@ -256,7 +265,16 @@ on_add_files_activate (GtkMenuItem *menuitem, gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt); gtk_file_chooser_set_select_multiple (GTK_FILE_CHOOSER (dlg), TRUE); - if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_OK) + // restore folder + gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), session_get_directory ()); + int response = gtk_dialog_run (GTK_DIALOG (dlg)); + // store folder + gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg)); + if (folder) { + session_set_directory (folder); + g_free (folder); + } + if (response == GTK_RESPONSE_OK) { GSList *lst = gtk_file_chooser_get_filenames (GTK_FILE_CHOOSER (dlg)); gtk_widget_destroy (dlg); @@ -307,7 +325,16 @@ on_add_folder1_activate (GtkMenuItem *menuitem, gtk_file_filter_set_name (flt, "Other files (*)"); gtk_file_filter_add_pattern (flt, "*"); gtk_file_chooser_add_filter (GTK_FILE_CHOOSER (dlg), flt); - if (gtk_dialog_run (GTK_DIALOG (dlg)) == GTK_RESPONSE_OK) + // restore folder + gtk_file_chooser_set_current_folder_uri (GTK_FILE_CHOOSER (dlg), session_get_directory ()); + int response = gtk_dialog_run (GTK_DIALOG (dlg)); + // store folder + gchar *folder = gtk_file_chooser_get_current_folder_uri (GTK_FILE_CHOOSER (dlg)); + if (folder) { + session_set_directory (folder); + g_free (folder); + } + if (response == GTK_RESPONSE_OK) { gchar *folder = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (dlg)); gtk_widget_destroy (dlg); @@ -1145,3 +1172,13 @@ on_volumebar_scroll_event (GtkWidget *widget, } + +gboolean +on_mainwin_configure_event (GtkWidget *widget, + GdkEventConfigure *event, + gpointer user_data) +{ + session_capture_window_attrs ((uintptr_t)widget); + return FALSE; +} + diff --git a/callbacks.h b/callbacks.h index 640cb10b..8857d7cf 100644 --- a/callbacks.h +++ b/callbacks.h @@ -487,3 +487,8 @@ on_volumebar_scroll_event (GtkWidget *widget, void on_order_shuffle_activate (GtkMenuItem *menuitem, gpointer user_data); + +gboolean +on_mainwin_configure_event (GtkWidget *widget, + GdkEventConfigure *event, + gpointer user_data); diff --git a/common.h b/common.h index 8ac08d46..13515721 100644 --- a/common.h +++ b/common.h @@ -21,4 +21,10 @@ #define min(x,y) ((x)<(y)?(x):(y)) #define max(x,y) ((x)>(y)?(x):(y)) +// those are defined in main.c +extern char confdir[1024]; // $HOME/.config +extern char dbconfdir[1024]; // $HOME/.config/deadbeef +extern char defpl[1024]; // $HOME/.config/deadbeef/default.dbpl +extern char sessfile[1024]; // $HOME/.config/deadbeef/session + #endif // __COMMON_H diff --git a/deadbeef.glade b/deadbeef.glade index a4e18d11..ae43df5f 100644 --- a/deadbeef.glade +++ b/deadbeef.glade @@ -24,6 +24,7 @@ False + diff --git a/gtksession.c b/gtksession.c new file mode 100644 index 00000000..45a320f0 --- /dev/null +++ b/gtksession.c @@ -0,0 +1,41 @@ +/* + 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 +#include +#ifdef HAVE_CONFIG_H +# include +#endif +#include "session.h" + +void +session_capture_window_attrs (uintptr_t window) { + GtkWindow *wnd = GTK_WINDOW (window); + extern int session_win_attrs[5]; + gtk_window_get_position (wnd, &session_win_attrs[0], &session_win_attrs[1]); + gtk_window_get_size (wnd, &session_win_attrs[2], &session_win_attrs[3]); + //printf ("attrs: %d %d %d %d\n", session_win_attrs[0], session_win_attrs[1], session_win_attrs[2], session_win_attrs[3]); +} + +void +session_restore_window_attrs (uintptr_t window) { + GtkWindow *wnd = GTK_WINDOW (window); + extern int session_win_attrs[5]; + gtk_window_move (wnd, session_win_attrs[0], session_win_attrs[1]); + gtk_window_resize (wnd, session_win_attrs[2], session_win_attrs[3]); +} diff --git a/interface.c b/interface.c index e14b4328..ab493525 100644 --- a/interface.c +++ b/interface.c @@ -360,6 +360,9 @@ create_mainwin (void) g_signal_connect ((gpointer) mainwin, "delete_event", G_CALLBACK (on_mainwin_delete_event), NULL); + g_signal_connect ((gpointer) mainwin, "configure_event", + G_CALLBACK (on_mainwin_configure_event), + NULL); g_signal_connect ((gpointer) open, "activate", G_CALLBACK (on_open_activate), NULL); diff --git a/main.c b/main.c index 3ccce32a..725d0ac6 100644 --- a/main.c +++ b/main.c @@ -47,6 +47,7 @@ #include "progress.h" #include "conf.h" #include "volume.h" +#include "session.h" #ifndef PREFIX #error PREFIX must be defined @@ -56,6 +57,7 @@ char confdir[1024]; // $HOME/.config 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; @@ -500,6 +502,7 @@ main (int argc, char *argv[]) { return -1; } snprintf (defpl, 1024, "%s/.config/deadbeef/default.dbpl", homedir); + snprintf (sessfile, 1024, "%s/.config/deadbeef/session", homedir); snprintf (confdir, 1024, "%s/.config", homedir); mkdir (confdir, 0755); snprintf (dbconfdir, 1024, "%s/.config/deadbeef", homedir); @@ -572,6 +575,7 @@ main (int argc, char *argv[]) { conf_load (); pl_load (defpl); + session_load (sessfile); messagepump_init (); codec_init_locking (); streamer_init (); @@ -602,6 +606,8 @@ main (int argc, char *argv[]) { gtkpl_init (); mainwin = create_mainwin (); + session_restore_window_attrs ((uintptr_t)mainwin); + volume_set_db (session_get_volume ()); searchwin = create_searchwin (); gtk_window_set_transient_for (GTK_WINDOW (searchwin), GTK_WINDOW (mainwin)); extern void main_playlist_init (GtkWidget *widget); @@ -631,6 +637,7 @@ main (int argc, char *argv[]) { streamer_free (); codec_free_locking (); + session_save (sessfile); pl_save (defpl); pl_free (); return 0; diff --git a/session.c b/session.c new file mode 100644 index 00000000..ca42dfdf --- /dev/null +++ b/session.c @@ -0,0 +1,227 @@ +/* + 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 +#include +#include +#include "session.h" +#include "common.h" + +char session_dir[2048]; +float session_volume; +int session_win_attrs[5] = { 40, 40, 500, 300, 0 }; +static uint8_t sessfile_magic[] = { 0xdb, 0xef, 0x5e, 0x55 }; // dbefsess in hexspeak + +static int +write_i16_be (uint16_t val, FILE *fp) { + uint8_t b; + b = (uint8_t)(val&0xff); + if (fwrite (&b, 1, 1, fp) != 1) { + return 0; + } + b = (uint8_t)((val&0xff00)>>8); + if (fwrite (&b, 1, 1, fp) != 1) { + return 1; + } + return 2; +} + +static int +write_i32_be (uint32_t val, FILE *fp) { + uint8_t b; + b = (uint8_t)(val&0xff); + if (fwrite (&b, 1, 1, fp) != 1) { + return 0; + } + b = (uint8_t)((val&0xff00)>>8); + if (fwrite (&b, 1, 1, fp) != 1) { + return 1; + } + b = (uint8_t)((val&0xff0000)>>16); + if (fwrite (&b, 1, 1, fp) != 1) { + return 2; + } + b = (uint8_t)((val&0xff000000)>>24); + if (fwrite (&b, 1, 1, fp) != 1) { + return 3; + } + return 4; +} + +static int +read_i16_be (uint16_t *pval, FILE *fp) { + uint16_t val = 0; + uint8_t b; + if (fread (&b, 1, 1, fp) != 1) { + return 0; + } + val |= (uint16_t)b; + if (fread (&b, 1, 1, fp) != 1) { + return 1; + } + val |= (((uint16_t)b) << 8); + *pval = val; + return 2; +} + +static int +read_i32_be (uint32_t *pval, FILE *fp) { + uint32_t val = 0; + uint8_t b; + if (fread (&b, 1, 1, fp) != 1) { + return 0; + } + val |= (uint32_t)b; + if (fread (&b, 1, 1, fp) != 1) { + return 1; + } + val |= (((uint32_t)b) << 8); + if (fread (&b, 1, 1, fp) != 1) { + return 2; + } + val |= (((uint32_t)b) << 16); + if (fread (&b, 1, 1, fp) != 1) { + return 3; + } + val |= (((uint32_t)b) << 24); + *pval = val; + return 4; +} + +void +session_reset (void) { + session_volume = 0; + session_dir[0] = 0; + session_win_attrs[0] = 40; + session_win_attrs[1] = 40; + session_win_attrs[2] = 500; + session_win_attrs[3] = 300; + session_win_attrs[4] = 0; +} + +int +session_save (const char *fname) { + FILE *fp = fopen (fname, "w+b"); + if (!fp) { + fprintf (stderr, "failed to save session, file %s could not be opened\n"); + return -1; + } + // magic + if (fwrite (sessfile_magic, 1, 4, fp) != 4) { + goto session_save_fail; + } + uint8_t version = 1; + if (fwrite (&version, 1, 1, fp) != 1) { + goto session_save_fail; + } + uint16_t l = strlen (session_dir); + if (write_i16_be (l, fp) != 2) { + goto session_save_fail; + } + if (fwrite (session_dir, 1, l, fp) != l) { + goto session_save_fail; + } + if (write_i32_be (*((uint32_t*)&session_volume), fp) != 4) { + goto session_save_fail; + } + for (int k = 0; k < 5; k++) { + if (write_i32_be (session_win_attrs[k], fp) != 4) { + goto session_save_fail; + } + } + fclose (fp); + return 0; +session_save_fail: + fprintf (stderr, "failed to save session, seems to be a disk error\n"); + fclose (fp); + return -1; +} + +int +session_load (const char *fname) { + FILE *fp = fopen (fname, "r+b"); + if (!fp) { + return -1; + } + // magic + uint8_t magic[4]; + if (fread (magic, 1, 4, fp) != 4) { + goto session_load_fail; + } + if (memcmp (magic, sessfile_magic, 4)) { + goto session_load_fail; + } + uint8_t version; + if (fread (&version, 1, 1, fp) != 1) { + goto session_load_fail; + } + if (version != 1) { + goto session_load_fail; + } + uint16_t l; + if (read_i16_be (&l, fp) != 2) { + goto session_load_fail; + } + if (l >= 2048) { + goto session_load_fail; + } + if (fread (session_dir, 1, l, fp) != l) { + goto session_load_fail; + } + session_dir[l] = 0; + if (read_i32_be ((uint32_t*)&session_volume, fp) != 4) { + goto session_load_fail; + } + for (int k = 0; k < 5; k++) { + if (read_i32_be (&session_win_attrs[k], fp) != 4) { + goto session_load_fail; + } + } +// printf ("dir: %s\n", session_dir); +// printf ("volume: %f\n", session_volume); +// printf ("win: %d %d %d %d %d\n", session_win_attrs[0], session_win_attrs[1], session_win_attrs[2], session_win_attrs[3], session_win_attrs[4]); + fclose (fp); + return 0; +session_load_fail: + fprintf (stderr, "failed to load session, session file is corrupt\n"); + fclose (fp); + session_reset (); + return -1; +} + +void +session_set_directory (const char *path) { + strncpy (session_dir, path, 2048); +} + +void +session_set_volume (float vol) { + printf ("volume: %f\n", vol); + session_volume = vol; +} + +const char * +session_get_directory (void) { + return session_dir; +} + +float +session_get_volume (void) { + return session_volume; +} + diff --git a/session.h b/session.h new file mode 100644 index 00000000..847a6320 --- /dev/null +++ b/session.h @@ -0,0 +1,48 @@ +/* + 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. +*/ +#ifndef __SESSION_H +#define __SESSION_H + +#include + +int +session_save (const char *fname); + +int +session_load (const char *fname); + +void +session_capture_window_attrs (uintptr_t window); + +void +session_set_directory (const char *path); + +void +session_set_volume (float vol); + +void +session_restore_window_attrs (uintptr_t window); + +const char * +session_get_directory (void); + +float +session_get_volume (void); + +#endif // __SESSION_H diff --git a/volume.c b/volume.c index 85a9a125..889e967b 100644 --- a/volume.c +++ b/volume.c @@ -19,12 +19,14 @@ #include #include #include "volume.h" +#include "session.h" static float volume_db = 0; // in dB static float volume_amp = 1; // amplitude [0..1] void volume_set_db (float dB) { + session_set_volume (dB); volume_db = dB; volume_amp = dB > -60 ? db_to_amp (dB) : 0; } @@ -38,6 +40,7 @@ void volume_set_amp (float amp) { volume_amp = amp; volume_db = amp > 0 ? amp_to_db (amp) : -60.f; + session_set_volume (volume_db); } float -- cgit v1.2.3