plug leaks, leaker tweaks, lang for effect info, c41 spiffs, wm probe tweaks
[goodguy/history.git] / cinelerra-5.1 / cinelerra / mwindow.C
index 5528477892299adf8d43b9c6d847cd705403d5c4..2c0ddff46de8ebc2c648ea7296982172cc6268aa 100644 (file)
@@ -29,6 +29,7 @@
 #include "bcdisplayinfo.h"
 #include "bcsignals.h"
 #include "bctimer.h"
+#include "bctrace.h"
 #include "bdcreate.h"
 #include "brender.h"
 #include "cache.h"
@@ -199,6 +200,8 @@ MWindow::MWindow()
        mainindexes = 0;
        mainprogress = 0;
        brender = 0;
+       brender_active = 0;
+       strcpy(cin_lang,"en");
        channeldb_buz =  new ChannelDB;
        channeldb_v4l2jpeg =  new ChannelDB;
        //file_server = 0;
@@ -228,6 +231,7 @@ MWindow::MWindow()
 MWindow::~MWindow()
 {
        run_lock->lock("MWindow::~MWindow");
+       stop_playback(1);
        in_destructor = 1;
 //printf("MWindow::~MWindow %d\n", __LINE__);
        gui->stop_drawing();
@@ -293,6 +297,9 @@ MWindow::~MWindow()
 #endif
        reset_caches();
        dead_plugins->remove_all_objects();
+// must delete theme before destroying plugindb
+//  theme destructor will be deleted by delete_plugins
+       delete theme;           theme = 0;
        delete_plugins();
        finit_error();
        keyframe_threads->remove_all_objects();
@@ -321,7 +328,6 @@ MWindow::~MWindow()
        delete defaults;        defaults = 0;
        delete assets;          assets = 0;
        delete splash_window;   splash_window = 0;
-//     delete theme;           theme = 0;      // deleted by delete_plugins
        if( !edl->Garbage::remove_user() ) edl = 0;
        delete channeldb_buz;
        delete channeldb_v4l2jpeg;
@@ -460,6 +466,39 @@ void MWindow::init_defaults(BC_Hash* &defaults, char *config_path)
        defaults->load();
 }
 
+
+void MWindow::check_language()
+{
+       char curr_lang[BCTEXTLEN]; curr_lang[0] = 0;
+       const char *env_lang = getenv("LANGUAGE");
+       if( !env_lang ) env_lang = getenv("LC_ALL");
+       if( !env_lang ) env_lang = getenv("LANG");
+       if( !env_lang ) {
+               snprintf(curr_lang, sizeof(curr_lang), "%s_%s-%s",
+                       BC_Resources::language, BC_Resources::region, BC_Resources::encoding);
+               env_lang = curr_lang;
+       }
+       char last_lang[BCTEXTLEN]; last_lang[0] = 0;
+       defaults->get("LAST_LANG",last_lang);
+       if( strcmp(env_lang,last_lang)) {
+               printf("lang changed from '%s' to '%s'\n", last_lang, env_lang);
+               defaults->update("LAST_LANG",env_lang);
+               char plugin_path[BCTEXTLEN];
+               create_defaults_path(plugin_path, PLUGIN_FILE);
+               ::remove(plugin_path);
+               char ladspa_path[BCTEXTLEN];
+               create_defaults_path(ladspa_path, LADSPA_FILE);
+               ::remove(ladspa_path);
+               defaults->save();
+       }
+       if( strlen(env_lang) > 1 &&
+           ( env_lang[2] == 0 || env_lang[2] == '_'  || env_lang[2] == '.' ) ) {
+               cin_lang[0] = env_lang[0];  cin_lang[1] = env_lang[1];  cin_lang[2] = 0;
+       }
+       else
+               strcpy(cin_lang, "en");
+}
+
 void MWindow::get_plugin_path(char *path, const char *plug_dir, const char *fs_path)
 {
        char *base_path = FileSystem::basepath(fs_path), *bp = base_path;
@@ -598,6 +637,7 @@ int MWindow::init_ladspa_plugins(MWindow *mwindow, Preferences *preferences)
                len = !cp ? strlen(path) : cp-path;
                char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN];
                memcpy(plugin_path, path, len);  plugin_path[len] = 0;
+               if( cp ) ++len;
                char *plugin_dir = FileSystem::basepath(plugin_path);
                strcpy(plugin_path, plugin_dir);  delete [] plugin_dir;
                create_defaults_path(index_path, LADSPA_FILE);
@@ -695,6 +735,66 @@ void MWindow::add_plugins(ArrayList<PluginServer*> &plugins)
        plugins.remove_all();
 }
 
+void MWindow::init_plugin_tips(ArrayList<PluginServer*> &plugins, const char *lang)
+{
+       const char *cfg_path = File::get_cindat_path();
+       char msg_path[BCTEXTLEN];  int txt = 0;
+       FILE *fp = 0;
+       if( BC_Resources::language[0] ) {
+               snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.%s",
+                       cfg_path, lang);
+               fp = fopen(msg_path, "r");
+       }
+       if( !fp ) {
+               txt = 1;
+               snprintf(msg_path, sizeof(msg_path), "%s/info/plugins.txt",
+                       cfg_path);
+               fp = fopen(msg_path, "r");
+       }
+       if( !fp ) return;
+       char text[BCTEXTLEN];
+       char *tp = text, *ep = tp + sizeof(text)-1;
+       char title[BCTEXTLEN];
+       title[0] = 0;
+       int no = 0;
+       for(;;) {
+               ++no;  int done = 1;
+               char line[BCTEXTLEN], *cp = line;
+               if( fgets(line,sizeof(line)-1,fp) ) {
+                       if( *cp == '#' ) continue;
+                       done = *cp == ' ' || *cp == '\t' ? 0 : -1;
+               }
+               if( done ) {
+                       if( tp > text && *--tp == '\n' ) *tp = 0;
+                       if( title[0] ) {
+                               tp = !txt ? title : _(title);
+                               int idx = plugins.size();
+                               while( --idx>=0 && strcmp(plugins[idx]->title, tp) );
+                               if( idx >= 0 ) {
+                                       delete [] plugins[idx]->tip;
+                                       plugins[idx]->tip = cstrdup(text);
+                               }
+                               title[0] = 0;
+                       }
+                       if( done > 0 ) break;
+                       tp = text;  *tp = 0;
+                       char *dp = strchr(cp, ':');
+                       if( !dp ) {
+                               printf("plugin tips: error on line %d\n", no);
+                               continue;
+                       }
+                       char *bp = title;
+                       while( cp < dp ) *bp++ = *cp++;
+                       *bp = 0;
+                       ++cp;
+               }
+
+               while( *cp == ' ' || *cp == '\t' ) ++cp;
+               for( ; tp<ep && (*tp=*cp)!=0; ++tp,++cp );
+       }
+       fclose(fp);
+}
+
 void MWindow::delete_plugins()
 {
        plugindb->remove_all_objects();
@@ -784,11 +884,17 @@ void MWindow::init_preferences()
        session->load_defaults(defaults);
        // set x11_host, screens, window_config
        screens = session->set_default_x11_host();
-       BC_Signals::set_trap_path("/tmp/cinelerra_%d.dmp");
        BC_Signals::set_trap_hook(trap_hook, this);
        BC_Signals::set_catch_segv(preferences->trap_sigsegv);
        BC_Signals::set_catch_intr(preferences->trap_sigintr);
+       if( preferences->trap_sigsegv || preferences->trap_sigintr ) {
+               BC_Trace::enable_locks();
+       }
+       else {
+               BC_Trace::disable_locks();
+       }
        BC_WindowBase::get_resources()->popupmenu_btnup = preferences->popupmenu_btnup;
+       BC_WindowBase::get_resources()->textbox_focus_policy = preferences->textbox_focus_policy;
 }
 
 void MWindow::clean_indexes()
@@ -883,6 +989,7 @@ void MWindow::init_gwindow()
 
 void MWindow::init_tipwindow()
 {
+       TipWindow::load_tips(cin_lang);
        if( !twindow )
                twindow = new TipWindow(this);
        twindow->start();
@@ -917,12 +1024,13 @@ void MWindow::init_theme()
                fprintf(stderr, _("MWindow::init_theme: prefered theme %s not found.\n"),
                         preferences->theme);
 
-       if( !theme_plugin && strcasecmp(preferences->theme, DEFAULT_THEME) ) {
+       const char *default_theme = _(DEFAULT_THEME);
+       if( !theme_plugin && strcasecmp(preferences->theme, default_theme) ) {
                fprintf(stderr, _("MWindow::init_theme: trying default theme %s\n"),
-                       DEFAULT_THEME);
+                       default_theme);
                for(int i = 0; i < plugindb->total && !theme_plugin; i++) {
                        if( plugindb->get(i)->theme &&
-                           !strcasecmp(DEFAULT_THEME, plugindb->get(i)->title) )
+                           !strcasecmp(default_theme, plugindb->get(i)->title) )
                                theme_plugin = plugindb->get(i);
                }
        }
@@ -969,6 +1077,7 @@ void MWindow::init_edl()
        edl->create_objects();
        fill_preset_defaults(default_standard, edl->session);
        edl->load_defaults(defaults);
+       edl->session->brender_start = edl->session->brender_end = 0;
        edl->create_default_tracks();
        edl->tracks->update_y_pixels(theme);
 }
@@ -1091,7 +1200,7 @@ void MWindow::init_gui()
 void MWindow::init_signals()
 {
        sighandler = new SigHandler;
-       sighandler->initialize();
+       sighandler->initialize("/tmp/cinelerra_%d.dmp");
 ENABLE_BUFFER
 }
 
@@ -1127,25 +1236,35 @@ void MWindow::init_brender()
                session->brender_end = 0;
                brender_lock->unlock();
        }
-       if(brender) brender->restart(edl);
+       brender_active = 0;
+       stop_brender();
 }
 
 void MWindow::restart_brender()
 {
 //printf("MWindow::restart_brender 1\n");
-       if(brender) brender->restart(edl);
+       if( !brender_active || !preferences->use_brender ) return;
+       if( !brender ) return;
+       int locked  = gui->get_window_lock();
+       if( locked ) gui->unlock_window();
+       brender->restart(edl);
+       if( locked ) gui->lock_window("MWindow::restart_brender");
 }
 
 void MWindow::stop_brender()
 {
-       if(brender) brender->stop();
+       if( !brender ) return;
+       int locked  = gui->get_window_lock();
+       if( locked ) gui->unlock_window();
+       brender->stop();
+       if( locked ) gui->lock_window("MWindow::stop_brender");
 }
 
 int MWindow::brender_available(int position)
 {
        int result = 0;
        brender_lock->lock("MWindow::brender_available 1");
-       if(brender)
+       if(brender && brender_active)
        {
                if(brender->map_valid)
                {
@@ -1164,13 +1283,29 @@ int MWindow::brender_available(int position)
        return result;
 }
 
-void MWindow::set_brender_start()
+void MWindow::set_brender_active(int v, int update)
 {
-       edl->session->brender_start = edl->local_session->get_selectionstart(1);
-       restart_brender();
-       gui->draw_overlays(1);
-}
+       if( !preferences->use_brender ) v = 0;
+       brender_active = v;
+       gui->mainmenu->brender_active->set_checked(v);
+       if( v != 0 ) {
+               edl->session->brender_start = edl->local_session->get_selectionstart(1);
+               edl->session->brender_end = edl->local_session->get_selectionend(1);
 
+               if(EQUIV(edl->session->brender_end, edl->session->brender_start)) {
+                       edl->session->brender_end = edl->tracks->total_video_length();
+               }
+               restart_brender();
+       }
+       else {
+               edl->session->brender_start = edl->session->brender_end = 0;
+               stop_brender();
+       }
+       if( update ) {
+               gui->update_timebar(0);
+               gui->draw_overlays(1);
+       }
+}
 
 int MWindow::has_commercials()
 {
@@ -1273,17 +1408,12 @@ void MWindow::stop_playback(int wait)
        int locked  = gui->get_window_lock();
        if( locked ) gui->unlock_window();
 
-       cwindow->playback_engine->que->send_command(STOP,
-               CHANGE_NONE,
-               0,
-               0);
-       cwindow->playback_engine->interrupt_playback(wait);
+       cwindow->playback_engine->stop_playback();
 
        for(int i = 0; i < vwindows.size(); i++) {
                VWindow *vwindow = vwindows[i];
                if( !vwindow->is_running() ) continue;
-               vwindow->playback_engine->que->send_command(STOP, CHANGE_NONE, 0, 0);
-               vwindow->playback_engine->interrupt_playback(wait);
+               vwindow->playback_engine->stop_playback();
        }
        if( locked ) gui->lock_window("MWindow::stop_playback");
 }
@@ -1402,17 +1532,16 @@ SET_TRACE
                        case FILE_NOT_FOUND:
                                sprintf(string, _("Failed to open %s"), new_asset->path);
                                gui->show_message(string, theme->message_error);
+                               gui->update_default_message();
                                break;
 
 // Unknown format
                        case FILE_UNRECOGNIZED_CODEC:
                        {
 // Test index file
-                               IndexFile indexfile(this, new_asset);
-                               result = indexfile.open_index();
-                               if(!result)
-                               {
-                                       indexfile.close_index();
+                               {       IndexFile indexfile(this, new_asset);
+                                       if( !(result = indexfile.open_index()) )
+                                               indexfile.close_index();
                                }
 
 // Test existing EDLs
@@ -1421,7 +1550,7 @@ SET_TRACE
                                                new_edls[j]->assets->get_asset(new_asset->path) :
                                                edl->assets->get_asset(new_asset->path);
                                        if( old_asset ) {
-                                               *new_asset = *old_asset;
+                                               new_asset->copy_from(old_asset,1);
                                                result = 0;
                                        }
                                }
@@ -1545,6 +1674,15 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                                if(update_filename)
                                                        set_filename(new_edl->local_session->clip_title);
                                        }
+                                       else
+                                       if( load_mode == LOADMODE_RESOURCESONLY ) {
+                                               strcpy(new_edl->local_session->clip_title,
+                                                       filenames->get(i));
+                                               struct stat st;
+                                               time_t t = !stat(filenames->get(i),&st) ?
+                                                       st.st_mtime : time(&t);
+                                               ctime_r(&t, new_edl->local_session->clip_notes);
+                                       }
                                }
 
                                new_edls.append(new_edl);
@@ -1565,12 +1703,10 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
 
-       if(!result) gui->statusbar->default_message();
-
-
-
-
-
+       if(!result) {
+               gui->reset_default_message();
+               gui->default_message();
+       }
 
 
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
@@ -1593,10 +1729,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                        edl->session->autos_follow_edits);
                }
 
-               paste_edls(&new_edls,
-                       load_mode,
-                       0,
-                       -1,
+               paste_edls(&new_edls, load_mode, 0, -1,
                        edl->session->labels_follow_edits,
                        edl->session->plugins_follow_edits,
                        edl->session->autos_follow_edits,
@@ -1624,32 +1757,26 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
        }
 
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
-       if(new_assets.size())
+       for(int i = 0; i < new_assets.size(); i++)
        {
-               for(int i = 0; i < new_assets.size(); i++)
-               {
-                       Asset *new_asset = new_assets[i];
+               Asset *new_asset = new_assets[i];
 
-                       File *new_file = 0;
-                       int got_it = 0;
-                       for(int j = 0; j < new_files.size(); j++)
+               File *new_file = 0;
+               int got_it = 0;
+               for(int j = 0; j < new_files.size(); j++)
+               {
+                       new_file = new_files[j];
+                       if(!strcmp(new_file->asset->path,
+                               new_asset->path))
                        {
-                               new_file = new_files[j];
-                               if(!strcmp(new_file->asset->path,
-                                       new_asset->path))
-                               {
-                                       got_it = 1;
-                                       break;
-                               }
+                               got_it = 1;
+                               break;
                        }
-
-                       mainindexes->add_next_asset(got_it ? new_file : 0, new_asset);
-                       got_indexes = 1;
-                       edl->assets->update(new_asset);
-
                }
 
-
+               mainindexes->add_next_asset(got_it ? new_file : 0, new_asset);
+               got_indexes = 1;
+               edl->assets->update(new_asset);
        }
 if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
 
@@ -1677,10 +1804,6 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                                                show_plugin(plugin);
                                        }
                                }
-                               else
-                               {
-                                       plugin->show = 0;
-                               }
 
                                plugin = (Plugin*)plugin->next;
                        }
@@ -1699,6 +1822,7 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__);
                edl->local_session->loop_playback = 0;
                edl->local_session->set_selectionstart(0);
                edl->local_session->set_selectionend(0);
+               set_brender_active(0, 0);
                fit_selection();
                goto_start();
        }
@@ -1877,6 +2001,7 @@ void MWindow::create_objects(int want_gui,
        if(debug) PRINT_TRACE
        default_standard = default_std();
        init_defaults(defaults, config_path);
+       check_language();
        init_preferences();
        if(splash_window)
                splash_window->operation->update(_("Initializing Plugins"));
@@ -1884,6 +2009,7 @@ void MWindow::create_objects(int want_gui,
        if(debug) PRINT_TRACE
        init_ladspa_plugins(this, preferences);
        if(debug) PRINT_TRACE
+       init_plugin_tips(*plugindb, cin_lang);
        if(splash_window)
                splash_window->operation->update(_("Initializing GUI"));
        if(debug) PRINT_TRACE
@@ -1912,6 +2038,9 @@ void MWindow::create_objects(int want_gui,
 
        Timer timer;
 
+       init_awindow();
+       if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
+
        init_compositor();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
 
@@ -1923,24 +2052,21 @@ void MWindow::create_objects(int want_gui,
        init_gui();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
 
-       init_awindow();
-       if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
-
        init_levelwindow();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
 
-       if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
-
        init_indexes();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
 
        init_channeldb();
-
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
+
        init_gwindow();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
+
        init_render();
        if(debug) printf("MWindow::create_objects %d total_time=%d\n", __LINE__, (int)timer.get_difference());
+
        init_brender();
        init_exportedl();
        init_commercials();
@@ -2457,8 +2583,8 @@ SET_TRACE
 // Needs mwindow to do GUI
                        gui->set_mwindow(this);
                        gui->open_plugin(0, preferences, edl, plugin);
-                       gui->show_gui();
                        plugin->show = 1;
+                       gui->show_gui();
                }
        }
        plugin_gui_lock->unlock();
@@ -2824,7 +2950,7 @@ void MWindow::update_project(int load_mode)
        const int debug = 0;
 
        if(debug) PRINT_TRACE
-       restart_brender();
+       init_brender();
        edl->tracks->update_y_pixels(theme);
 
        if(debug) PRINT_TRACE
@@ -2916,9 +3042,13 @@ void MWindow::rebuild_indices()
                index_state->index_status = INDEX_NOTTESTED;
                if( indexable->is_asset ) {
                        Asset *asset = (Asset *)indexable;
-                       if( asset->format != FILE_PCM )
+                       if( asset->format != FILE_PCM ) {
+                               asset->format = FILE_UNKNOWN;
                                asset->reset_audio();
+                       }
                        asset->reset_video();
+//                     File file; // re-probe the asset
+//                     file.open_file(preferences, asset, 1, 0);
                }
                mainindexes->add_next_asset(0, indexable);
        }
@@ -3063,8 +3193,8 @@ void MWindow::remove_asset_from_caches(Asset *asset)
 void MWindow::remove_assets_from_project(int push_undo, int redraw,
                ArrayList<Indexable*> *drag_assets, ArrayList<EDL*> *drag_clips)
 {
-       for(int i = 0; i < session->drag_assets->total; i++) {
-               Indexable *indexable = session->drag_assets->get(i);
+       for(int i = 0; i < drag_assets->total; i++) {
+               Indexable *indexable = drag_assets->get(i);
                if(indexable->is_asset) remove_asset_from_caches((Asset*)indexable);
        }
 
@@ -3081,11 +3211,11 @@ void MWindow::remove_assets_from_project(int push_undo, int redraw,
                }
        }
 
-       for(int i = 0; i < session->drag_assets->size(); i++) {
+       for(int i = 0; i < drag_assets->size(); i++) {
                for(int j = 0; j < vwindows.size(); j++) {
                        VWindow *vwindow = vwindows[j];
                        if( !vwindow->is_running() ) continue;
-                       if(session->drag_assets->get(i) == vwindow->get_source()) {
+                       if(drag_assets->get(i) == vwindow->get_source()) {
                                vwindow->gui->lock_window("MWindow::remove_assets_from_project 2");
                                vwindow->delete_source(1, 1);
                                vwindow->gui->unlock_window();
@@ -3093,29 +3223,22 @@ void MWindow::remove_assets_from_project(int push_undo, int redraw,
                }
        }
 
-       for(int i = 0; i < session->drag_assets->size(); i++) {
-               Indexable *indexable = session->drag_assets->get(i);
+       for(int i = 0; i < drag_assets->size(); i++) {
+               Indexable *indexable = drag_assets->get(i);
                remove_indexfile(indexable);
        }
 
 //printf("MWindow::rebuild_indices 1 %s\n", indexable->path);
        if(push_undo) undo->update_undo_before();
        if(drag_assets) edl->remove_from_project(drag_assets);
-       if(drag_clips) edl->remove_from_project(session->drag_clips);
+       if(drag_clips) edl->remove_from_project(drag_clips);
        if(redraw) save_backup();
        if(push_undo) undo->update_undo_after(_("remove assets"), LOAD_ALL);
-       if(redraw)
-       {
+       if(redraw) {
                restart_brender();
 
                gui->lock_window("MWindow::remove_assets_from_project 3");
-               gui->update(1,
-                       1,
-                       1,
-                       1,
-                       0,
-                       1,
-                       0);
+               gui->update(1, 1, 1, 1, 0, 1, 0);
                gui->unlock_window();
 
        // Removes from playback here
@@ -3531,7 +3654,7 @@ int MWindow::select_asset(Asset *asset, int vstream, int astream, int delete_tra
                                        next_edit = edit->next;
                                        if( edit->channel != vstream ||
                                            !edit->asset || !edit->asset->is_asset ||
-                                           *asset != *edit->asset )
+                                           !asset->equivalent(*edit->asset,1,1,edl) )
                                                delete edit;
                                }
                        }
@@ -3542,6 +3665,7 @@ int MWindow::select_asset(Asset *asset, int vstream, int astream, int delete_tra
                        else if( delete_tracks )
                                edl->tracks->delete_track(track);
                }
+               edl->retrack();
                edl->resample(old_framerate, session->frame_rate, TRACK_VIDEO);
        }
        if( !result && asset->audio_data && asset->channels > 0 ) {
@@ -3591,7 +3715,7 @@ int MWindow::select_asset(Asset *asset, int vstream, int astream, int delete_tra
                                        next_edit = edit->next;
                                        if( !((1<<edit->channel) & channel_mask) ||
                                            !edit->asset || !edit->asset->is_asset ||
-                                           *asset != *edit->asset )
+                                           !asset->equivalent(*edit->asset,1,1,edl) )
                                                delete edit;
                                }
                                if( !track->edits->first )