X-Git-Url: https://git.distorted.org.uk/~mdw/disorder/blobdiff_plain/c2f519409c8d38f59e169abfc39bc97586222f85..6e19032aa4c34a5c6c900e558d8bfa88f8382bc0:/disobedience/disobedience.c diff --git a/disobedience/disobedience.c b/disobedience/disobedience.c index 8ca36e5..b988aa8 100644 --- a/disobedience/disobedience.c +++ b/disobedience/disobedience.c @@ -20,11 +20,11 @@ */ #include "disobedience.h" +#include "regexp.h" #include "version.h" #include #include -#include #include /* Apologies for the numerous de-consting casts, but GLib et al do not seem to @@ -71,9 +71,6 @@ int volume_l; /** @brief Right channel volume */ int volume_r; -/** @brief Audio backend */ -const struct uaudio *backend; - double goesupto = 10; /* volume upper bound */ /** @brief True if a NOP is in flight */ @@ -175,27 +172,38 @@ static GtkWidget *notebook(void) { /* Tracking of window sizes */ static int toplevel_width = 640, toplevel_height = 480; static int mini_width = 480, mini_height = 140; +static struct timeval last_mode_switch; static void main_minimode(const char attribute((unused)) *event, void attribute((unused)) *evendata, void attribute((unused)) *callbackdata) { if(full_mode) { + gtk_window_resize(GTK_WINDOW(toplevel), toplevel_width, toplevel_height); gtk_widget_show(tabs); gtk_widget_hide(playing_mini); /* Show the queue (bit confusing otherwise!) */ gtk_notebook_set_current_page(GTK_NOTEBOOK(tabs), 0); - gtk_window_resize(GTK_WINDOW(toplevel), toplevel_width, toplevel_height); } else { + gtk_window_resize(GTK_WINDOW(toplevel), mini_width, mini_height); gtk_widget_hide(tabs); gtk_widget_show(playing_mini); - gtk_window_resize(GTK_WINDOW(toplevel), mini_width, mini_height); } + xgettimeofday(&last_mode_switch, NULL); } /* Called when the window size is allocate */ static void toplevel_size_allocate(GtkWidget attribute((unused)) *w, GtkAllocation *a, gpointer attribute((unused)) user_data) { + struct timeval now; + xgettimeofday(&now, NULL); + if(tvdouble(tvsub(now, last_mode_switch)) < 0.5) { + /* Suppress size-allocate signals that are within half a second of a mode + * switch: they are quite likely to be the result of re-arranging widgets + * within the old size, not the application of the new size. Yes, this is + * a disgusting hack! */ + return; /* OMG too soon! */ + } if(full_mode) { toplevel_width = a->width; toplevel_height = a->height; @@ -205,9 +213,52 @@ static void toplevel_size_allocate(GtkWidget attribute((unused)) *w, } } +/* Periodically check the toplevel's size + * (the hack in toplevel_size_allocate() means we could in principle + * miss a user-initiated resize) + */ +static void check_toplevel_size(const char attribute((unused)) *event, + void attribute((unused)) *evendata, + void attribute((unused)) *callbackdata) { + GtkAllocation a; + gtk_window_get_size(GTK_WINDOW(toplevel), &a.width, &a.height); + toplevel_size_allocate(NULL, &a, NULL); +} + +static void hack_window_title(const char attribute((unused)) *event, + void attribute((unused)) *eventdata, + void attribute((unused)) *callbackdata) { + char *p; + const char *note; + static const char *last_note = 0; + + if(!(last_state & DISORDER_CONNECTED)) + note = "(disconnected)"; + else if(last_state & DISORDER_TRACK_PAUSED) + note = "(paused)"; + else if(playing_track) { + byte_asprintf(&p, "'%s' by %s, from '%s'", + namepart(playing_track->track, "display", "title"), + namepart(playing_track->track, "display", "artist"), + namepart(playing_track->track, "display", "album")); + note = p; + } else if(!(last_state & DISORDER_PLAYING_ENABLED)) + note = "(playing disabled)"; + else if(!(last_state & DISORDER_RANDOM_ENABLED)) + note = "(random play disabled)"; + else + note = "(nothing to play for unknown reason)"; + + if(last_note && !strcmp(note, last_note)) + return; + last_note = xstrdup(note); + byte_asprintf(&p, "Disobedience: %s", note); + gtk_window_set_title(GTK_WINDOW(toplevel), p); +} + /** @brief Create and populate the main window */ static void make_toplevel_window(void) { - GtkWidget *const vbox = gtk_vbox_new(FALSE, 1); + GtkWidget *const vbox = gtk_vbox_new(FALSE/*homogeneous*/, 1/*spacing*/); GtkWidget *const rb = report_box(); D(("top_window")); @@ -222,7 +273,7 @@ static void make_toplevel_window(void) { g_signal_connect(G_OBJECT(toplevel), "size-allocate", G_CALLBACK(toplevel_size_allocate), NULL); /* lay out the window */ - gtk_window_set_title(GTK_WINDOW(toplevel), "Disobedience"); + hack_window_title(0, 0, 0); gtk_container_add(GTK_CONTAINER(toplevel), vbox); /* lay out the vbox */ gtk_box_pack_start(GTK_BOX(vbox), @@ -251,6 +302,14 @@ static void make_toplevel_window(void) { 0); gtk_widget_set_style(toplevel, tool_style); event_register("mini-mode-changed", main_minimode, 0); + event_register("periodic-fast", check_toplevel_size, 0); + event_register("playing-track-changed", hack_window_title, 0); + event_register("enabled-changed", hack_window_title, 0); + event_register("random-changed", hack_window_title, 0); + event_register("pause-changed", hack_window_title, 0); + event_register("playing-changed", hack_window_title, 0); + event_register("connected-changed", hack_window_title, 0); + event_register("lookups-completed", hack_window_title, 0); } static void userinfo_rights_completed(void attribute((unused)) *v, @@ -317,10 +376,9 @@ static gboolean periodic_fast(gpointer attribute((unused)) data) { } last = now; #endif - if(rtp_supported && backend && backend->get_volume) { + if(rtp_supported) { int nl, nr; - backend->get_volume(&nl, &nr); - if(nl != volume_l || nr != volume_r) { + if (!rtp_getvol(&nl, &nr) && (nl != volume_l || nr != volume_r)) { volume_l = nl; volume_r = nr; event_raise("volume-changed", 0); @@ -414,7 +472,7 @@ static const struct option options[] = { }; /* display usage message and terminate */ -static void help(void) { +static void attribute((noreturn)) help(void) { xprintf("Disobedience - GUI client for DisOrder\n" "\n" "Usage:\n" @@ -485,8 +543,7 @@ int main(int argc, char **argv) { mem_init(); /* garbage-collect PCRE's memory */ - pcre_malloc = xmalloc; - pcre_free = xfree; + regexp_setup(); if(!setlocale(LC_CTYPE, "")) disorder_fatal(errno, "error calling setlocale"); gtkok = gtk_init_check(&argc, &argv); while((n = getopt_long(argc, argv, "hVc:dtHC", options, 0)) >= 0) { @@ -513,12 +570,6 @@ int main(int argc, char **argv) { D(("create main loop")); mainloop = g_main_loop_new(0, 0); if(config_read(0, NULL)) disorder_fatal(0, "cannot read configuration"); - /* we'll need mixer support */ - backend = uaudio_apis[0]; - if(backend->configure) - backend->configure(); - if(backend->open_mixer) - backend->open_mixer(); /* create the clients */ if(!(client = gtkclient()) || !(logclient = gtkclient())) @@ -545,6 +596,7 @@ int main(int argc, char **argv) { event_register("log-connected", check_rtp_address, 0); suppress_actions = 0; playlists_init(); + globals_init(); /* If no password is set yet pop up a login box */ if(!config->password) login_box();