notify user when JACK crashes or stops unexpectedly
This commit is contained in:
parent
128590f5bf
commit
1e9d406f23
|
@ -103,12 +103,17 @@ studio_publish(void)
|
|||
return true;
|
||||
}
|
||||
|
||||
void emit_studio_started()
|
||||
void emit_studio_started(void)
|
||||
{
|
||||
dbus_signal_emit(g_dbus_connection, STUDIO_OBJECT_PATH, IFACE_STUDIO, "StudioStarted", "");
|
||||
}
|
||||
|
||||
void emit_studio_stopped()
|
||||
void emit_studio_crashed(void)
|
||||
{
|
||||
dbus_signal_emit(g_dbus_connection, STUDIO_OBJECT_PATH, IFACE_STUDIO, "StudioCrashed", "");
|
||||
}
|
||||
|
||||
void emit_studio_stopped(void)
|
||||
{
|
||||
dbus_signal_emit(g_dbus_connection, STUDIO_OBJECT_PATH, IFACE_STUDIO, "StudioStopped", "");
|
||||
}
|
||||
|
@ -147,10 +152,8 @@ void on_event_jack_started(void)
|
|||
emit_studio_started();
|
||||
}
|
||||
|
||||
void on_event_jack_stopped(void)
|
||||
static void on_jack_stopped_internal(void)
|
||||
{
|
||||
emit_studio_stopped();
|
||||
|
||||
if (g_studio.automatic)
|
||||
{
|
||||
log_info("Unloading automatic studio.");
|
||||
|
@ -171,8 +174,17 @@ void on_event_jack_stopped(void)
|
|||
}
|
||||
}
|
||||
|
||||
void on_event_jack_stopped(void)
|
||||
{
|
||||
emit_studio_stopped();
|
||||
on_jack_stopped_internal();
|
||||
}
|
||||
|
||||
void handle_unexpected_jack_server_stop(void)
|
||||
{
|
||||
emit_studio_crashed();
|
||||
on_jack_stopped_internal();
|
||||
|
||||
/* TODO: if user wants, restart jack server and reconnect all jack apps to it */
|
||||
}
|
||||
|
||||
|
@ -215,7 +227,6 @@ void studio_run(void)
|
|||
* the change will be consumed by the run method of the studio stop command */
|
||||
log_error("JACK stopped unexpectedly.");
|
||||
log_error("Save your work, then unload and reload the studio.");
|
||||
on_event_jack_stopped();
|
||||
handle_unexpected_jack_server_stop();
|
||||
}
|
||||
}
|
||||
|
@ -234,7 +245,6 @@ void studio_run(void)
|
|||
ladish_graph_clear(g_studio.studio_graph, false);
|
||||
ladish_graph_clear(g_studio.jack_graph, true);
|
||||
|
||||
on_event_jack_stopped();
|
||||
handle_unexpected_jack_server_stop();
|
||||
}
|
||||
}
|
||||
|
@ -680,6 +690,9 @@ SIGNAL_ARGS_END
|
|||
SIGNAL_ARGS_BEGIN(StudioStarted, "Studio started")
|
||||
SIGNAL_ARGS_END
|
||||
|
||||
SIGNAL_ARGS_BEGIN(StudioCrashed, "Studio crashed")
|
||||
SIGNAL_ARGS_END
|
||||
|
||||
SIGNAL_ARGS_BEGIN(StudioStopped, "Studio stopped")
|
||||
SIGNAL_ARGS_END
|
||||
|
||||
|
@ -694,6 +707,7 @@ SIGNAL_ARGS_END
|
|||
SIGNALS_BEGIN
|
||||
SIGNAL_DESCRIBE(StudioRenamed)
|
||||
SIGNAL_DESCRIBE(StudioStarted)
|
||||
SIGNAL_DESCRIBE(StudioCrashed)
|
||||
SIGNAL_DESCRIBE(StudioStopped)
|
||||
SIGNAL_DESCRIBE(RoomAppeared)
|
||||
SIGNAL_DESCRIBE(RoomDisappeared)
|
||||
|
|
187
gui/main.c
187
gui/main.c
|
@ -75,8 +75,20 @@ graph_view_handle g_studio_view = NULL;
|
|||
|
||||
static guint g_jack_poll_source_tag;
|
||||
static double g_jack_max_dsp_load = 0.0;
|
||||
static bool g_studio_started = false;
|
||||
static bool g_studio_loaded = false;
|
||||
|
||||
#define STUDIO_STATE_NA 0
|
||||
#define STUDIO_STATE_UNLOADED 1
|
||||
#define STUDIO_STATE_STOPPED 2
|
||||
#define STUDIO_STATE_STARTED 3
|
||||
#define STUDIO_STATE_CRASHED 4
|
||||
|
||||
static unsigned int g_studio_state = STUDIO_STATE_UNLOADED;
|
||||
|
||||
#define JACK_STATE_NA 0
|
||||
#define JACK_STATE_STOPPED 1
|
||||
#define JACK_STATE_STARTED 2
|
||||
|
||||
static unsigned int g_jack_state = JACK_STATE_NA;
|
||||
|
||||
struct studio_list
|
||||
{
|
||||
|
@ -483,68 +495,118 @@ static gboolean poll_jack(gpointer data)
|
|||
return TRUE;
|
||||
}
|
||||
|
||||
void studio_state_changed(void)
|
||||
bool studio_state_changed(char ** name_ptr_ptr)
|
||||
{
|
||||
gtk_widget_set_sensitive(g_menu_item_start_studio, g_studio_loaded);
|
||||
gtk_widget_set_sensitive(g_menu_item_stop_studio, g_studio_loaded);
|
||||
gtk_widget_set_sensitive(g_menu_item_save_studio, g_studio_loaded && g_studio_started);
|
||||
gtk_widget_set_sensitive(g_menu_item_unload_studio, g_studio_loaded);
|
||||
gtk_widget_set_sensitive(g_menu_item_rename_studio, g_studio_loaded);
|
||||
gtk_widget_set_sensitive(g_menu_item_start_app, g_studio_loaded);
|
||||
const char * status;
|
||||
const char * name;
|
||||
char * buffer;
|
||||
|
||||
gtk_widget_set_sensitive(g_menu_item_start_studio, g_studio_state == STUDIO_STATE_STOPPED);
|
||||
gtk_widget_set_sensitive(g_menu_item_stop_studio, g_studio_state == STUDIO_STATE_STARTED);
|
||||
gtk_widget_set_sensitive(g_menu_item_save_studio, g_studio_state == STUDIO_STATE_STARTED);
|
||||
gtk_widget_set_sensitive(g_menu_item_unload_studio, g_studio_state != STUDIO_STATE_UNLOADED);
|
||||
gtk_widget_set_sensitive(g_menu_item_rename_studio, g_studio_state == STUDIO_STATE_STOPPED || g_studio_state == STUDIO_STATE_STARTED);
|
||||
gtk_widget_set_sensitive(g_menu_item_start_app, g_studio_state == STUDIO_STATE_STOPPED || g_studio_state == STUDIO_STATE_STARTED);
|
||||
//gtk_widget_set_sensitive(g_menu_item_create_room, g_studio_loaded);
|
||||
//gtk_widget_set_sensitive(g_menu_item_destroy_room, g_studio_loaded);
|
||||
//gtk_widget_set_sensitive(g_menu_item_load_project, g_studio_loaded);
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(g_studio_status_label), name);
|
||||
|
||||
switch (g_jack_state)
|
||||
{
|
||||
case JACK_STATE_NA:
|
||||
status = "JACK is sick";
|
||||
break;
|
||||
case JACK_STATE_STOPPED:
|
||||
status = "Stopped";
|
||||
break;
|
||||
case JACK_STATE_STARTED:
|
||||
status = "xruns";
|
||||
break;
|
||||
default:
|
||||
status = "???";
|
||||
}
|
||||
|
||||
buffer = NULL;
|
||||
|
||||
switch (g_studio_state)
|
||||
{
|
||||
case STUDIO_STATE_NA:
|
||||
name = "ladishd is sick";
|
||||
break;
|
||||
case STUDIO_STATE_UNLOADED:
|
||||
name = "No studio loaded";
|
||||
break;
|
||||
case STUDIO_STATE_CRASHED:
|
||||
status = "Crashed";
|
||||
/* fall through */
|
||||
case STUDIO_STATE_STOPPED:
|
||||
case STUDIO_STATE_STARTED:
|
||||
if (!studio_proxy_get_name(&buffer))
|
||||
{
|
||||
log_error("failed to get studio name");
|
||||
}
|
||||
else
|
||||
{
|
||||
name = buffer;
|
||||
break;
|
||||
}
|
||||
default:
|
||||
name = "???";
|
||||
}
|
||||
|
||||
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(g_xrun_progress_bar), status);
|
||||
gtk_label_set_text(GTK_LABEL(g_studio_status_label), name);
|
||||
|
||||
if (buffer == NULL)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
if (name_ptr_ptr != NULL)
|
||||
{
|
||||
*name_ptr_ptr = buffer;
|
||||
}
|
||||
else
|
||||
{
|
||||
free(buffer);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void control_proxy_on_studio_appeared(void)
|
||||
{
|
||||
char * name;
|
||||
char * name;
|
||||
|
||||
g_studio_loaded = true;
|
||||
|
||||
if (!studio_proxy_get_name(&name))
|
||||
g_studio_state = STUDIO_STATE_STOPPED;
|
||||
if (studio_state_changed(&name))
|
||||
{
|
||||
log_error("failed to get studio name");
|
||||
goto exit;
|
||||
if (g_studio_view != NULL)
|
||||
{
|
||||
log_error("studio appear signal received but studio already exists");
|
||||
}
|
||||
else if (!create_view(name, SERVICE_NAME, STUDIO_OBJECT_PATH, true, true, false, &g_studio_view))
|
||||
{
|
||||
log_error("create_view() failed for studio");
|
||||
}
|
||||
|
||||
free(name);
|
||||
}
|
||||
|
||||
if (g_studio_view != NULL)
|
||||
{
|
||||
log_error("studio appear signal received but studio already exists");
|
||||
goto free_name;
|
||||
}
|
||||
|
||||
if (!create_view(name, SERVICE_NAME, STUDIO_OBJECT_PATH, true, true, false, &g_studio_view))
|
||||
{
|
||||
log_error("create_view() failed for studio");
|
||||
goto free_name;
|
||||
}
|
||||
|
||||
studio_state_changed();
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(g_studio_status_label), name);
|
||||
|
||||
free_name:
|
||||
free(name);
|
||||
|
||||
exit:
|
||||
return;
|
||||
}
|
||||
|
||||
void control_proxy_on_studio_disappeared(void)
|
||||
{
|
||||
g_studio_state = STUDIO_STATE_UNLOADED;
|
||||
studio_state_changed(NULL);
|
||||
|
||||
if (g_studio_view == NULL)
|
||||
{
|
||||
log_error("studio disappear signal received but studio does not exists");
|
||||
return;
|
||||
}
|
||||
|
||||
g_studio_loaded = false;
|
||||
|
||||
studio_state_changed();
|
||||
|
||||
gtk_label_set_text(GTK_LABEL(g_studio_status_label), "No studio loaded");
|
||||
|
||||
if (g_studio_view != NULL)
|
||||
{
|
||||
destroy_view(g_studio_view);
|
||||
|
@ -557,16 +619,35 @@ static void on_studio_renamed(const char * new_studio_name)
|
|||
if (g_studio_view != NULL)
|
||||
{
|
||||
set_view_name(g_studio_view, new_studio_name);
|
||||
gtk_label_set_text(GTK_LABEL(g_studio_status_label), new_studio_name);
|
||||
}
|
||||
}
|
||||
|
||||
void on_studio_started(void)
|
||||
{
|
||||
g_studio_state = STUDIO_STATE_STARTED;
|
||||
studio_state_changed(NULL);
|
||||
}
|
||||
|
||||
void on_studio_stopped(void)
|
||||
{
|
||||
g_studio_state = STUDIO_STATE_STOPPED;
|
||||
studio_state_changed(NULL);
|
||||
}
|
||||
|
||||
void on_studio_crashed(void)
|
||||
{
|
||||
g_studio_state = STUDIO_STATE_CRASHED;
|
||||
studio_state_changed(NULL);
|
||||
error_message_box("JACK crashed or stopped unexpectedly. Save your work, then unload and reload the studio.");
|
||||
}
|
||||
|
||||
void jack_started(void)
|
||||
{
|
||||
log_info("JACK started");
|
||||
|
||||
g_studio_started = true;
|
||||
|
||||
studio_state_changed();
|
||||
g_jack_state = JACK_STATE_STARTED;
|
||||
studio_state_changed(NULL);
|
||||
|
||||
gtk_widget_set_sensitive(g_buffer_size_combo, true);
|
||||
gtk_widget_set_sensitive(g_clear_load_button, true);
|
||||
|
@ -578,23 +659,24 @@ void jack_stopped(void)
|
|||
{
|
||||
log_info("JACK stopped");
|
||||
|
||||
g_studio_started = false;
|
||||
|
||||
g_source_remove(g_jack_poll_source_tag);
|
||||
|
||||
studio_state_changed();
|
||||
g_jack_state = JACK_STATE_STOPPED;
|
||||
studio_state_changed(NULL);
|
||||
|
||||
gtk_widget_set_sensitive(g_buffer_size_combo, false);
|
||||
buffer_size_clear();
|
||||
gtk_widget_set_sensitive(g_clear_load_button, false);
|
||||
gtk_progress_bar_set_fraction(GTK_PROGRESS_BAR(g_xrun_progress_bar), 0.0);
|
||||
gtk_progress_bar_set_text(GTK_PROGRESS_BAR(g_xrun_progress_bar), "Stopped");
|
||||
}
|
||||
|
||||
void jack_appeared(void)
|
||||
{
|
||||
log_info("JACK appeared");
|
||||
|
||||
g_jack_state = JACK_STATE_STOPPED;
|
||||
studio_state_changed(NULL);
|
||||
|
||||
#if defined(SHOW_RAW_JACK)
|
||||
if (!create_view("Raw JACK", JACKDBUS_SERVICE_NAME, JACKDBUS_OBJECT_PATH, false, false, true, &g_jack_view))
|
||||
{
|
||||
|
@ -610,6 +692,9 @@ void jack_disappeared(void)
|
|||
|
||||
jack_stopped();
|
||||
|
||||
g_jack_state = JACK_STATE_NA;
|
||||
studio_state_changed(NULL);
|
||||
|
||||
#if defined(SHOW_RAW_JACK)
|
||||
if (g_jack_view != NULL)
|
||||
{
|
||||
|
@ -765,6 +850,8 @@ int main(int argc, char** argv)
|
|||
return 1;
|
||||
}
|
||||
|
||||
studio_proxy_set_startstop_callbacks(on_studio_started, on_studio_stopped, on_studio_crashed);
|
||||
|
||||
studio_proxy_set_renamed_callback(on_studio_renamed);
|
||||
|
||||
set_buffer_size_combo_width();
|
||||
|
|
|
@ -30,6 +30,7 @@
|
|||
static void (* g_renamed_callback)(const char * new_studio_name) = NULL;
|
||||
static void (* g_started_callback)(void) = NULL;
|
||||
static void (* g_stopped_callback)(void) = NULL;
|
||||
static void (* g_crashed_callback)(void) = NULL;
|
||||
|
||||
static void on_studio_renamed(void * context, DBusMessage * message_ptr)
|
||||
{
|
||||
|
@ -71,6 +72,16 @@ static void on_studio_stopped(void * context, DBusMessage * message_ptr)
|
|||
}
|
||||
}
|
||||
|
||||
static void on_studio_crashed(void * context, DBusMessage * message_ptr)
|
||||
{
|
||||
log_info("StudioCrashed");
|
||||
|
||||
if (g_crashed_callback != NULL)
|
||||
{
|
||||
g_crashed_callback();
|
||||
}
|
||||
}
|
||||
|
||||
static void on_room_appeared(void * context, DBusMessage * message_ptr)
|
||||
{
|
||||
log_info("RoomAppeared");
|
||||
|
@ -88,6 +99,7 @@ static struct dbus_signal_hook g_signal_hooks[] =
|
|||
{"StudioRenamed", on_studio_renamed},
|
||||
{"StudioStarted", on_studio_started},
|
||||
{"StudioStopped", on_studio_stopped},
|
||||
{"StudioCrashed", on_studio_crashed},
|
||||
{"RoomAppeared", on_room_appeared},
|
||||
{"RoomDisappeared", on_room_disappeared},
|
||||
{NULL, NULL}
|
||||
|
@ -153,10 +165,11 @@ void studio_proxy_set_renamed_callback(void (* callback)(const char * new_studio
|
|||
g_renamed_callback = callback;
|
||||
}
|
||||
|
||||
void studio_proxy_set_startstop_callbacks(void (* started_callback)(void), void (* stopped_callback)(void))
|
||||
void studio_proxy_set_startstop_callbacks(void (* started_callback)(void), void (* stopped_callback)(void), void (* crashed_callback)(void))
|
||||
{
|
||||
g_started_callback = started_callback;
|
||||
g_stopped_callback = stopped_callback;
|
||||
g_crashed_callback = crashed_callback;
|
||||
}
|
||||
|
||||
bool studio_proxy_start(void)
|
||||
|
|
|
@ -38,7 +38,7 @@ bool studio_proxy_save(void);
|
|||
bool studio_proxy_unload(void);
|
||||
void studio_proxy_set_renamed_callback(void (* callback)(const char * new_studio_name));
|
||||
|
||||
void studio_proxy_set_startstop_callbacks(void (* started_callback)(void), void (* stopped_callback)(void));
|
||||
void studio_proxy_set_startstop_callbacks(void (* started_callback)(void), void (* stopped_callback)(void), void (* crashed_callback)(void));
|
||||
bool studio_proxy_start(void);
|
||||
bool studio_proxy_stop(void);
|
||||
|
||||
|
|
Loading…
Reference in New Issue