summaryrefslogtreecommitdiff
path: root/gtk2_ardour/ardour_ui.cc
diff options
context:
space:
mode:
Diffstat (limited to 'gtk2_ardour/ardour_ui.cc')
-rw-r--r--gtk2_ardour/ardour_ui.cc272
1 files changed, 220 insertions, 52 deletions
diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc
index fdfdc9fdad..4f1c85f6b4 100644
--- a/gtk2_ardour/ardour_ui.cc
+++ b/gtk2_ardour/ardour_ui.cc
@@ -27,15 +27,18 @@
#include <cerrno>
#include <fstream>
+#ifndef PLATFORM_WINDOWS
+#include <sys/resource.h>
+#endif
+
#include <stdint.h>
#include <fcntl.h>
#include <signal.h>
#include <unistd.h>
#include <time.h>
-#include <sys/resource.h>
-#include <sys/types.h>
-#include <sys/sysctl.h>
+#include <glib.h>
+#include <glib/gstdio.h>
#include <gtkmm/messagedialog.h>
#include <gtkmm/accelmap.h>
@@ -48,6 +51,7 @@
#include "pbd/memento_command.h"
#include "pbd/openuri.h"
#include "pbd/file_utils.h"
+#include "pbd/localtime_r.h"
#include "gtkmm2ext/application.h"
#include "gtkmm2ext/bindings.h"
@@ -67,6 +71,7 @@
#include "ardour/filename_extensions.h"
#include "ardour/filesystem_paths.h"
#include "ardour/port.h"
+#include "ardour/plugin_manager.h"
#include "ardour/process_thread.h"
#include "ardour/profile.h"
#include "ardour/recent_sessions.h"
@@ -75,6 +80,11 @@
#include "ardour/session_state_utils.h"
#include "ardour/session_utils.h"
#include "ardour/slave.h"
+#include "ardour/system_exec.h"
+
+#ifdef WINDOWS_VST_SUPPORT
+#include <fst.h>
+#endif
#include "timecode/time.h"
@@ -215,6 +225,10 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
ui_config = new UIConfiguration();
+ ui_config->ParameterChanged.connect (sigc::mem_fun (*this, &ARDOUR_UI::parameter_changed));
+ boost::function<void (string)> pc (boost::bind (&ARDOUR_UI::parameter_changed, this, _1));
+ ui_config->map_parameters (pc);
+
editor = 0;
mixer = 0;
meterbridge = 0;
@@ -289,7 +303,13 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[], const char* localedir)
/* and ambiguous files */
- ARDOUR::FileSource::AmbiguousFileName.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::ambiguous_file, this, _1, _2, _3));
+ ARDOUR::FileSource::AmbiguousFileName.connect_same_thread (forever_connections, boost::bind (&ARDOUR_UI::ambiguous_file, this, _1, _2));
+
+ /* also plugin scan messages */
+ ARDOUR::PluginScanMessage.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::plugin_scan_dialog, this, _1, _2, _3), gui_context());
+ ARDOUR::PluginScanTimeout.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::plugin_scan_timeout, this, _1), gui_context());
+
+ ARDOUR::GUIIdle.connect (forever_connections, MISSING_INVALIDATOR, boost::bind(&ARDOUR_UI::gui_idle_handler, this), gui_context());
/* lets get this party started */
@@ -468,7 +488,7 @@ ARDOUR_UI::post_engine ()
_tooltips.enable();
- ActionManager::load_menus ();
+ ActionManager::load_menus (ARDOUR_COMMAND_LINE::menus_file);
if (setup_windows ()) {
throw failed_constructor ();
@@ -541,11 +561,6 @@ ARDOUR_UI::~ARDOUR_UI ()
ui_config->save_state();
}
- delete keyboard;
- delete editor;
- delete mixer;
- delete meterbridge;
-
stop_video_server();
}
@@ -752,7 +767,8 @@ ARDOUR_UI::starting ()
// wait for announce reply from nsm server
for ( i = 0; i < 5000; ++i) {
nsm->check ();
- usleep (i);
+
+ Glib::usleep (i);
if (nsm->is_active()) {
break;
}
@@ -764,7 +780,7 @@ ARDOUR_UI::starting ()
// wait for open command from nsm server
for ( i = 0; i < 5000; ++i) {
nsm->check ();
- usleep (1000);
+ Glib::usleep (1000);
if (nsm->client_id ()) {
break;
}
@@ -847,7 +863,7 @@ ARDOUR_UI::starting ()
void
ARDOUR_UI::check_memory_locking ()
{
-#ifdef __APPLE__
+#if defined(__APPLE__) || defined(PLATFORM_WINDOWS)
/* OS X doesn't support mlockall(2), and so testing for memory locking capability there is pointless */
return;
#else // !__APPLE__
@@ -986,8 +1002,6 @@ If you still wish to quit, please use the\n\n\
close_all_dialogs ();
- loading_message (string_compose (_("Please wait while %1 cleans up..."), PROGRAM_NAME));
-
if (_session) {
// _session->set_deletion_in_progress ();
_session->set_clean ();
@@ -998,6 +1012,9 @@ If you still wish to quit, please use the\n\n\
halt_connection.disconnect ();
AudioEngine::instance()->stop ();
+#ifdef WINDOWS_VST_SUPPORT
+ fst_stop_threading();
+#endif
quit ();
}
@@ -1639,10 +1656,10 @@ ARDOUR_UI::session_add_mixed_track (const ChanCount& input, const ChanCount& out
catch (...) {
MessageDialog msg (*editor,
- string_compose (_("There are insufficient JACK ports available\n\
+ string_compose (_("There are insufficient ports available\n\
to create a new track or bus.\n\
You should save %1, exit and\n\
-restart JACK with more ports."), PROGRAM_NAME));
+restart with more ports."), PROGRAM_NAME));
msg.run ();
}
}
@@ -1700,10 +1717,10 @@ ARDOUR_UI::session_add_audio_route (
catch (...) {
MessageDialog msg (*editor,
- string_compose (_("There are insufficient JACK ports available\n\
+ string_compose (_("There are insufficient ports available\n\
to create a new track or bus.\n\
You should save %1, exit and\n\
-restart JACK with more ports."), PROGRAM_NAME));
+restart with more ports."), PROGRAM_NAME));
pop_back_splash (msg);
msg.run ();
}
@@ -1865,12 +1882,25 @@ ARDOUR_UI::transport_roll ()
bool rolling = _session->transport_rolling();
if (_session->get_play_loop()) {
- /* XXX it is not possible to just leave seamless loop and keep
- playing at present (nov 4th 2009)
+
+ /* If loop playback is not a mode, then we should cancel
+ it when this action is requested. If it is a mode
+ we just leave it in place.
*/
- if (!Config->get_seamless_loop()) {
- _session->request_play_loop (false, true);
- }
+
+ if (!Config->get_loop_is_mode()) {
+ /* XXX it is not possible to just leave seamless loop and keep
+ playing at present (nov 4th 2009)
+ */
+ if (!Config->get_seamless_loop()) {
+ /* stop loop playback and stop rolling */
+ _session->request_play_loop (false, true);
+ } else if (rolling) {
+ /* stop loop playback but keep rolling */
+ _session->request_play_loop (false, false);
+ }
+ }
+
} else if (_session->get_play_range () && !Config->get_always_play_range()) {
/* stop playing a range if we currently are */
_session->request_play_range (0, true);
@@ -1927,7 +1957,7 @@ ARDOUR_UI::toggle_roll (bool with_abort, bool roll_out_of_bounded_mode)
/* disk buffers are normal, so we can keep playing */
affect_transport = false;
}
- _session->request_play_loop (false, true);
+ _session->request_play_loop (false, affect_transport);
} else if (_session->get_play_range ()) {
affect_transport = false;
_session->request_play_range (0, true);
@@ -1958,16 +1988,23 @@ ARDOUR_UI::toggle_session_auto_loop ()
if (_session->get_play_loop()) {
- if (_session->transport_rolling()) {
+ /* looping enabled, our job is to disable it */
+
+ _session->request_play_loop (false);
+
+ } else {
- _session->request_locate (looploc->start(), true);
- _session->request_play_loop (false);
+ /* looping not enabled, our job is to enable it.
+ loop-is-NOT-mode: this action always starts the transport rolling.
+ loop-IS-mode: this action simply sets the loop play mechanism, but
+ does not start transport.
+ */
+ if (Config->get_loop_is_mode()) {
+ _session->request_play_loop (true, false);
} else {
- _session->request_play_loop (false);
+ _session->request_play_loop (true, true);
}
- } else {
- _session->request_play_loop (true);
}
//show the loop markers
@@ -2095,7 +2132,11 @@ ARDOUR_UI::map_transport_state ()
auto_loop_button.set_active (true);
play_selection_button.set_active (false);
- roll_button.set_active (false);
+ if (Config->get_loop_is_mode()) {
+ roll_button.set_active (true);
+ } else {
+ roll_button.set_active (false);
+ }
} else {
@@ -2117,7 +2158,11 @@ ARDOUR_UI::map_transport_state ()
stop_button.set_active (true);
roll_button.set_active (false);
play_selection_button.set_active (false);
- auto_loop_button.set_active (false);
+ if (Config->get_loop_is_mode ()) {
+ auto_loop_button.set_active (_session->get_play_loop());
+ } else {
+ auto_loop_button.set_active (false);
+ }
update_disk_space ();
}
}
@@ -2906,7 +2951,15 @@ ARDOUR_UI::load_session (const std::string& path, const std::string& snap_name,
_session->set_clean ();
}
+#ifdef WINDOWS_VST_SUPPORT
+ fst_stop_threading();
+#endif
+
flush_pending ();
+
+#ifdef WINDOWS_VST_SUPPORT
+ fst_start_threading();
+#endif
retval = 0;
out:
@@ -3101,13 +3154,13 @@ require some unused files to continue to exist."));
space_adjusted = rep.space;
} else if (rep.space < 1000000) {
bprefix = _("kilo");
- space_adjusted = truncf((float)rep.space / 1000.0);
+ space_adjusted = floorf((float)rep.space / 1000.0);
} else if (rep.space < 1000000 * 1000) {
bprefix = _("mega");
- space_adjusted = truncf((float)rep.space / (1000.0 * 1000.0));
+ space_adjusted = floorf((float)rep.space / (1000.0 * 1000.0));
} else {
bprefix = _("giga");
- space_adjusted = truncf((float)rep.space / (1000.0 * 1000 * 1000.0));
+ space_adjusted = floorf((float)rep.space / (1000.0 * 1000 * 1000.0));
}
if (msg_delete) {
@@ -3331,12 +3384,6 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
setup_order_hint();
- PBD::ScopedConnection idle_connection;
-
- if (count > 8) {
- ARDOUR::GUIIdle.connect (idle_connection, MISSING_INVALIDATOR, boost::bind (&Gtkmm2ext::UI::flush_pending, this), gui_context());
- }
-
string template_path = add_route_dialog->track_template();
if (!template_path.empty()) {
@@ -3378,15 +3425,13 @@ ARDOUR_UI::add_route (Gtk::Window* float_window)
session_add_audio_bus (input_chan.n_audio(), output_chan.n_audio(), route_group, count, name_template);
break;
}
-
- /* idle connection will end at scope end */
}
void
ARDOUR_UI::stop_video_server (bool ask_confirm)
{
if (!video_server_process && ask_confirm) {
- warning << _("Video-Server was not launched by Ardour. The request to stop it is ignored.") << endmsg;
+ warning << string_compose (_("Video-Server was not launched by %1. The request to stop it is ignored."), PROGRAM_NAME) << endmsg;
}
if (video_server_process) {
if(ask_confirm) {
@@ -3452,16 +3497,24 @@ ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg)
std::string icsd_docroot = video_server_dialog->get_docroot();
if (icsd_docroot.empty()) {icsd_docroot = X_("/");}
- struct stat sb;
- if (!lstat (icsd_docroot.c_str(), &sb) == 0 || !S_ISDIR(sb.st_mode)) {
+ GStatBuf sb;
+ if (!g_lstat (icsd_docroot.c_str(), &sb) == 0 || !S_ISDIR(sb.st_mode)) {
warning << _("Specified docroot is not an existing directory.") << endmsg;
continue;
}
- if ( (!lstat (icsd_exec.c_str(), &sb) == 0)
+#ifndef PLATFORM_WINDOWS
+ if ( (!g_lstat (icsd_exec.c_str(), &sb) == 0)
|| (sb.st_mode & (S_IXUSR|S_IXGRP|S_IXOTH)) == 0 ) {
warning << _("Given Video Server is not an executable file.") << endmsg;
continue;
}
+#else
+ if ( (!g_lstat (icsd_exec.c_str(), &sb) == 0)
+ || (sb.st_mode & (S_IXUSR)) == 0 ) {
+ warning << _("Given Video Server is not an executable file.") << endmsg;
+ continue;
+ }
+#endif
char **argp;
argp=(char**) calloc(9,sizeof(char*));
@@ -3490,14 +3543,15 @@ ARDOUR_UI::start_video_server (Gtk::Window* float_window, bool popup_msg)
delete video_server_process;
}
- video_server_process = new SystemExec(icsd_exec, argp);
+ video_server_process = new ARDOUR::SystemExec(icsd_exec, argp);
if (video_server_process->start()) {
warning << _("Cannot launch the video-server") << endmsg;
continue;
}
int timeout = 120; // 6 sec
while (!ARDOUR_UI::instance()->video_timeline->check_server()) {
- usleep (50000);
+ Glib::usleep (50000);
+ gui_idle_handler();
if (--timeout <= 0 || !video_server_process->is_running()) break;
}
if (timeout <= 0) {
@@ -3763,6 +3817,116 @@ quickly enough to keep up with recording.\n"), PROGRAM_NAME));
}
}
+
+/* TODO: this is getting elaborate enough to warrant being split into a dedicated class */
+static MessageDialog *scan_dlg = NULL;
+static ProgressBar *scan_pbar = NULL;
+static HBox *scan_tbox = NULL;
+
+void
+ARDOUR_UI::cancel_plugin_scan ()
+{
+ PluginManager::instance().cancel_plugin_scan();
+}
+
+void
+ARDOUR_UI::cancel_plugin_timeout ()
+{
+ PluginManager::instance().cancel_plugin_timeout();
+ scan_tbox->hide();
+}
+
+void
+ARDOUR_UI::plugin_scan_timeout (int timeout)
+{
+ if (!scan_dlg || !scan_dlg->is_mapped() || !scan_pbar) {
+ return;
+ }
+ if (timeout > 0) {
+ scan_pbar->set_fraction ((float) timeout / (float) Config->get_vst_scan_timeout());
+ scan_tbox->show();
+ } else {
+ scan_tbox->hide();
+ }
+ gui_idle_handler();
+}
+
+void
+ARDOUR_UI::plugin_scan_dialog (std::string type, std::string plugin, bool can_cancel)
+{
+ if (type == X_("closeme") && !(scan_dlg && scan_dlg->is_mapped())) {
+ return;
+ }
+
+ const bool cancelled = PluginManager::instance().cancelled();
+ if (type != X_("closeme") && !Config->get_show_plugin_scan_window()) {
+ if (cancelled && scan_dlg->is_mapped()) {
+ scan_dlg->hide();
+ gui_idle_handler();
+ return;
+ }
+ if (cancelled || !can_cancel) {
+ return;
+ }
+ }
+
+ static Gtk::Button *cancel_button;
+ static Gtk::Button *timeout_button;
+ if (!scan_dlg) {
+ scan_dlg = new MessageDialog("", false, MESSAGE_INFO, BUTTONS_NONE); // TODO manage
+ VBox* vbox = scan_dlg->get_vbox();
+ vbox->set_size_request(400,-1);
+ scan_dlg->set_title (_("Scanning for plugins"));
+
+ cancel_button = manage(new Gtk::Button(_("Cancel plugin scan")));
+ cancel_button->set_name ("EditorGTKButton");
+ cancel_button->signal_clicked().connect ( mem_fun (*this, &ARDOUR_UI::cancel_plugin_scan) );
+ cancel_button->show();
+
+ scan_dlg->get_vbox()->pack_start ( *cancel_button, PACK_SHRINK);
+
+ scan_tbox = manage( new HBox() );
+
+ timeout_button = manage(new Gtk::Button(_("Stop Timeout")));
+ timeout_button->set_name ("EditorGTKButton");
+ timeout_button->signal_clicked().connect ( mem_fun (*this, &ARDOUR_UI::cancel_plugin_timeout) );
+ timeout_button->show();
+
+ scan_pbar = manage(new ProgressBar());
+ scan_pbar->set_orientation(Gtk::PROGRESS_RIGHT_TO_LEFT);
+ scan_pbar->set_text(_("Scan Timeout"));
+ scan_pbar->show();
+
+ scan_tbox->pack_start (*scan_pbar, PACK_EXPAND_WIDGET, 4);
+ scan_tbox->pack_start (*timeout_button, PACK_SHRINK, 4);
+
+ scan_dlg->get_vbox()->pack_start (*scan_tbox, PACK_SHRINK, 4);
+ }
+
+ if (type == X_("closeme")) {
+ scan_dlg->hide();
+ } else {
+ scan_dlg->set_message(type + ": " + Glib::path_get_basename(plugin));
+ scan_dlg->show();
+ }
+ if (!can_cancel || !cancelled) {
+ scan_tbox->hide();
+ }
+ cancel_button->set_sensitive(can_cancel && !cancelled);
+
+ gui_idle_handler();
+}
+
+void
+ARDOUR_UI::gui_idle_handler ()
+{
+ int timeout = 30;
+ /* due to idle calls, gtk_events_pending() may always return true */
+ while (gtk_events_pending() && --timeout) {
+ gtk_main_iteration ();
+ }
+}
+
void
ARDOUR_UI::disk_underrun_handler ()
{
@@ -4095,10 +4259,14 @@ ARDOUR_UI::setup_profile ()
Profile->set_small_screen ();
}
- if (getenv ("ARDOUR_SAE")) {
+ if (g_getenv ("ARDOUR_SAE")) {
Profile->set_sae ();
Profile->set_single_package ();
}
+
+ if (g_getenv ("TRX")) {
+ Profile->set_trx ();
+ }
}
int
@@ -4125,7 +4293,7 @@ ARDOUR_UI::missing_file (Session*s, std::string str, DataType type)
}
int
-ARDOUR_UI::ambiguous_file (std::string file, std::string /*path*/, std::vector<std::string> hits)
+ARDOUR_UI::ambiguous_file (std::string file, std::vector<std::string> hits)
{
AmbiguousFileDialog dialog (file, hits);