X-Git-Url: https://git.cinelerra-gg.org/git/?p=goodguy%2Fcinelerra.git;a=blobdiff_plain;f=cinelerra-5.1%2Fcinelerra%2Fmwindow.C;h=2918e23e63e59e4035bb86e2b07059ea0536fd2e;hp=e63b7c54a8c629284fe682ad1822aa3831eddf0f;hb=HEAD;hpb=54b918a8b84f666bf32548ebd12b93908061d2a6 diff --git a/cinelerra-5.1/cinelerra/mwindow.C b/cinelerra-5.1/cinelerra/mwindow.C index e63b7c54..1291b992 100644 --- a/cinelerra-5.1/cinelerra/mwindow.C +++ b/cinelerra-5.1/cinelerra/mwindow.C @@ -1,6 +1,7 @@ /* * CINELERRA * Copyright (C) 1997-2014 Adam Williams + * Copyright (C) 2003-2016 Cinelerra CV contributors * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License as published by @@ -283,8 +284,10 @@ MWindow::~MWindow() delete convert_render; convert_render = 0; delete render; render = 0; delete mixers_align; mixers_align = 0; +#ifdef HAVE_COMMERCIALS commit_commercial(); if( commercials && !commercials->remove_user() ) commercials = 0; +#endif close_mixers(); if( speed_edl ) { speed_edl->remove_user(); speed_edl = 0; } // Save defaults for open plugins @@ -556,21 +559,46 @@ void MWindow::get_plugin_path(char *path, const char *plug_dir, const char *fs_p delete [] base_path; } -int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_dir) +/** +* @brief Load plugins according to an index file. +* +* @details Builds an ArrayList of plugin servers only if there is no +* mismatch for file layout version, index identifier, or timestamp of +* the built-in plugins. If OK, add the plugin servers to the global list. +* +* @note If an error is returned the index file needs to be rebuilt, and +* then this function must be called again. +* There are two types of index files, with the same layout internally. +* One called "Cinelerra_plugins" for built-ins, ffmpeg and lv2 . +* The other type "ladspa_plugins.index_id" where index_id is either the +* path or the $CIN_BUILD identifier if the path is from the running +* AppImage itself. If there are multiple ladspa directories in the +* path, there will be multiple index files. +* +* @return -1 if file no open, 0 if OK, 1 if error. +*/ +int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_dir, const char *index_id) { if( !fp ) return -1; + struct stat st; + fstat (fileno(fp), &st); // don't bother if the file has just been created. + if( st.st_size < 4 ) return 1; + // load index fseek(fp, 0, SEEK_SET); int ret = 0; char index_line[BCTEXTLEN]; - int index_version = -1, len = strlen(plugin_dir); + int index_version = -1, len = strlen(index_id); if( !fgets(index_line, BCTEXTLEN, fp) || sscanf(index_line, "%d", &index_version) != 1 || index_version != PLUGIN_FILE_VERSION || !fgets(index_line, BCTEXTLEN, fp) || (int)strlen(index_line)-1 != len || index_line[len] != '\n' || - strncmp(index_line, plugin_dir, len) != 0 ) ret = 1; - + strncmp(index_line, index_id, len) != 0 ) { +// printf("index file mismatch, version %d, index id length %d, expected id %s, file id %s\n", index_version, len, index_id, index_line); + ret = 1; + } + ArrayList plugins; while( !ret && !feof(fp) && fgets(index_line, BCTEXTLEN, fp) ) { if( index_line[0] == ';' ) continue; @@ -579,6 +607,7 @@ int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_di char path[BCTEXTLEN], title[BCTEXTLEN]; int64_t mtime = 0; if( PluginServer::scan_table(index_line, type, path, title, mtime) ) { +// printf("PluginServer::scan_table failed for %s\n", index_line); ret = 1; continue; } PluginServer *server = 0; @@ -589,6 +618,7 @@ int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_di char plugin_path[BCTEXTLEN]; struct stat st; sprintf(plugin_path, "%s/%s", plugin_dir, path); if( stat(plugin_path, &st) || st.st_mtime != mtime ) { +// printf("Plugin %s index time %ld, file time %ld\n", plugin_path, mtime, st.st_mtime); ret = 1; continue; } server = new PluginServer(mwindow, plugin_path, type); @@ -605,6 +635,7 @@ int MWindow::load_plugin_index(MWindow *mwindow, FILE *fp, const char *plugin_di // Create plugin server from index entry server->set_title(title); if( server->read_table(index_line) ) { +// printf("server->read_table failed for title %s, %s\n", title, index_line); ret = 1; continue; } } @@ -644,16 +675,27 @@ int MWindow::check_plugin_index(ArrayList &plugins, return 0; } - +/** +* @brief Load built-in and LV2 plugins as specified in index file, +* rebuild the index file if needed. +* @param[in] mwindow: GUI class pointer, will be NULL for batch +* rendering or renderfarm client. +* @param[in] preferences: Information from cinelerra_rc file. +*/ int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences) { if( !plugindb ) plugindb = new ArrayList; init_ffmpeg(); - char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN]; + char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN], index_id[BCTEXTLEN]; create_defaults_path(index_path, PLUGIN_FILE); char *plugin_dir = FileSystem::basepath(preferences->plugin_dir); strcpy(plugin_path, plugin_dir); delete [] plugin_dir; + // index_id is 2nd line of the index file, normally full plugin path, + // but fixed value if AppImage because the path changes on each run. + // And if the second line does not match on the next run the index is rebuilt. + if( getenv("APPDIR") && getenv("CINGG_BUILD")) strcpy(index_id, getenv("CINGG_BUILD")); + else strcpy(index_id, plugin_path); FILE *fp = fopen(index_path,"a+"); if( !fp ) { fprintf(stderr,_("MWindow::init_plugins: " @@ -663,19 +705,19 @@ int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences) int fd = fileno(fp), ret = -1; if( !flock(fd, LOCK_EX) ) { fseek(fp, 0, SEEK_SET); - ret = load_plugin_index(mwindow, fp, plugin_path); + ret = load_plugin_index(mwindow, fp, plugin_path, index_id); } if( ret > 0 ) { ftruncate(fd, 0); fseek(fp, 0, SEEK_SET); - printf("init plugin index: %s\n", plugin_path); + printf("build plugin index for: %s\n", plugin_path); fprintf(fp, "%d\n", PLUGIN_FILE_VERSION); - fprintf(fp, "%s\n", plugin_path); + fprintf(fp, "%s\n", index_id); init_plugin_index(mwindow, preferences, fp, plugin_path); init_ffmpeg_index(mwindow, preferences, fp); init_lv2_index(mwindow, preferences, fp); fseek(fp, 0, SEEK_SET); - ret = load_plugin_index(mwindow, fp, plugin_path); + ret = load_plugin_index(mwindow, fp, plugin_path, index_id); } if( ret ) { fprintf(stderr,_("MWindow::init_plugins: " @@ -686,26 +728,42 @@ int MWindow::init_plugins(MWindow *mwindow, Preferences *preferences) return ret; } +/** +* @brief Load ladspa plugins as specified in index files, for each ladspa +* directory keep a separate index file. Rebuild index file(s) if needed. +* @param[in] mwindow: GUI class pointer, will be NULL for batch +* rendering or renderfarm client. +* @param[in] preferences: Information from cinelerra_rc file. +*/ int MWindow::init_ladspa_plugins(MWindow *mwindow, Preferences *preferences) { #ifdef HAVE_LADSPA char *path = getenv("LADSPA_PATH"); + char *appdir = getenv("APPDIR"); char ladspa_path[BCTEXTLEN]; - if( !path ) { + if( !path ) { // if no env var, use CinGG's own ladspa dir strncpy(ladspa_path, File::get_ladspa_path(), sizeof(ladspa_path)); path = ladspa_path; } for( int len=0; *path; path+=len ) { char *cp = strchr(path,':'); len = !cp ? strlen(path) : cp-path; - char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN]; + char index_path[BCTEXTLEN], plugin_path[BCTEXTLEN], index_id[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); cp = index_path + strlen(index_path); - for( char *bp=plugin_path; *bp!=0; ++bp ) + // If the first part of the plugin_path matches the APPDIR, we are + // referring to CinGG's ladspa, replace the path by a fixed ID. APPDIR + // only exists if we are running as AppImage (with variable mount points). + if( appdir && strncmp(plugin_path, appdir, strlen(appdir)) == 0 ) + strcpy(index_id, getenv("CINGG_BUILD")); + else strcpy(index_id, plugin_path); + + // Concatenate the path, replacing '/' with '_'. + for( char *bp=index_id; *bp!=0; ++bp ) *cp++ = *bp=='/' ? '_' : *bp; *cp = 0; FILE *fp = fopen(index_path,"a+"); @@ -717,14 +775,17 @@ int MWindow::init_ladspa_plugins(MWindow *mwindow, Preferences *preferences) int fd = fileno(fp), ret = -1; if( !flock(fd, LOCK_EX) ) { fseek(fp, 0, SEEK_SET); - ret = load_plugin_index(mwindow, fp, plugin_path); + ret = load_plugin_index(mwindow, fp, plugin_path, index_id); } if( ret > 0 ) { ftruncate(fd, 0); fseek(fp, 0, SEEK_SET); - init_ladspa_index(mwindow, preferences, fp, plugin_path); + printf("build ladspa plugin index for: %s\n", plugin_path); + fprintf(fp, "%d\n", PLUGIN_FILE_VERSION); + fprintf(fp, "%s\n", index_id); + init_plugin_index(mwindow, preferences, fp, plugin_path); fseek(fp, 0, SEEK_SET); - ret = load_plugin_index(mwindow, fp, plugin_path); + ret = load_plugin_index(mwindow, fp, plugin_path, index_id); } if( ret ) { fprintf(stderr,_("MWindow::init_ladspa_plugins: " @@ -766,7 +827,7 @@ void MWindow::scan_plugin_index(MWindow *mwindow, Preferences *preferences, FILE char fs_path[BCTEXTLEN], path[BCTEXTLEN]; get_plugin_path(fs_path, 0, fs.dir_list[i]->path); get_plugin_path(path, plug_dir, fs_path); - if( fs.is_dir(fs_path) ) { + if( fs.is_dir(fs_path) ) { // recursively scan child directory scan_plugin_index(mwindow, preferences, fp, plug_dir, path, idx); continue; } @@ -2160,6 +2221,13 @@ if(debug) printf("MWindow::load_filenames %d\n", __LINE__); } result = 0; break; } +// File is a list and size of listed files don't match + case FILE_SIZE_DONT_MATCH: { + eprintf(_("File sizes don't match")); + sprintf(string, _("File sizes don't match")); + gui->show_message(string, theme->message_error); + gui->update_default_message(); + break; } case FILE_NOT_FOUND: { eprintf(_("Failed to open %s"), new_asset->path); @@ -4325,7 +4393,7 @@ void MWindow::get_backup_path(char *path, int len) void MWindow::create_timestamped_copy_from_previous_backup(char *previouspath) { - if (previouspath == nullptr) return; + if (previouspath == NULL) return; char backup_path[BCTEXTLEN]; backup_path[0] = 0; time_t now = time(NULL); @@ -5236,7 +5304,7 @@ int MWindow::select_asset(Asset *asset, int vstream, int astream, int delete_tra int channels = 0; for( uint64_t mask=channel_mask; mask!=0; mask>>=1 ) channels += mask & 1; if( channels < 1 ) channels = 1; - if( channels > 6 ) channels = 6; + if( channels > MAXCHANNELS ) channels = MAXCHANNELS; session->audio_tracks = session->audio_channels = channels; int *achannel_positions = preferences->channel_positions[session->audio_channels-1]; @@ -5385,6 +5453,8 @@ ConfirmRefWindow::ConfirmRefWindow(MWindow *mwindow, char *path, { this->mwindow = mwindow; this->path = path; +// *** CONTEXT_HELP *** + context_help_set_keyword("File by Reference"); } ConfirmRefWindow::~ConfirmRefWindow()