28 #include <glibmm/main.h> 40 if (m_killsignal == SIGKILL) {
41 Glib::signal_timeout().connect_once(
42 sigc::hide_return(sigc::bind(sigc::ptr_fun(::
kill), m_pid, SIGKILL)), 100);
43 return ::kill(m_pid, SIGTERM) != -1;
45 return ::kill(m_pid, m_killsignal) != -1;
50 for (list<GxChild*>::iterator i = children.begin(); i != children.end(); ++i) {
58 for (list<GxChild*>::iterator i = children.begin(); i != children.end(); ++i) {
66 Glib::RefPtr<Glib::MainContext> ctx = Glib::MainContext::get_default();
67 while (children.size() > 0) {
82 for (list<GxChild*>::iterator i = children.begin(); i != children.end(); ++i) {
83 if ((*i)->hasName(name)) {
90 #define EXIT_PGM_NOT_FOUND 127 94 pid_t pid = waitpid(-1, &status, WNOHANG);
95 if (pid == 0 || pid == -1) {
98 bool pgm_found =
true;
99 if (WIFEXITED(status)) {
103 }
else if (!WIFSIGNALED(status)) {
110 for (list<GxChild*>::iterator i = cl.begin(); i != cl.end(); ++i) {
111 if ((*i)->hasPid(pid)) {
134 sigfillset(&waitset);
135 sigprocmask(SIG_UNBLOCK, &waitset, NULL);
136 execvp(args[0], (
char**)args);
143 children.push_back(p);
149 const char **p =
new const char*[args.size()+1];
151 for (list<string>::iterator j = args.begin(); j != args.end(); ++j) {
155 assert(i == args.size());
157 GxChild *c = launch(name, p, killsignal);
171 JackCaptureGui::JackCaptureGui(
GxChild *p, GtkCheckMenuItem *i)
173 gtk_widget_ref(GTK_WIDGET(item));
174 p->
terminated.connect(sigc::mem_fun(*
this, &JackCaptureGui::terminated));
177 void JackCaptureGui::terminated(
bool pgm_found) {
178 gtk_check_menu_item_set_active(item,
false);
180 gx_print_info(
"Jack capture gui",
"jack_capture_gui2 terminated");
184 " ERORR [Jack Capture GUI]\n\n " 185 " jack_capture_gui2 is not installed! " 188 gtk_widget_unref(GTK_WIDGET(item));
192 void JackCaptureGui::start_stop(GtkCheckMenuItem *menuitem, gpointer) {
193 const char *app_name =
"jack_capture_gui2";
194 if (gtk_check_menu_item_get_active(menuitem)) {
195 if (childprocs.
find(app_name)) {
198 string sess = string(getenv(
"HOME")) +
"/guitarix_session";
199 const char *
const args[] = {
200 app_name,
"-o",
"yes",
"-f", sess.c_str(),
201 "-n",
"guitarix",
"-p",
"/.guitarix/ja_ca_ssetrc", 0 };
202 GxChild *jack_cap_gui = childprocs.
launch(app_name, args, SIGTERM);
204 new JackCaptureGui(jack_cap_gui, menuitem);
208 "ERROR [Jack capture gui]\n\n " 209 "jack_capture_gui2 could not be launched!" 212 string(
"jack_capture_gui2 could not be launched (fork failed)!"));
213 gtk_check_menu_item_set_active(menuitem, FALSE);
216 childprocs.
kill(app_name);
222 JackCapture::JackCapture(
GxChild *p, GtkToggleButton *b)
224 gtk_widget_ref(GTK_WIDGET(button));
225 p->
terminated.connect(sigc::mem_fun(*
this, &JackCapture::terminated));
228 void JackCapture::terminated(
bool pgm_found) {
229 gtk_toggle_button_set_active(button,
false);
234 " WARNING [jack_capture]\n " 235 " You need jack_capture >= 0.9.30 by Kjetil S. Matheussen \n " 236 " Please look here\n " 237 " http://old.notam02.no/arkiv/src/?M=D\n");
239 gtk_widget_unref(GTK_WIDGET(button));
244 string JackCapture::make_fname(
string buf,
size_t j,
size_t i,
int n) {
246 str << buf.substr(0, j+1) << n << buf.substr(i);
250 list<string> JackCapture::capture_command(
int& seq) {
252 string gfilename = gx_system::sysvar.gx_user_dir + gx_system::sysvar.jcapsetup_file;
253 ifstream f(gfilename.c_str());
267 " ERROR [Record]\n\n " 268 " Please run jack capture settings first [alt+j]" 274 l.push_back(
"--hide-buffer-usage");
275 size_t i = buf.find_last_of(
".");
276 if (i == string::npos) {
277 gx_print_error(
"Record",
"could not parse cmd file (internal error)");
281 size_t j = buf.find_last_not_of(
"0123456789", i-1);
284 for (n = 1; n < 1000; ++n) {
285 fname = make_fname(buf, j, i, n);
286 if (access(fname.c_str(), F_OK) != 0) {
291 gx_print_error(
"Record",
"more than 999 capture files in directory?!");
300 void JackCapture::stop() {
301 childprocs.
kill(
"jack_capture");
304 void JackCapture::start_stop(GtkWidget *widget, gpointer data) {
305 static int last_seqno;
307 GtkToggleButton*
const cap_button =
reinterpret_cast<GtkToggleButton*
>(widget);
308 const char *app_name =
"jack_capture";
309 if (gtk_toggle_button_get_active(cap_button) == FALSE) {
313 if (jack_capture->
kill()) {
316 boost::format(
" Terminated jack_capture, session file #%1%")
320 "Record",
" Sorry, could not stop (Ctrl-C) jack_capture");
326 if (gx_gui::GxMainInterface::get_instance().jack.client == NULL) {
327 gtk_toggle_button_set_active(cap_button, FALSE);
329 " WARNING [Record]\n\n " 330 " Reconnect to Jack server first (Shift+C)" 336 list<string> capturas = capture_command(last_seqno);
337 if (capturas.empty()) {
338 gtk_toggle_button_set_active(cap_button, FALSE);
341 GxChild *jack_capture = childprocs.
launch(app_name, capturas, SIGINT);
343 gtk_toggle_button_set_active(cap_button, FALSE);
345 " WARNING [jack_capture] Sorry, could not start jack_capture");
348 new JackCapture(jack_capture, cap_button);
351 boost::format(
"Started jack_capture, session file #%1%") % last_seqno);
357 Meterbridge::Meterbridge(
GxChild *p, Glib::RefPtr<Gtk::ToggleAction>& a)
359 p->
terminated.connect(sigc::mem_fun(*
this, &Meterbridge::terminated));
362 void Meterbridge::terminated(
bool pgm_found) {
363 action->set_active(
false);
369 " WARNING [meterbridge]\n\n " 370 " meterbridge is not installed! " 377 childprocs.
kill(
"meterbridge");
384 " WARNING [Meterbridge]\n\n " 385 " Reconnect to Jack server first (Shift+C)" 390 const char *app_name =
"meterbridge";
391 if (action->get_active()) {
392 if (childprocs.
find(app_name)) {
396 const char *
const args[] = {
397 app_name,
"-n", s.c_str(),
"-t",
"sco",
"-c",
"3",
404 GxChild *meterbridge = childprocs.
launch(app_name, args, SIGKILL);
410 "WARNING [meterbridge]\n\n " 411 "meterbridge could not be launched!" 414 string(
"meterbridge could not be launched (fork failed)!"));
415 action->set_active(
false);
418 childprocs.
kill(app_name);
void gx_print_info(const char *, const std::string &)
void gx_print_error(const char *, const std::string &)
void gx_sigchld_handler()
#define EXIT_PGM_NOT_FOUND
GxChild * launch(string name, const char *const args[], int killsignal)
void gx_print_warning(const char *, const std::string &)
sigc::signal< void, bool > terminated
const string & get_instancename()
static void start_stop(Glib::RefPtr< Gtk::ToggleAction > &action, gx_jack::GxJack &jack)
int gx_message_popup(const char *)
string client_insert_name
GxChild * find(string name)