diff --git a/session-manager/src/NSM_Proxy_UI.fl b/session-manager/src/NSM_Proxy_UI.fl index 4e6aa0e..ffa1be3 100644 --- a/session-manager/src/NSM_Proxy_UI.fl +++ b/session-manager/src/NSM_Proxy_UI.fl @@ -7,31 +7,31 @@ class NSM_Proxy_UI {open Function {make_window()} {open } { Fl_Window {} { - label {NSM Proxy} open - xywh {1011 106 490 665} type Double color 47 labelcolor 55 visible xclass NSM-Proxy + label {NSM Proxy} open selected + xywh {644 190 635 665} type Double color 47 labelcolor 55 xclass {NSM-Proxy} visible } { Fl_Box {} { label {Command-line options are incompatible with robust session management for a variety of reasons, so the NSM server does not support them directly. This proxy exists to allow programs which require command-line options to be included in an NSM session. Be warned that referring to files outside of the session directory will impair your ability to reliably archive and transport sessions. Patching the program to use NSM natively will result in a better experience. The program will be started with its current directory being a uniquely named directory under the current session directory. It is recommended that you only refer to files in the current directory. -} selected - xywh {15 11 460 233} box BORDER_BOX color 41 labelfont 8 labelcolor 55 align 128 +} + xywh {15 11 610 139} box BORDER_BOX color 41 labelfont 8 labelsize 12 labelcolor 55 align 128 } Fl_File_Input executable_input { label {Executable: } - xywh {115 262 350 33} + xywh {115 162 495 31} } Fl_Input arguments_input { label {Arguments:} - xywh {115 414 350 28} + xywh {110 310 350 28} } Fl_Input label_input { label {Label:} - xywh {115 452 350 28} + xywh {110 340 350 28} } Fl_Return_Button start_button { label Start - xywh {380 625 88 25} + xywh {535 630 88 25} } Fl_Button kill_button { label Kill @@ -39,7 +39,7 @@ The program will be started with its current directory being a uniquely named di } Fl_Choice save_signal_choice { label {Save Signal:} open - xywh {110 625 170 25} down_box BORDER_BOX + xywh {110 468 170 25} down_box BORDER_BOX } { MenuItem {} { label None @@ -59,12 +59,41 @@ The program will be started with its current directory being a uniquely named di } } Fl_Box {} { - label {The environment variables $NSM_CLIENT_ID and $NSM_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively.} - xywh {15 312 460 87} box BORDER_BOX color 41 labelfont 8 labelcolor 55 align 128 + label {The environment variables $NSM_CLIENT_ID and $NSM_SESSION_NAME will contain the unique client ID (suitable for use as e.g. a JACK client name) and the display name for the session, respectively. The variable $CONFIG_FILE will contain the name of the config file selected above.} + xywh {15 235 610 69} box BORDER_BOX color 41 labelfont 8 labelsize 12 labelcolor 55 align 128 } Fl_Box {} { label {Some (very few) programs may respond to a specific Unix signal by somehow saving their state. If 'Save Signal' is set to something other than 'None', then NSM Proxy will deliver the specified signal to the proxied process upon an NSM 'Save' event. Most programs will treat these signals just like SIGTERM and die. You have been warned.} - xywh {15 497 460 114} box BORDER_BOX color 41 labelfont 8 labelcolor 55 align 128 + xywh {15 378 610 79} box BORDER_BOX color 41 labelfont 8 labelsize 12 labelcolor 55 align 128 + } + Fl_Choice stop_signal_choice { + label {Stop Signal:} open + xywh {108 592 170 25} down_box BORDER_BOX + } { + MenuItem {} { + label SIGTERM + xywh {10 10 40 24} + } + MenuItem {} { + label SIGINT + xywh {40 40 40 24} + } + MenuItem {} { + label SIGHUP + xywh {50 50 40 24} + } + } + Fl_Box {} { + label {Most programs will shutdown gracefully when sent a SIGTERM or SIGINT signal. It's impossible to know which signal a specific program will respond to. A unhandled signal will simply kill the process, and may cause problems with the audio subsystem (e.g. JACK). Check the program's documentation or source code to determine which signal to use to stop it gracefully.} + xywh {15 502 610 79} box BORDER_BOX color 41 labelfont 8 labelsize 12 labelcolor 55 align 128 + } + Fl_File_Input config_file_input { + label {Config File:} + xywh {114 195 406 31} + } + Fl_Button config_file_browse_button { + label Browse + xywh {530 195 85 25} } } } diff --git a/session-manager/src/nsm-proxy-gui.C b/session-manager/src/nsm-proxy-gui.C index e2a89dc..2196cfc 100644 --- a/session-manager/src/nsm-proxy-gui.C +++ b/session-manager/src/nsm-proxy-gui.C @@ -25,6 +25,7 @@ #define APP_NAME "NSM Proxy" #define APP_TITLE "NSM Proxy" +#include #include "NSM_Proxy_UI.H" #include #include @@ -50,6 +51,8 @@ osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_me ui->arguments_input->value( &argv[0]->s ); else if (!strcmp( path, "/nsm/proxy/executable" )) ui->executable_input->value( &argv[0]->s ); + else if (!strcmp( path, "/nsm/proxy/config_file" )) + ui->config_file_input->value( &argv[0]->s ); else if (!strcmp( path, "/nsm/proxy/save_signal" )) { if ( argv[0]->i == SIGUSR1 ) @@ -61,6 +64,15 @@ osc_update ( const char *path, const char *types, lo_arg **argv, int argc, lo_me else ui->save_signal_choice->value( 0 ); } + else if (!strcmp( path, "/nsm/proxy/stop_signal" )) + { + if ( argv[0]->i == SIGTERM ) + ui->stop_signal_choice->value( 0 ); + else if ( argv[0]->i == SIGINT ) + ui->stop_signal_choice->value( 1 ); + else if ( argv[0]->i == SIGHUP ) + ui->stop_signal_choice->value( 2 ); + } Fl::unlock(); @@ -85,8 +97,10 @@ init_osc ( const char *osc_port ) lo_server_thread_add_method( loth, "/nsm/proxy/executable", "s", osc_update, NULL ); lo_server_thread_add_method( loth, "/nsm/proxy/arguments", "s", osc_update, NULL ); + lo_server_thread_add_method( loth, "/nsm/proxy/config_file", "s", osc_update, NULL ); lo_server_thread_add_method( loth, "/nsm/proxy/label", "s", osc_update, NULL ); lo_server_thread_add_method( loth, "/nsm/proxy/save_signal", "i", osc_update, NULL ); + lo_server_thread_add_method( loth, "/nsm/proxy/stop_signal", "i", osc_update, NULL ); lo_server_thread_start( loth ); } @@ -104,9 +118,10 @@ handle_kill ( Fl_Widget *o, void *v ) void handle_start ( Fl_Widget *o, void *v ) { - lo_send_from( nsmp_addr, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/start", "ss", + lo_send_from( nsmp_addr, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/start", "sss", ui->executable_input->value(), - ui->arguments_input->value() ); + ui->arguments_input->value(), + ui->config_file_input->value() ); } void @@ -122,6 +137,20 @@ handle_executable ( Fl_Widget *o, void *v ) ui->label_input->value( ui->executable_input->value() ); } + +void +handle_config_file ( Fl_Widget *o, void *v ) +{ +} + +void +handle_config_file_browse ( Fl_Widget *o, void *v ) +{ + const char * file = fl_file_chooser( "Pick file", "*", NULL, 1 ); + + ui->config_file_input->value( file ); +} + void handle_save_signal ( Fl_Widget *o, void *v ) { @@ -140,14 +169,35 @@ handle_save_signal ( Fl_Widget *o, void *v ) sig ); } +void +handle_stop_signal ( Fl_Widget *o, void *v ) +{ + int sig = SIGTERM; + + const char* picked = ui->stop_signal_choice->mvalue()->label(); + + if ( !strcmp( picked, "SIGTERM" ) ) + sig = SIGTERM; + else if ( !strcmp( picked, "SIGINT" ) ) + sig = SIGINT; + else if ( !strcmp( picked, "SIGHUP" ) ) + sig = SIGHUP; + + lo_send_from( nsmp_addr, losrv, LO_TT_IMMEDIATE,"/nsm/proxy/stop_signal", "i", + sig ); +} + void connect_ui ( void ) { ui->executable_input->callback( handle_executable, NULL ); + ui->config_file_input->callback( handle_config_file, NULL ); ui->kill_button->callback( handle_kill, NULL ); ui->start_button->callback( handle_start, NULL ); ui->save_signal_choice->callback( handle_save_signal, NULL ); + ui->stop_signal_choice->callback( handle_stop_signal, NULL ); ui->label_input->callback( handle_label, NULL ); + ui->config_file_browse_button->callback( handle_config_file_browse, NULL ); } diff --git a/session-manager/src/nsm-proxy.C b/session-manager/src/nsm-proxy.C index 4cadd83..8b0a98f 100644 --- a/session-manager/src/nsm-proxy.C +++ b/session-manager/src/nsm-proxy.C @@ -56,16 +56,19 @@ class NSM_Proxy { char *_label; char *_executable; + char *_config_file; char *_arguments; int _save_signal; + int _stop_signal; int _pid; public: NSM_Proxy ( ) { - _label = _executable = _arguments = 0; + _label = _executable = _arguments = _config_file = 0; _save_signal = 0; + _stop_signal = SIGTERM; _pid = 0; } @@ -76,15 +79,17 @@ public: void kill ( void ) { if ( _pid ) - ::kill( _pid, SIGTERM ); + ::kill( _pid, _stop_signal ); } - bool start ( const char *executable, const char *arguments ) + bool start ( const char *executable, const char *arguments, const char *config_file ) { if ( _executable ) free( _executable ); if ( _arguments ) free( _arguments ); + if ( _config_file ) + free( _config_file ); _executable = strdup( executable ); @@ -93,6 +98,11 @@ public: else _arguments = NULL; + if ( config_file ) + _config_file = strdup( config_file ); + else + _config_file = NULL; + return start(); } @@ -128,6 +138,8 @@ public: setenv( "NSM_CLIENT_ID", nsm_client_id, 1 ); setenv( "NSM_SESSION_NAME", nsm_display_name, 1 ); + if ( _config_file ) + setenv( "CONFIG_FILE", _config_file, 1 ); unsetenv( "NSM_URL" ); if ( -1 == execvp( "/bin/sh", args ) ) @@ -147,6 +159,11 @@ public: { _save_signal = s; } + + void stop_signal ( int s ) + { + _stop_signal = s; + } void label ( const char *s ) { @@ -187,7 +204,12 @@ public: if ( _arguments && strlen(_arguments) ) fprintf( fp, "arguments\n\t%s\n", _arguments ); + if ( _config_file && strlen(_config_file) ) + fprintf( fp, "config file\n\t%s\n", _config_file ); + fprintf( fp, "save signal\n\t%i\n", _save_signal ); + + fprintf( fp, "stop signal\n\t%i\n", _stop_signal ); if ( _label && strlen(_label) ) fprintf( fp, "label\n\t%s\n", _label ); @@ -221,11 +243,18 @@ public: _executable = value; else if (!strcmp( name, "arguments" ) ) _arguments = value; + else if (!strcmp( name, "config file" ) ) + _config_file = value; else if ( !strcmp( name, "save signal" ) ) { _save_signal = atoi( value ); free( value ); } + else if ( !strcmp( name, "stop signal" ) ) + { + _stop_signal = atoi( value ); + free( value ); + } else if ( !strcmp( name, "label" ) ) { label( value ); @@ -254,6 +283,8 @@ public: lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/label", "s", _label ? _label : "" ); lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/executable", "s", _executable ? _executable : "" ); lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/arguments", "s", _arguments ? _arguments : "" ); + lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/config_file", "s", _config_file ? _config_file : "" ); + lo_send_from( to, losrv, LO_TT_IMMEDIATE, "/nsm/proxy/stop_signal", "i", _stop_signal ); } }; @@ -493,12 +524,20 @@ osc_save_signal ( const char *path, const char *types, lo_arg **argv, int argc, return 0; } +int +osc_stop_signal ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) +{ + nsm_proxy->stop_signal( argv[0]->i ); + + return 0; +} + int osc_start ( const char *path, const char *types, lo_arg **argv, int argc, lo_message msg, void *user_data ) { snapshot( project_file ); - if ( nsm_proxy->start( &argv[0]->s, &argv[1]->s ) ) + if ( nsm_proxy->start( &argv[0]->s, &argv[1]->s, &argv[2]->s ) ) { hide_gui(); } @@ -567,8 +606,9 @@ init_osc ( const char *osc_port ) /* GUI */ lo_server_add_method( losrv, "/nsm/proxy/label", "s", osc_label, NULL ); lo_server_add_method( losrv, "/nsm/proxy/save_signal", "i", osc_save_signal, NULL ); + lo_server_add_method( losrv, "/nsm/proxy/stop_signal", "i", osc_stop_signal, NULL ); lo_server_add_method( losrv, "/nsm/proxy/kill", "", osc_kill, NULL ); - lo_server_add_method( losrv, "/nsm/proxy/start", "ss", osc_start, NULL ); + lo_server_add_method( losrv, "/nsm/proxy/start", "sss", osc_start, NULL ); lo_server_add_method( losrv, "/nsm/proxy/update", "", osc_update, NULL ); }