GtkWidget *playlists_menu;
GtkWidget *menu_editplaylists_widget;
static GtkWidget *menu_minimode_widget;
+static GtkWidget *apis_menu;
/** @brief Main menu widgets */
GtkItemFactory *mainmenufactory;
users_set_sensitive(FALSE);
}
+/** @brief Called to select the network playback API */
+static void rtp_menu_activate(GtkMenuItem *menuitem,
+ gpointer user_data) {
+ if(GTK_CHECK_MENU_ITEM(menuitem)->active)
+ change_rtp_api(user_data);
+}
+
/** @brief Create the menu bar widget */
GtkWidget *menubar(GtkWidget *window) {
GtkWidget *m;
(char *)"<Branch>", /* item_type */
0 /* extra_data */
},
+ {
+ (char *)"/Control/Network Playback API", /* path */
+ 0, /* accelerator */
+ 0, /* callback */
+ 0, /* callback_action */
+ (char *)"<Branch>", /* item_type */
+ 0 /* extra_data */
+ },
{
(char *)"/Help", /* path */
"<GdisorderMain>/Control/Activate playlist");
playlists_menu = gtk_item_factory_get_widget(mainmenufactory,
"<GdisorderMain>/Control/Activate playlist");
+ apis_menu = gtk_item_factory_get_widget(mainmenufactory,
+ "<GdisorderMain>/Control/Network Playback API");
menu_editplaylists_widget = gtk_item_factory_get_widget(mainmenufactory,
"<GdisorderMain>/Edit/Edit playlists");
menu_minimode_widget = gtk_item_factory_get_widget(mainmenufactory,
assert(menu_playlists_widget != 0);
assert(playlists_menu != 0);
assert(menu_editplaylists_widget != 0);
+ assert(apis_menu != 0);
GtkWidget *edit_widget = gtk_item_factory_get_widget(mainmenufactory,
"<GdisorderMain>/Edit");
if(menu_minimode_widget)
g_signal_connect(G_OBJECT(menu_minimode_widget), "toggled",
G_CALLBACK(toggled_minimode), NULL);
+
+ /* Populate the APIs menu */
+ GSList *playback_menu_group = NULL;
+ load_rtp_config();
+ assert(rtp_api != NULL);
+ for(int n = 0; uaudio_apis[n]; ++n) {
+ if(uaudio_apis[n]->flags & UAUDIO_API_CLIENT) {
+ GtkWidget *mw = gtk_radio_menu_item_new_with_label(playback_menu_group,
+ uaudio_apis[n]->name);
+ playback_menu_group = gtk_radio_menu_item_get_group(GTK_RADIO_MENU_ITEM(mw));
+ gtk_menu_shell_append(GTK_MENU_SHELL(apis_menu), mw);
+ /* Tick the currently selected API... */
+ if(!strcmp(uaudio_apis[n]->name, rtp_api))
+ gtk_check_menu_item_set_active(GTK_CHECK_MENU_ITEM(mw), TRUE);
+ /* ...and only then connect the signal */
+ g_signal_connect(mw, "toggled", G_CALLBACK(rtp_menu_activate),
+ (char *)uaudio_apis[n]->name);
+ }
+ }
+
return m;
}
disorder_fatal(errno, "close");
/* execute the player */
execlp("disorder-playrtp",
- "disorder-playrtp", "--socket", rtp_socket, (char *)0);
+ "disorder-playrtp",
+ "--socket", rtp_socket,
+ "--api", rtp_api,
+ (char *)0);
disorder_fatal(errno, "disorder-playrtp");
} else {
/* child */
fclose(fp);
}
+static char *rtp_config_file(void) {
+ static char *rtp_config;
+ const char *home = getenv("HOME");
+ if(!rtp_config)
+ byte_xasprintf(&rtp_config, "%s/.disorder/api", home);
+ return rtp_config;
+}
+
+const char *rtp_api;
+
+void load_rtp_config(void) {
+ char *rtp_config = rtp_config_file();
+ FILE *fp;
+ if((fp = fopen(rtp_config, "r"))) {
+ char *line;
+ if(inputline(rtp_config, fp, &line, '\n') == 0) {
+ for(int n = 0; uaudio_apis[n]; ++n)
+ if(!strcmp(uaudio_apis[n]->name, line))
+ rtp_api = line;
+ }
+ fclose(fp);
+ }
+ if(!rtp_api)
+ rtp_api = uaudio_default(uaudio_apis, UAUDIO_API_CLIENT)->name;
+}
+
+void save_rtp_config(void) {
+ if(rtp_api) {
+ char *rtp_config = rtp_config_file();
+ char *tmp;
+ byte_xasprintf(&tmp, "%s.tmp", rtp_config);
+ FILE *fp;
+ if(!(fp = fopen(tmp, "w"))){
+ fpopup_msg(GTK_MESSAGE_ERROR, "error opening %s: %s",
+ tmp, strerror(errno));
+ return;
+ }
+ if(fprintf(fp, "%s\n", rtp_api) < 0) {
+ fpopup_msg(GTK_MESSAGE_ERROR, "error writing to %s: %s",
+ tmp, strerror(errno));
+ fclose(fp);
+ return;
+ }
+ if(fclose(fp) < 0) {
+ fpopup_msg(GTK_MESSAGE_ERROR, "error closing %s: %s",
+ tmp, strerror(errno));
+ return;
+ }
+ if(rename(tmp, rtp_config) < 0) {
+ fpopup_msg(GTK_MESSAGE_ERROR, "error renaming %s: %s",
+ tmp, strerror(errno));
+ }
+ }
+}
+
+void change_rtp_api(const char *api) {
+ if(rtp_api && !strcmp(api, rtp_api))
+ return; /* no change */
+ int running = rtp_running();
+ if(running)
+ stop_rtp();
+ rtp_api = api;
+ save_rtp_config();
+ // TODO this is racy and does not work; the player doesn't shut down quickly
+ // enough.
+ if(running)
+ start_rtp();
+}
+
/*
Local Variables:
c-basic-offset:2