From df1da084eddfb2f9b2016595649b435be43c15d3 Mon Sep 17 00:00:00 2001 From: Paul Davis Date: Fri, 18 Jan 2008 19:58:34 +0000 Subject: [PATCH] permit OSX native package without JACK; prevent excessive track name lengths from messing up JACK port names; splash screen tweaks for OS X; new region gain control operations ; work on AU plugin GUIs (totally incomplete); don't needlessly create prompters in a barcontroller (create on demand) git-svn-id: svn://localhost/ardour2/branches/2.0-ongoing@2938 d708f5d6-7413-0410-9779-e7cbd77b26cf --- gtk2_ardour/ardbg | 1 + gtk2_ardour/ardour.menus | 3 + gtk2_ardour/ardour_ui.cc | 59 +++------ gtk2_ardour/ardour_ui.h | 4 +- gtk2_ardour/ardour_ui_dependents.cc | 13 ++ gtk2_ardour/au_pluginui.h | 5 + gtk2_ardour/au_pluginui.mm | 78 ++++++++++-- gtk2_ardour/editor.h | 1 + gtk2_ardour/editor_actions.cc | 6 + gtk2_ardour/editor_mixer.cc | 2 +- gtk2_ardour/editor_ops.cc | 60 ++++++++++ gtk2_ardour/plugin_ui.cc | 52 +++++++- gtk2_ardour/plugin_ui.h | 8 +- gtk2_ardour/splash.cc | 44 ++++++- gtk2_ardour/splash.h | 10 +- gtk2_ardour/utils.cc | 2 +- libs/ardour/ardour/io.h | 5 +- libs/ardour/audio_unit.cc | 2 +- libs/ardour/audioengine.cc | 3 +- libs/ardour/io.cc | 146 ++++++++++++----------- libs/ardour/rb_effect.cc | 22 ++-- libs/gtkmm2ext/binding_proxy.cc | 22 +++- libs/gtkmm2ext/gtk_ui.cc | 3 +- libs/gtkmm2ext/gtkmm2ext/binding_proxy.h | 4 +- tools/osx_packaging/osx_build | 6 + 25 files changed, 405 insertions(+), 156 deletions(-) diff --git a/gtk2_ardour/ardbg b/gtk2_ardour/ardbg index 063b2b1b6d..cdb640d63e 100755 --- a/gtk2_ardour/ardbg +++ b/gtk2_ardour/ardbg @@ -2,4 +2,5 @@ dir=`dirname "$0"` . $dir/ardev_common.sh LD_LIBRARY_PATH=/usr/local/lib:$LD_LIBRARY_PATH +export ARDOUR_INSIDE_GDB=1 exec gdb $EXECUTABLE "$@" diff --git a/gtk2_ardour/ardour.menus b/gtk2_ardour/ardour.menus index a42919f006..73768f3cf4 100644 --- a/gtk2_ardour/ardour.menus +++ b/gtk2_ardour/ardour.menus @@ -132,6 +132,9 @@ + + + diff --git a/gtk2_ardour/ardour_ui.cc b/gtk2_ardour/ardour_ui.cc index 88ce2fc24d..a66df27df1 100644 --- a/gtk2_ardour/ardour_ui.cc +++ b/gtk2_ardour/ardour_ui.cc @@ -201,7 +201,6 @@ ARDOUR_UI::ARDOUR_UI (int *argcp, char **argvp[]) have_disk_speed_dialog_displayed = false; _will_create_new_session_automatically = false; session_loaded = false; - loading_dialog = 0; last_speed_displayed = -1.0f; keybindings_path = ARDOUR::find_config_file ("ardour.bindings"); @@ -268,12 +267,7 @@ ARDOUR_UI::create_engine () return 0; } -#ifdef __APPLE__ - // OS X where everything is sllloooowwww - loading_dialog->set_message (_("Starting audio engine")); - loading_dialog->show_all (); - flush_pending (); -#endif + loading_message (_("Starting audio engine")); try { engine = new ARDOUR::AudioEngine (ARDOUR_COMMAND_LINE::jack_client_name); @@ -613,13 +607,6 @@ Please consider the possibilities, and perhaps (re)start JACK.")); win.run (); } -static bool -_hide_splash (gpointer arg) -{ - ((ARDOUR_UI*)arg)->hide_splash(); - return false; -} - void ARDOUR_UI::startup () { @@ -627,10 +614,6 @@ ARDOUR_UI::startup () new_session_dialog = new NewSessionDialog(); - // in 4 seconds, hide the splash screen - - Glib::signal_timeout().connect (bind (sigc::ptr_fun (_hide_splash), this), 4000); - bool backend_audio_is_running = EngineControl::engine_running(); XMLNode* audio_setup = Config->extra_xml ("AudioSetup"); @@ -2069,8 +2052,6 @@ ARDOUR_UI::load_cmdline_session (const Glib::ustring& session_name, const Glib:: /* lets just try to load it */ if (create_engine ()) { - hide_splash (); - loading_dialog->hide (); backend_audio_error (false, new_session_dialog); return -1; } @@ -2174,6 +2155,21 @@ ARDOUR_UI::build_session_from_nsd (const Glib::ustring& session_path, const Glib return 0; } +void +ARDOUR_UI::end_loading_messages () +{ + // hide_splash (); +} + +void +ARDOUR_UI::loading_message (const std::string& msg) +{ +#ifdef __APPLE__ + show_splash (); + splash->message (msg); + flush_pending (); +#endif +} bool ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be_new) @@ -2183,14 +2179,6 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be Glib::ustring session_path; Glib::ustring template_name; - if (!loading_dialog) { - loading_dialog = new MessageDialog (*new_session_dialog, - "", - false, - Gtk::MESSAGE_INFO, - Gtk::BUTTONS_NONE); - } - int response = Gtk::RESPONSE_NONE; if (!ARDOUR_COMMAND_LINE::session_name.empty()) { @@ -2231,8 +2219,8 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be do { new_session_dialog->set_have_engine (backend_audio_is_running); new_session_dialog->present (); + end_loading_messages (); response = new_session_dialog->run (); - loading_dialog->hide (); _session_is_new = false; @@ -2264,7 +2252,6 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be if (create_engine ()) { backend_audio_error (!backend_audio_is_running, new_session_dialog); - loading_dialog->hide (); flush_pending (); new_session_dialog->set_existing_session (false); @@ -2274,7 +2261,6 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be goto try_again; } - loading_dialog->hide (); backend_audio_is_running = true; if (response == Gtk::RESPONSE_OK) { @@ -2358,7 +2344,6 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be try_again: if (response == Gtk::RESPONSE_NONE) { - loading_dialog->hide (); new_session_dialog->set_existing_session (false); new_session_dialog->reset (); } @@ -2368,7 +2353,6 @@ ARDOUR_UI::get_session_parameters (bool backend_audio_is_running, bool should_be done: show(); - loading_dialog->hide (); new_session_dialog->hide(); new_session_dialog->reset(); goto_editor_window (); @@ -2418,14 +2402,7 @@ ARDOUR_UI::load_session (const Glib::ustring& path, const Glib::ustring& snap_na goto out; } -#ifdef __APPLE__ - // OS X where everything is sllloooowwww - if (loading_dialog) { - loading_dialog->set_markup (_("Please wait while Ardour loads your session")); - flush_pending (); - } -#endif - + loading_message (_("Please wait while Ardour loads your session")); disable_screen_updates (); try { diff --git a/gtk2_ardour/ardour_ui.h b/gtk2_ardour/ardour_ui.h index 58832a2b10..8417c6c4fd 100644 --- a/gtk2_ardour/ardour_ui.h +++ b/gtk2_ardour/ardour_ui.h @@ -755,7 +755,9 @@ class ARDOUR_UI : public Gtkmm2ext::UI Glib::RefPtr ptag, Glib::RefPtr mtag, const char *msg); Gtk::Label status_bar_label; Gtk::ToggleButton error_log_button; - Gtk::MessageDialog* loading_dialog; + + void loading_message (const std::string& msg); + void end_loading_messages (); void platform_specific (); void platform_setup (); diff --git a/gtk2_ardour/ardour_ui_dependents.cc b/gtk2_ardour/ardour_ui_dependents.cc index ee76f5ae11..387aa88ac2 100644 --- a/gtk2_ardour/ardour_ui_dependents.cc +++ b/gtk2_ardour/ardour_ui_dependents.cc @@ -31,6 +31,7 @@ #include "public_editor.h" #include "mixer_ui.h" #include "keyboard.h" +#include "splash.h" #include "route_params_ui.h" #include "i18n.h" @@ -106,9 +107,21 @@ ARDOUR_UI::connect_dependents_to_session (ARDOUR::Session *s) s->restore_history (""); } +static bool +_hide_splash (gpointer arg) +{ + ((ARDOUR_UI*)arg)->hide_splash(); + return false; +} + void ARDOUR_UI::goto_editor_window () { + if (splash && splash->is_visible()) { + // in 2 seconds, hide the splash screen + Glib::signal_timeout().connect (bind (sigc::ptr_fun (_hide_splash), this), 2000); + } + editor->show_window (); editor->present(); flush_pending (); diff --git a/gtk2_ardour/au_pluginui.h b/gtk2_ardour/au_pluginui.h index ab816f9630..46e4cde12f 100644 --- a/gtk2_ardour/au_pluginui.h +++ b/gtk2_ardour/au_pluginui.h @@ -36,6 +36,10 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox void on_realize (); void on_show (); + void on_hide (); + bool on_map_event (GdkEventAny*); + bool on_focus_in_event (GdkEventFocus*); + bool on_focus_out_event (GdkEventFocus*); OSStatus carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event); @@ -59,6 +63,7 @@ class AUPluginUI : public PlugUIBase, public Gtk::VBox EventHandlerRef carbon_event_handler; bool carbon_parented; bool cocoa_parented; + bool _activating_from_app; void test_view_support (bool&, bool&); bool test_cocoa_view_support (); diff --git a/gtk2_ardour/au_pluginui.mm b/gtk2_ardour/au_pluginui.mm index 51f73199f7..d2bdecfe60 100644 --- a/gtk2_ardour/au_pluginui.mm +++ b/gtk2_ardour/au_pluginui.mm @@ -35,10 +35,12 @@ AUPluginUI::AUPluginUI (boost::shared_ptr insert) bool has_carbon; bool has_cocoa; + _activating_from_app = false; carbon_parented = false; cocoa_parented = false; cocoa_parent = 0; cocoa_window = 0; + au_view = 0; test_view_support (has_carbon, has_cocoa); @@ -250,7 +252,7 @@ AUPluginUI::create_carbon_view (bool generic) kWindowNoShadowAttribute| kWindowNoTitleBarAttribute); - if ((err = CreateNewWindow(kDocumentWindowClass, attr, &r, &carbon_window)) != noErr) { + if ((err = CreateNewWindow(kFloatingWindowClass, attr, &r, &carbon_window)) != noErr) { error << string_compose (_("AUPluginUI: cannot create carbon window (err: %1)"), err) << endmsg; return -1; } @@ -314,7 +316,10 @@ AUPluginUI::activate () if (carbon_parented) { [cocoa_parent makeKeyAndOrderFront:nil]; + cerr << "APP activated, activate carbon window\n"; + _activating_from_app = true; ActivateWindow (carbon_window, TRUE); + _activating_from_app = false; } } @@ -338,17 +343,26 @@ AUPluginUI::carbon_event (EventHandlerCallRef nextHandlerRef, EventRef event) ClickActivationResult howToHandleClick; NSWindow* win = get_nswindow (); + cerr << "window " << win << " carbon event type " << eventKind << endl; + switch (eventKind) { case kEventWindowHandleActivate: + cerr << "carbon window activated\n"; + if (_activating_from_app) { + cerr << "app activation, ignore window activation\n"; + return noErr; + } [win makeMainWindow]; return eventNotHandledErr; break; case kEventWindowHandleDeactivate: + cerr << "carbon window deactivated\n"; return eventNotHandledErr; break; case kEventWindowGetClickActivation: + cerr << "carbon window CLICK activated\n"; howToHandleClick = kActivateAndHandleClick; SetEventParameter(event, kEventParamClickActivation, typeClickActivationResult, sizeof(ClickActivationResult), &howToHandleClick); @@ -470,13 +484,27 @@ AUPluginUI::parent_cocoa_window () newContentSize.width += (newFrame.size.width - currentFrame.size.width); newContentSize.height += (newFrame.size.height - currentFrame.size.height); +#ifdef PACK_COCOA_INTO_GTK_WINDOW + NSView* view = [win contentView]; + + [win setContentSize:newContentSize]; + [view addSubview:scroll_view]; +#else [cocoa_window setContentSize:newContentSize]; [cocoa_window setContentView:scroll_view]; +#endif } else { +#ifdef PACK_COCOA_INTO_GTK_WINDOW + NSView* view = [win contentView]; + + [win setContentSize:au_view_frame.size]; + [view addSubview:au_view]; +#else [cocoa_window setContentSize:au_view_frame.size]; [cocoa_window setContentView:au_view]; +#endif } @@ -497,16 +525,16 @@ AUPluginUI::parent_cocoa_window () [cocoa_window setFrame:view_frame display:NO]; /* make top level window big enough to hold cocoa window and titlebar */ - + content_frame.size.width = view_frame.size.width; content_frame.size.height = view_frame.size.height + titlebar_height; [win setFrame:content_frame display:NO]; /* now make cocoa window a child of this top level */ - + [win addChildWindow:cocoa_window ordered:NSWindowAbove]; - // [win setLevel:NSFloatingWindowLevel]; + [win setLevel:NSFloatingWindowLevel]; [win setHidesOnDeactivate:YES]; cocoa_parented = true; @@ -519,7 +547,7 @@ AUPluginUI::on_realize () { VBox::on_realize (); - if (cocoa_window) { + if (au_view) { if (parent_cocoa_window ()) { } @@ -532,6 +560,27 @@ AUPluginUI::on_realize () } } +void +AUPluginUI::on_hide () +{ + // VBox::on_hide (); + cerr << "AU plugin window hidden\n"; +} + +bool +AUPluginUI::on_map_event (GdkEventAny* ev) +{ + cerr << "AU plugin map event\n"; + + if (au_view) { + show_all (); + } else if (carbon_window) { + [cocoa_parent setIsVisible:YES]; + ShowWindow (carbon_window); + } + return false; +} + void AUPluginUI::on_show () { @@ -539,10 +588,11 @@ AUPluginUI::on_show () VBox::on_show (); - if (cocoa_window) { - [cocoa_window setIsVisible:YES]; + if (au_view) { + show_all (); } else if (carbon_window) { [cocoa_parent setIsVisible:YES]; + ShowWindow (carbon_window); } } @@ -565,3 +615,17 @@ create_au_gui (boost::shared_ptr plugin_insert, VBox** box) (*box) = aup; return aup; } + +bool +AUPluginUI::on_focus_in_event (GdkEventFocus* ev) +{ + cerr << "au plugin focus in\n"; + return false; +} + +bool +AUPluginUI::on_focus_out_event (GdkEventFocus* ev) +{ + cerr << "au plugin focus out\n"; + return false; +} diff --git a/gtk2_ardour/editor.h b/gtk2_ardour/editor.h index 4deaf7161f..ac67f9015f 100644 --- a/gtk2_ardour/editor.h +++ b/gtk2_ardour/editor.h @@ -980,6 +980,7 @@ class Editor : public PublicEditor void reverse_region (); void normalize_region (); void denormalize_region (); + void adjust_region_scale_amplitude (bool up); void audition_region_from_region_list (); void hide_region_from_region_list (); diff --git a/gtk2_ardour/editor_actions.cc b/gtk2_ardour/editor_actions.cc index d3f32f1646..ce33a0177e 100644 --- a/gtk2_ardour/editor_actions.cc +++ b/gtk2_ardour/editor_actions.cc @@ -353,6 +353,12 @@ Editor::register_actions () ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "normalize-region", _("Normalize Region"), mem_fun(*this, &Editor::normalize_region)); ActionManager::session_sensitive_actions.push_back (act); + + act = ActionManager::register_action (editor_actions, "boost-region-gain", _("Boost Region Gain"), bind (mem_fun(*this, &Editor::adjust_region_scale_amplitude), true)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "cut-region-gain", _("Cut Region Gain"), bind (mem_fun(*this, &Editor::adjust_region_scale_amplitude), false)); + ActionManager::session_sensitive_actions.push_back (act); + act = ActionManager::register_action (editor_actions, "crop", _("Crop"), mem_fun(*this, &Editor::crop_region_to_selection)); ActionManager::session_sensitive_actions.push_back (act); act = ActionManager::register_action (editor_actions, "insert-chunk", _("Insert Chunk"), bind (mem_fun(*this, &Editor::paste_named_selection), 1.0f)); diff --git a/gtk2_ardour/editor_mixer.cc b/gtk2_ardour/editor_mixer.cc index 2f6e9d5704..8b60d73f69 100644 --- a/gtk2_ardour/editor_mixer.cc +++ b/gtk2_ardour/editor_mixer.cc @@ -157,7 +157,7 @@ Editor::set_selected_mixer_strip (TimeAxisView& view) current_mixer_strip = new MixerStrip (*ARDOUR_UI::instance()->the_mixer(), *session, - at->route()); + at->route(), false); current_mixer_strip->GoingAway.connect (mem_fun(*this, &Editor::cms_deleted)); if (show) { diff --git a/gtk2_ardour/editor_ops.cc b/gtk2_ardour/editor_ops.cc index eba74abe60..51a6d294cd 100644 --- a/gtk2_ardour/editor_ops.cc +++ b/gtk2_ardour/editor_ops.cc @@ -47,6 +47,7 @@ #include #include #include +#include #include "ardour_ui.h" #include "editor.h" @@ -62,6 +63,7 @@ #include "gtk-custom-hruler.h" #include "gui_thread.h" #include "keyboard.h" +#include "utils.h" #include "i18n.h" @@ -4090,6 +4092,8 @@ Editor::denormalize_region () return; } + ExclusiveRegionSelection (*this, entered_regionview); + if (selection->regions.empty()) { return; } @@ -4108,6 +4112,62 @@ Editor::denormalize_region () commit_reversible_command (); } +void +Editor::adjust_region_scale_amplitude (bool up) +{ + if (!session) { + return; + } + + ExclusiveRegionSelection (*this, entered_regionview); + + if (selection->regions.empty()) { + return; + } + + begin_reversible_command ("denormalize"); + + for (RegionSelection::iterator r = selection->regions.begin(); r != selection->regions.end(); ++r) { + AudioRegionView* const arv = dynamic_cast(*r); + if (!arv) + continue; + XMLNode &before = arv->region()->get_state(); + + double fraction = gain_to_slider_position (arv->audio_region()->scale_amplitude ()); + + cerr << "slider pos for " << arv->audio_region()->scale_amplitude () + << " = " << fraction + << endl; + + if (up) { + fraction += 0.05; + fraction = min (fraction, 1.0); + } else { + fraction -= 0.05; + fraction = max (fraction, 0.0); + } + + if (!up && fraction <= 0) { + continue; + } + + if (up && fraction >= 1.0) { + continue; + } + + fraction = slider_position_to_gain (fraction); + fraction = coefficient_to_dB (fraction); + fraction = dB_to_coefficient (fraction); + + cerr << "set scale amp for " << arv->audio_region()->name() << " to " << fraction << endl; + + arv->audio_region()->set_scale_amplitude (fraction); + session->add_command (new MementoCommand(*(arv->region().get()), &before, &arv->region()->get_state())); + } + + commit_reversible_command (); +} + void Editor::reverse_region () diff --git a/gtk2_ardour/plugin_ui.cc b/gtk2_ardour/plugin_ui.cc index ed77747d7d..0a587b95fa 100644 --- a/gtk2_ardour/plugin_ui.cc +++ b/gtk2_ardour/plugin_ui.cc @@ -67,6 +67,9 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr insert, bool scr bool have_gui = false; non_gtk_gui = false; + Label* label = manage (new Label()); + label->set_markup ("THIS IS THE PLUGIN UI"); + if (insert->plugin()->has_editor()) { switch (insert->type()) { case ARDOUR::VST: @@ -74,7 +77,10 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr insert, bool scr break; case ARDOUR::AudioUnit: - have_gui = create_audiounit_editor (insert); + //have_gui = create_audiounit_editor (insert); + have_gui = true; + get_vbox()->pack_start (*label, false, false); + cerr << "#*#*#*#*#*#*#*#*## PACK " << label << " INTO PLUGIN UI\n"; break; case ARDOUR::LADSPA: @@ -82,8 +88,13 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr insert, bool scr break; default: +#ifndef VST_SUPPORT error << _("unknown type of editor-supplying plugin (note: no VST support in this version of ardour)") << endmsg; +#else + error << _("unknown type of editor-supplying plugin") + << endmsg; +#endif throw failed_constructor (); } @@ -106,9 +117,10 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr insert, bool scr set_name ("PluginEditor"); add_events (Gdk::KEY_PRESS_MASK|Gdk::KEY_RELEASE_MASK|Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); - signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast (this))); + signal_delete_event().connect (bind (sigc::ptr_fun (just_hide_it), reinterpret_cast (this)), false); insert->GoingAway.connect (mem_fun(*this, &PluginUIWindow::plugin_going_away)); +#if 0 gint h = _pluginui->get_preferred_height (); gint w = _pluginui->get_preferred_width (); @@ -122,12 +134,37 @@ PluginUIWindow::PluginUIWindow (boost::shared_ptr insert, bool scr } set_default_size (w, h); +#endif } PluginUIWindow::~PluginUIWindow () { } +void +PluginUIWindow::on_show () +{ + cerr << "PluginWindow shown\n"; + + ArdourDialog::on_show (); + Glib::ListHandle kids (get_vbox()->get_children()); + + cerr << "send show to " << kids.size() << " children of this plugin UI\n"; + + for (Glib::ListHandle::iterator x = kids.begin(); x != kids.end(); ++x) { + cerr << "\tSend show to " << (*x) << endl; + (*x)->show (); + } + cerr << "!! send done\n"; +} + +void +PluginUIWindow::on_hide () +{ + cerr << "PluginWindow hidden\n"; + ArdourDialog::on_hide (); +} + bool PluginUIWindow::create_vst_editor(boost::shared_ptr insert) { @@ -162,6 +199,7 @@ PluginUIWindow::create_audiounit_editor (boost::shared_ptr insert) #else VBox* box; _pluginui = create_au_gui (insert, &box); + cerr << "#*#*#*#*#*#*#*#*## PACK " << box << " INTO PLUGIN UI\n"; get_vbox()->add (*box); non_gtk_gui = true; @@ -177,9 +215,11 @@ PluginUIWindow::app_activated (bool yn) { #if defined (HAVE_AUDIOUNITS) && defined(GTKOSX) if (yn) { - _pluginui->activate (); + if (_pluginui) { + _pluginui->activate (); + } } - cerr << "activated ? " << yn << endl; + cerr << "APP activated ? " << yn << endl; #endif } @@ -208,7 +248,9 @@ PluginUIWindow::plugin_going_away () { ENSURE_GUI_THREAD(mem_fun(*this, &PluginUIWindow::plugin_going_away)); - _pluginui->stop_updating(0); + if (_pluginui) { + _pluginui->stop_updating(0); + } delete_when_idle (this); } diff --git a/gtk2_ardour/plugin_ui.h b/gtk2_ardour/plugin_ui.h index dec4db3481..19a6ad5092 100644 --- a/gtk2_ardour/plugin_ui.h +++ b/gtk2_ardour/plugin_ui.h @@ -206,9 +206,11 @@ class PluginUIWindow : public ArdourDialog void resize_preferred(); - virtual bool on_key_press_event (GdkEventKey*); - virtual bool on_key_release_event (GdkEventKey*); - + bool on_key_press_event (GdkEventKey*); + bool on_key_release_event (GdkEventKey*); + void on_show (); + void on_hide (); + private: PlugUIBase* _pluginui; bool non_gtk_gui; diff --git a/gtk2_ardour/splash.cc b/gtk2_ardour/splash.cc index 4da01783c5..79764b4605 100644 --- a/gtk2_ardour/splash.cc +++ b/gtk2_ardour/splash.cc @@ -26,30 +26,62 @@ Splash::Splash () throw failed_constructor(); } - set_size_request (pixbuf->get_width(), pixbuf->get_height()); + darea.set_size_request (pixbuf->get_width(), pixbuf->get_height()); set_type_hint (Gdk::WINDOW_TYPE_HINT_SPLASHSCREEN); set_keep_above (true); set_position (WIN_POS_CENTER); - add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); + darea.add_events (Gdk::BUTTON_PRESS_MASK|Gdk::BUTTON_RELEASE_MASK); + + layout = create_pango_layout (""); + + darea.show (); + darea.signal_expose_event().connect (mem_fun (*this, &Splash::expose)); + + add (darea); +} + +void +Splash::on_realize () +{ + Window::on_realize (); + layout->set_font_description (get_style()->get_font()); } + bool Splash::on_button_release_event (GdkEventButton* ev) { hide (); + return true; } bool -Splash::on_expose_event (GdkEventExpose* ev) +Splash::expose (GdkEventExpose* ev) { - RefPtr window = get_window(); - - Window::on_expose_event (ev); + RefPtr window = darea.get_window(); window->draw_pixbuf (get_style()->get_bg_gc (STATE_NORMAL), pixbuf, ev->area.x, ev->area.y, ev->area.x, ev->area.y, ev->area.width, ev->area.height, Gdk::RGB_DITHER_NONE, 0, 0); + + Glib::RefPtr style = darea.get_style(); + Glib::RefPtr white = style->get_white_gc(); + + window->draw_layout (white, 10, pixbuf->get_height() - 30, layout); + return true; } + +void +Splash::message (const string& msg) +{ + string str (""); + str += msg; + str += ""; + + layout->set_markup (str); + darea.queue_draw (); + get_window()->process_updates (true); +} diff --git a/gtk2_ardour/splash.h b/gtk2_ardour/splash.h index 3ef717d08d..5ba5478941 100644 --- a/gtk2_ardour/splash.h +++ b/gtk2_ardour/splash.h @@ -21,6 +21,9 @@ #define __ardour_gtk_splash_h__ #include +#include +#include +#include #include class ARDOUR_UI; @@ -31,11 +34,16 @@ class Splash : public Gtk::Window Splash (); ~Splash () {} - bool on_expose_event (GdkEventExpose*); + bool expose (GdkEventExpose*); bool on_button_release_event (GdkEventButton*); + void on_realize (); + void message (const std::string& msg); + private: Glib::RefPtr pixbuf; + Gtk::DrawingArea darea; + Glib::RefPtr layout; }; #endif /* __ardour_gtk_splash_h__ */ diff --git a/gtk2_ardour/utils.cc b/gtk2_ardour/utils.cc index 991f31b74d..5395fedc2d 100644 --- a/gtk2_ardour/utils.cc +++ b/gtk2_ardour/utils.cc @@ -106,7 +106,7 @@ fit_to_pixels (const ustring& str, int pixel_width, Pango::FontDescription& font gint just_hide_it (GdkEventAny *ev, Gtk::Window *win) { - win->hide_all (); + win->hide (); return TRUE; } diff --git a/libs/ardour/ardour/io.h b/libs/ardour/ardour/io.h index 1bd913aec9..db0a097490 100644 --- a/libs/ardour/ardour/io.h +++ b/libs/ardour/ardour/io.h @@ -399,8 +399,9 @@ class IO : public PBD::StatefulDestructible bool ensure_inputs_locked (uint32_t, bool clear, void *src); bool ensure_outputs_locked (uint32_t, bool clear, void *src); - int32_t find_input_port_hole (); - int32_t find_output_port_hole (); + std::string build_legal_port_name (bool for_input); + int32_t find_input_port_hole (const char* base); + int32_t find_output_port_hole (const char* base); }; } // namespace ARDOUR diff --git a/libs/ardour/audio_unit.cc b/libs/ardour/audio_unit.cc index c8dae0406a..dae5eea99e 100644 --- a/libs/ardour/audio_unit.cc +++ b/libs/ardour/audio_unit.cc @@ -512,7 +512,7 @@ PluginInfoList AUPluginInfo::discover () { PluginInfoList plugs; - + discover_fx (plugs); discover_music (plugs); diff --git a/libs/ardour/audioengine.cc b/libs/ardour/audioengine.cc index 2d8d225630..2337e51481 100644 --- a/libs/ardour/audioengine.cc +++ b/libs/ardour/audioengine.cc @@ -1060,9 +1060,8 @@ AudioEngine::connect_to_jack (string client_name) const char *server_name = NULL; jack_client_name = client_name; /* might be reset below */ - _jack = jack_client_open (jack_client_name.c_str(), options, &status, server_name); - + if (_jack == NULL) { /* just return without an error message. something else will take care of it */ return -1; diff --git a/libs/ardour/io.cc b/libs/ardour/io.cc index cc5c812af8..b3bfd82271 100644 --- a/libs/ardour/io.cc +++ b/libs/ardour/io.cc @@ -836,7 +836,6 @@ int IO::add_output_port (string destination, void* src, DataType type) { Port* our_port; - char name[64]; if (type == DataType::NIL) type = _default_type; @@ -854,15 +853,10 @@ IO::add_output_port (string destination, void* src, DataType type) /* Create a new output port */ - // FIXME: naming scheme for differently typed ports? - if (_output_maximum == 1) { - snprintf (name, sizeof (name), _("%s/out"), _name.c_str()); - } else { - snprintf (name, sizeof (name), _("%s/out %u"), _name.c_str(), find_output_port_hole()); - } + string portname = build_legal_port_name (false); - if ((our_port = _session.engine().register_output_port (type, name)) == 0) { - error << string_compose(_("IO: cannot register output port %1"), name) << endmsg; + if ((our_port = _session.engine().register_output_port (type, portname)) == 0) { + error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg; return -1; } @@ -950,7 +944,6 @@ int IO::add_input_port (string source, void* src, DataType type) { Port* our_port; - char name[64]; if (type == DataType::NIL) type = _default_type; @@ -967,15 +960,10 @@ IO::add_input_port (string source, void* src, DataType type) /* Create a new input port */ - // FIXME: naming scheme for differently typed ports? - if (_input_maximum == 1) { - snprintf (name, sizeof (name), _("%s/in"), _name.c_str()); - } else { - snprintf (name, sizeof (name), _("%s/in %u"), _name.c_str(), find_input_port_hole()); - } - - if ((our_port = _session.engine().register_input_port (type, name)) == 0) { - error << string_compose(_("IO: cannot register input port %1"), name) << endmsg; + string portname = build_legal_port_name (true); + + if ((our_port = _session.engine().register_input_port (type, portname)) == 0) { + error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg; return -1; } @@ -1067,21 +1055,14 @@ IO::ensure_inputs_locked (uint32_t n, bool clear, void* src) while (_ninputs < n) { - char buf[64]; - /* Create a new input port (of the default type) */ - if (_input_maximum == 1) { - snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str()); - } - else { - snprintf (buf, sizeof (buf), _("%s/in %u"), _name.c_str(), find_input_port_hole()); - } + string portname = build_legal_port_name (true); try { - if ((input_port = _session.engine().register_input_port (_default_type, buf)) == 0) { - error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg; + if ((input_port = _session.engine().register_input_port (_default_type, portname)) == 0) { + error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg; return -1; } } @@ -1173,20 +1154,13 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src) while (_ninputs < nin) { - char buf[64]; - /* Create a new input port */ - if (_input_maximum == 1) { - snprintf (buf, sizeof (buf), _("%s/in"), _name.c_str()); - } - else { - snprintf (buf, sizeof (buf), _("%s/in %u"), _name.c_str(), find_input_port_hole()); - } - + string portname = build_legal_port_name (true); + try { - if ((port = _session.engine().register_input_port (_default_type, buf)) == 0) { - error << string_compose(_("IO: cannot register input port %1"), buf) << endmsg; + if ((port = _session.engine().register_input_port (_default_type, portname)) == 0) { + error << string_compose(_("IO: cannot register input port %1"), portname) << endmsg; return -1; } } @@ -1207,19 +1181,11 @@ IO::ensure_io (uint32_t nin, uint32_t nout, bool clear, void* src) while (_noutputs < nout) { - char buf[64]; - - /* Create a new output port */ - - if (_output_maximum == 1) { - snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str()); - } else { - snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole()); - } - + string portname = build_legal_port_name (false); + try { - if ((port = _session.engine().register_output_port (_default_type, buf)) == 0) { - error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg; + if ((port = _session.engine().register_output_port (_default_type, portname)) == 0) { + error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg; return -1; } } @@ -1333,18 +1299,12 @@ IO::ensure_outputs_locked (uint32_t n, bool clear, void* src) while (_noutputs < n) { - char buf[64]; - /* Create a new output port */ - if (_output_maximum == 1) { - snprintf (buf, sizeof (buf), _("%s/out"), _name.c_str()); - } else { - snprintf (buf, sizeof (buf), _("%s/out %u"), _name.c_str(), find_output_port_hole()); - } + string portname = build_legal_port_name (false); - if ((output_port = _session.engine().register_output_port (_default_type, buf)) == 0) { - error << string_compose(_("IO: cannot register output port %1"), buf) << endmsg; + if ((output_port = _session.engine().register_output_port (_default_type, portname)) == 0) { + error << string_compose(_("IO: cannot register output port %1"), portname) << endmsg; return -1; } @@ -2665,8 +2625,54 @@ IO::transport_stopped (nframes_t frame) _panner->transport_stopped (frame); } +string +IO::build_legal_port_name (bool in) +{ + const int name_size = jack_port_name_size(); + int limit; + char* suffix; + int maxports; + + if (in) { + suffix = _("in"); + maxports = _input_maximum; + } else { + suffix = _("out"); + maxports = _output_maximum; + } + + if (maxports == 1) { + // allow space for the slash + the suffix + limit = name_size - _session.engine().client_name().length() - (strlen (suffix) + 1); + char buf[name_size+1]; + snprintf (buf, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix); + return string (buf); + } + + // allow up to 4 digits for the output port number, plus the slash, suffix and extra space + + limit = name_size - _session.engine().client_name().length() - (strlen (suffix) + 5); + + char buf1[name_size+1]; + char buf2[name_size+1]; + + snprintf (buf1, name_size+1, ("%.*s/%s"), limit, _name.c_str(), suffix); + + int port_number; + + if (in) { + port_number = find_input_port_hole (buf1); + } else { + port_number = find_output_port_hole (buf1); + } + + snprintf (buf2, name_size+1, "%s %d", buf1, port_number); + + return string (buf2); +} + int32_t -IO::find_input_port_hole () +IO::find_input_port_hole (const char* base) { /* CALLER MUST HOLD IO LOCK */ @@ -2676,11 +2682,14 @@ IO::find_input_port_hole () return 1; } - for (n = 1; n < UINT_MAX; ++n) { + /* we only allow up to 4 characters for the port number + */ + + for (n = 1; n < 9999; ++n) { char buf[jack_port_name_size()]; vector::iterator i; - snprintf (buf, jack_port_name_size(), _("%s/in %u"), _name.c_str(), n); + snprintf (buf, jack_port_name_size(), _("%s %u"), base, n); for (i = _inputs.begin(); i != _inputs.end(); ++i) { if ((*i)->short_name() == buf) { @@ -2696,7 +2705,7 @@ IO::find_input_port_hole () } int32_t -IO::find_output_port_hole () +IO::find_output_port_hole (const char* base) { /* CALLER MUST HOLD IO LOCK */ @@ -2706,11 +2715,14 @@ IO::find_output_port_hole () return 1; } - for (n = 1; n < UINT_MAX; ++n) { + /* we only allow up to 4 characters for the port number + */ + + for (n = 1; n < 9999; ++n) { char buf[jack_port_name_size()]; vector::iterator i; - snprintf (buf, jack_port_name_size(), _("%s/out %u"), _name.c_str(), n); + snprintf (buf, jack_port_name_size(), _("%s %u"), base, n); for (i = _outputs.begin(); i != _outputs.end(); ++i) { if ((*i)->short_name() == buf) { diff --git a/libs/ardour/rb_effect.cc b/libs/ardour/rb_effect.cc index a8d22c13b3..f86248d44d 100644 --- a/libs/ardour/rb_effect.cc +++ b/libs/ardour/rb_effect.cc @@ -74,9 +74,12 @@ RBEffect::run (boost::shared_ptr region) nframes_t pos = 0; int avail = 0; + double this_time_fraction = tsr.time_fraction * region->stretch (); + double this_pitch_fraction = tsr.pitch_fraction * region->shift (); + RubberBandStretcher stretcher (session.frame_rate(), region->n_channels(), (RubberBandStretcher::Options) tsr.opts, - tsr.time_fraction, tsr.pitch_fraction); + this_time_fraction, this_pitch_fraction); stretcher.setExpectedInputDuration(region->length()); stretcher.setDebugLevel(1); @@ -91,14 +94,14 @@ RBEffect::run (boost::shared_ptr region) digits just to disambiguate close but not identical FX */ - if (tsr.time_fraction == 1.0) { - snprintf (suffix, sizeof (suffix), "@%d", (int) floor (tsr.pitch_fraction * 100.0f)); - } else if (tsr.pitch_fraction == 1.0) { - snprintf (suffix, sizeof (suffix), "@%d", (int) floor (tsr.time_fraction * 100.0f)); + if (this_time_fraction == 1.0) { + snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_pitch_fraction * 100.0f)); + } else if (this_pitch_fraction == 1.0) { + snprintf (suffix, sizeof (suffix), "@%d", (int) floor (this_time_fraction * 100.0f)); } else { snprintf (suffix, sizeof (suffix), "@%d-%d", - (int) floor (tsr.time_fraction * 100.0f), - (int) floor (tsr.pitch_fraction * 100.0f)); + (int) floor (this_time_fraction * 100.0f), + (int) floor (this_pitch_fraction * 100.0f)); } /* create new sources */ @@ -259,9 +262,8 @@ RBEffect::run (boost::shared_ptr region) nframes_t start; nframes_t length; - // note: tsr.time_fraction is a percentage of original length. 100 = no change, - // 50 is half as long, 200 is twice as long, etc. - + // note: this_time_fraction is a ratio of original length. 1.0 = no change, + // 0.5 is half as long, 2.0 is twice as long, etc. float stretch = (*x)->stretch() * (tsr.time_fraction/100.0); float shift = (*x)->shift() * tsr.pitch_fraction; diff --git a/libs/gtkmm2ext/binding_proxy.cc b/libs/gtkmm2ext/binding_proxy.cc index 3a2f5bbbc8..90f95f82ef 100644 --- a/libs/gtkmm2ext/binding_proxy.cc +++ b/libs/gtkmm2ext/binding_proxy.cc @@ -32,13 +32,19 @@ using namespace std; using namespace PBD; BindingProxy::BindingProxy (Controllable& c) - : prompter (Gtk::WIN_POS_MOUSE, 30000, false), + : prompter (0), controllable (c), bind_button (2), bind_statemask (Gdk::CONTROL_MASK) { - prompter.signal_unmap_event().connect (mem_fun (*this, &BindingProxy::prompter_hiding)); +} + +BindingProxy::~BindingProxy () +{ + if (prompter) { + delete prompter; + } } void @@ -61,8 +67,12 @@ BindingProxy::button_press_handler (GdkEventButton *ev) if ((ev->state & bind_statemask) && ev->button == bind_button) { if (Controllable::StartLearning (&controllable)) { string prompt = _("operate controller now"); - prompter.set_text (prompt); - prompter.touch (); // shows popup + if (prompter == 0) { + prompter = new PopUp (Gtk::WIN_POS_MOUSE, 30000, false); + prompter->signal_unmap_event().connect (mem_fun (*this, &BindingProxy::prompter_hiding)); + } + prompter->set_text (prompt); + prompter->touch (); // shows popup learning_connection = controllable.LearningFinished.connect (mem_fun (*this, &BindingProxy::learning_finished)); } return true; @@ -75,7 +85,9 @@ void BindingProxy::learning_finished () { learning_connection.disconnect (); - prompter.touch (); // hides popup + if (prompter) { + prompter->touch (); // hides popup + } } diff --git a/libs/gtkmm2ext/gtk_ui.cc b/libs/gtkmm2ext/gtk_ui.cc index eed78e1fdb..58178056c2 100644 --- a/libs/gtkmm2ext/gtk_ui.cc +++ b/libs/gtkmm2ext/gtk_ui.cc @@ -591,7 +591,8 @@ UI::flush_pending () bool UI::just_hide_it (GdkEventAny *ev, Window *win) { - win->hide_all (); + cerr << "++++ JUST HIDING " << win->get_window() << endl; + win->hide (); return true; } diff --git a/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h index a26c8ace2a..d8f37c7649 100644 --- a/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h +++ b/libs/gtkmm2ext/gtkmm2ext/binding_proxy.h @@ -33,7 +33,7 @@ class BindingProxy : public sigc::trackable { public: BindingProxy (PBD::Controllable&); - virtual ~BindingProxy() {} + virtual ~BindingProxy(); void set_bind_button_state (guint button, guint statemask); void get_bind_button_state (guint &button, guint &statemask); @@ -42,7 +42,7 @@ class BindingProxy : public sigc::trackable protected: - Gtkmm2ext::PopUp prompter; + Gtkmm2ext::PopUp* prompter; PBD::Controllable& controllable; guint bind_button; guint bind_statemask; diff --git a/tools/osx_packaging/osx_build b/tools/osx_packaging/osx_build index 09d2e7a337..ff08c7e933 100755 --- a/tools/osx_packaging/osx_build +++ b/tools/osx_packaging/osx_build @@ -74,10 +74,16 @@ if test x$SAE != x ; then env="$envARDOUR_KEYBOARD_LAYOUTde" fi +# +# if we're not going to bundle JACK, make sure we can find +# jack in the places where it might be +# + if test x$WITH_JACK != x ; then env="$envARDOUR_WITH_JACKtrue" else env="$envPATH/usr/local/bin:/opt/bin" + env="$envDYLIB_FALLBACK_LIBRARY_PATH/usr/local/lib:/opt/lib" fi env="LSEnvironmentARDOUR_BUNDLEDtrue$env" -- 2.30.2