olaf neophyte and de.po updates, valgrind tweaks, delete green lady, inkscape dpi=96
[goodguy/history.git] / cinelerra-5.1 / cinelerra / pluginserver.C
index 2935ce9dfa6a81f263b8e0f7ef0537599037dd4d..6e42e947a4a10b3d51e5acc34ab54f4ed78e52b6 100644 (file)
@@ -2,21 +2,21 @@
 /*
  * CINELERRA
  * Copyright (C) 2009 Adam Williams <broadcast at earthling dot net>
- * 
+ *
  * 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
  * the Free Software Foundation; either version 2 of the License, or
  * (at your option) any later version.
- * 
+ *
  * This program is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
- * 
+ *
  * You should have received a copy of the GNU General Public License
  * along with this program; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- * 
+ *
  */
 
 #include "amodule.h"
@@ -79,6 +79,7 @@ void PluginServer::init()
        plugin_obj = new PluginObj();
        modules = new ArrayList<Module*>;
        nodes = new ArrayList<VirtualNode*>;
+       tip = 0;
 }
 
 PluginServer::PluginServer()
@@ -86,7 +87,7 @@ PluginServer::PluginServer()
        init();
 }
 
-PluginServer::PluginServer(MWindow *mwindow, char *path, int type)
+PluginServer::PluginServer(MWindow *mwindow, const char *path, int type)
 {
        char fpath[BCTEXTLEN];
        init();
@@ -97,7 +98,7 @@ PluginServer::PluginServer(MWindow *mwindow, char *path, int type)
                sprintf(fpath, "ff_%s", path);
                path = fpath;
        }
-        set_path(path);
+       set_path(path);
 }
 
 PluginServer::PluginServer(PluginServer &that)
@@ -107,12 +108,13 @@ PluginServer::PluginServer(PluginServer &that)
        plugin_obj = that.plugin_obj;
        plugin_obj->add_user();
        title = !that.title ? 0 : cstrdup(that.title);
+       tip = !that.tip ? 0 : cstrdup(that.tip);
        path = !that.path ? 0 : cstrdup(that.path);
        ff_name = !that.ff_name ? 0 : cstrdup(that.ff_name);
        modules = new ArrayList<Module*>;
        nodes = new ArrayList<VirtualNode*>;
 
-       attachment = that.attachment;   
+       attachment = that.attachment;
        realtime = that.realtime;
        multichannel = that.multichannel;
        preferences = that.preferences;
@@ -137,6 +139,7 @@ PluginServer::~PluginServer()
        delete [] path;
        delete [] ff_name;
        delete [] title;
+       delete [] tip;
        delete modules;
        delete nodes;
        delete picon;
@@ -150,30 +153,42 @@ int PluginServer::reset_parameters()
        keyframe = 0;
        prompt = 0;
        cleanup_plugin();
-       autos = 0;
-       edl = 0;
-       preferences = 0;
-       title = 0;
-       path = 0;
+
+       plugin_obj = 0;
+       client = 0; 
+       new_plugin = 0;
+       lad_index = -1;
+       lad_descriptor_function = 0;
+       lad_descriptor = 0;
        ff_name = 0;
-       audio = video = theme = 0;
-       fileio = 0;
-       uses_gui = 0;
+       use_opengl = 0;
+       vdevice = 0;
+       plugin_type = 0;
+       start_auto = end_auto = 0;
+       autos = 0;
+       reverse = 0;
+       plugin_open = 0;
        realtime = multichannel = fileio = 0;
        synthesis = 0;
-       start_auto = end_auto = 0;
+       audio = video = theme = 0;
+       uses_gui = 0;
        transition = 0;
-       new_plugin = 0;
-       client = 0;
-       use_opengl = 0;
-       vdevice = 0;
+       title = 0;
+       tip = 0;
+       path = 0;
+       data_text = 0;
+       for( int i=sizeof(args)/sizeof(args[0]); --i>=0; ) args[i] = 0;
+       total_args = 0; 
+       dir_idx = 0;
        modules = 0;
        nodes = 0;
+       attachmentpoint = 0;
+       edl = 0;
+       preferences = 0;
+       prompt = 0;
+       temp_frame = 0;
        picon = 0;
 
-       lad_index = -1;
-       lad_descriptor_function = 0;
-       lad_descriptor = 0;
        return 0;
 }
 
@@ -223,6 +238,21 @@ int PluginServer::get_lad_index()
        return this->lad_index;
 }
 
+int PluginServer::is_unknown()
+{
+       return plugin_type == PLUGIN_TYPE_UNKNOWN ? 1 : 0;
+}
+
+int PluginServer::is_executable()
+{
+       return  plugin_type == PLUGIN_TYPE_EXECUTABLE ? 1 : 0;
+}
+
+int PluginServer::is_builtin()
+{
+       return plugin_type == PLUGIN_TYPE_BUILTIN ? 1 : 0;
+}
+
 int PluginServer::is_ladspa()
 {
        return plugin_type == PLUGIN_TYPE_LADSPA ? 1 : 0;
@@ -233,6 +263,11 @@ int PluginServer::is_ffmpeg()
        return plugin_type == PLUGIN_TYPE_FFMPEG ? 1 : 0;
 }
 
+int PluginServer::is_lv2()
+{
+       return plugin_type == PLUGIN_TYPE_LV2 ? 1 : 0;
+}
+
 void PluginServer::set_path(const char *path)
 {
        delete [] this->path;
@@ -252,7 +287,7 @@ int PluginServer::get_synthesis()
 
 void PluginServer::set_title(const char *string)
 {
-       if(title) delete [] title;
+       delete [] title;
        title = cstrdup(string);
 }
 
@@ -264,7 +299,7 @@ void PluginServer::generate_display_title(char *string)
        else
                BC_Resources::encode(BC_Resources::encoding, 0,
                                _(title),strlen(title)+1, ltitle,BCTEXTLEN);
-       if(plugin && plugin->track) 
+       if(plugin && plugin->track)
                sprintf(string, "%s: %s", plugin->track->title, ltitle);
        else
                strcpy(string, ltitle);
@@ -303,9 +338,9 @@ void *PluginServer::get_sym(const char *sym)
 }
 
 // Open plugin for signal processing
-int PluginServer::open_plugin(int master, 
+int PluginServer::open_plugin(int master,
        Preferences *preferences,
-       EDL *edl, 
+       EDL *edl,
        Plugin *plugin)
 {
        if(plugin_open) return 0;
@@ -313,20 +348,20 @@ int PluginServer::open_plugin(int master,
        this->preferences = preferences;
        this->plugin = plugin;
        this->edl = edl;
-       if( plugin_type != PLUGIN_TYPE_FFMPEG && plugin_type != PLUGIN_TYPE_EXECUTABLE && !load_obj() ) {
-// If the load failed, can't use error to detect executable
-//  because locale and language selection change the load_error()
+       if( !is_ffmpeg() && !is_lv2() && !is_executable() && !load_obj() ) {
+// If the load failed, can't use error string to detect executable
+//  because locale and language selection changes the load_error() message
 //     if( !strstr(string, "executable") ) { set_title(path); plugin_type = PLUGIN_TYPE_EXECUTABLE; }
                eprintf("PluginServer::open_plugin: load_obj %s = %s\n", path, load_error());
                return PLUGINSERVER_NOT_RECOGNIZED;
        }
-       if( plugin_type == PLUGIN_TYPE_UNKNOWN || plugin_type == PLUGIN_TYPE_BUILTIN ) {
+       if( is_unknown() || is_builtin() ) {
                new_plugin =
                        (PluginClient* (*)(PluginServer*)) get_sym("new_plugin");
                if( new_plugin )
                        plugin_type = PLUGIN_TYPE_BUILTIN;
        }
-       if( plugin_type == PLUGIN_TYPE_UNKNOWN || plugin_type == PLUGIN_TYPE_LADSPA ) {
+       if( is_unknown() || is_ladspa() ) {
                lad_descriptor_function =
                        (LADSPA_Descriptor_Function) get_sym("ladspa_descriptor");
                if( lad_descriptor_function ) {
@@ -337,7 +372,7 @@ int PluginServer::open_plugin(int master,
                        plugin_type = PLUGIN_TYPE_LADSPA;
                }
        }
-       if( plugin_type == PLUGIN_TYPE_UNKNOWN ) {
+       if( is_unknown() ) {
                fprintf(stderr, "PluginServer::open_plugin "
                        " %d: plugin undefined in %s\n", __LINE__, path);
                return PLUGINSERVER_NOT_RECOGNIZED;
@@ -348,11 +383,14 @@ int PluginServer::open_plugin(int master,
        case PLUGIN_TYPE_BUILTIN:
                client = new_plugin(this);
                break;
+       case PLUGIN_TYPE_FFMPEG:
+               client = new_ffmpeg_plugin();
+               break;
        case PLUGIN_TYPE_LADSPA:
                client = new PluginAClientLAD(this);
                break;
-       case PLUGIN_TYPE_FFMPEG:
-               client = new_ffmpeg_plugin();
+       case PLUGIN_TYPE_LV2:
+               client = new_lv2_plugin();
                break;
        default:
                client = 0;
@@ -360,7 +398,7 @@ int PluginServer::open_plugin(int master,
        }
        if( !client )
                return PLUGINSERVER_NOT_RECOGNIZED;
-       
+
 // Run initialization functions
        realtime = client->is_realtime();
 // Don't load defaults when probing the directory.
@@ -449,7 +487,7 @@ int PluginServer::read_table(char *text)
 }
 
 int PluginServer::init_realtime(int realtime_sched,
-               int total_in_buffers, 
+               int total_in_buffers,
                int buffer_size)
 {
 
@@ -459,8 +497,8 @@ int PluginServer::init_realtime(int realtime_sched,
 // initialize plugin
 // Call start_realtime
        this->total_in_buffers = this->total_out_buffers = total_in_buffers;
-       client->plugin_init_realtime(realtime_sched, 
-               total_in_buffers, 
+       client->plugin_init_realtime(realtime_sched,
+               total_in_buffers,
                buffer_size);
 
        return 0;
@@ -468,8 +506,8 @@ int PluginServer::init_realtime(int realtime_sched,
 
 
 // Replaced by pull method but still needed for transitions
-void PluginServer::process_transition(VFrame *input, 
-               VFrame *output, 
+void PluginServer::process_transition(VFrame *input,
+               VFrame *output,
                int64_t current_position,
                int64_t total_len)
 {
@@ -493,9 +531,9 @@ void PluginServer::process_transition(VFrame *input,
        use_opengl = 0;
 }
 
-void PluginServer::process_transition(Samples *input, 
+void PluginServer::process_transition(Samples *input,
                Samples *output,
-               int64_t current_position, 
+               int64_t current_position,
                int64_t fragment_size,
                int64_t total_len)
 {
@@ -506,12 +544,12 @@ void PluginServer::process_transition(Samples *input,
        aclient->total_len = total_len;
        aclient->source_start = 0;
        aclient->process_realtime(fragment_size,
-               input, 
+               input,
                output);
 }
 
 
-void PluginServer::process_buffer(VFrame **frame, 
+void PluginServer::process_buffer(VFrame **frame,
        int64_t current_position,
        double frame_rate,
        int64_t total_len,
@@ -530,10 +568,10 @@ void PluginServer::process_buffer(VFrame **frame,
                vclient->input[i] = frame[i];
                vclient->output[i] = frame[i];
        }
-       
+
        if(plugin)
        {
-               vclient->source_start = (int64_t)plugin->startproject * 
+               vclient->source_start = (int64_t)plugin->startproject *
                        frame_rate /
                        vclient->project_frame_rate;
        }
@@ -579,7 +617,7 @@ void PluginServer::process_buffer(Samples **buffer,
        aclient->sample_rate = sample_rate;
 
        if(plugin)
-               aclient->source_start = plugin->startproject * 
+               aclient->source_start = plugin->startproject *
                        sample_rate /
                        aclient->project_sample_rate;
 
@@ -587,16 +625,16 @@ void PluginServer::process_buffer(Samples **buffer,
        aclient->begin_process_buffer();
        if(multichannel)
        {
-               aclient->process_buffer(fragment_size, 
-                       buffer, 
-                       current_position, 
+               aclient->process_buffer(fragment_size,
+                       buffer,
+                       current_position,
                        sample_rate);
        }
        else
        {
-               aclient->process_buffer(fragment_size, 
-                       buffer[0], 
-                       current_position, 
+               aclient->process_buffer(fragment_size,
+                       buffer[0],
+                       current_position,
                        sample_rate);
        }
        aclient->end_process_buffer();
@@ -656,7 +694,7 @@ int64_t PluginServer::get_written_frames()
 
 // ======================= Non-realtime plugin
 
-int PluginServer::get_parameters(int64_t start, int64_t end, int channels)      
+int PluginServer::get_parameters(int64_t start, int64_t end, int channels)
 {
        if(!plugin_open) return 0;
 
@@ -722,9 +760,9 @@ int PluginServer::process_loop(Samples **buffers, int64_t &write_length)
 }
 
 
-int PluginServer::start_loop(int64_t start, 
-       int64_t end, 
-       int64_t buffer_size, 
+int PluginServer::start_loop(int64_t start,
+       int64_t end,
+       int64_t buffer_size,
        int total_buffers)
 {
        if(!plugin_open) return 0;
@@ -738,8 +776,8 @@ int PluginServer::stop_loop()
        return client->plugin_stop_loop();
 }
 
-int PluginServer::read_frame(VFrame *buffer, 
-       int channel, 
+int PluginServer::read_frame(VFrame *buffer,
+       int channel,
        int64_t start_position)
 {
        ((VModule*)modules->values[channel])->render(buffer,
@@ -783,13 +821,13 @@ int PluginServer::read_samples(Samples *buffer,
 }
 
 
-int PluginServer::read_samples(Samples *buffer, 
-       int channel, 
+int PluginServer::read_samples(Samples *buffer,
+       int channel,
        int64_t start_position,
        int64_t size)
 {
 // total_samples is now set in buffer
-       ((AModule*)modules->values[channel])->render(buffer, 
+       ((AModule*)modules->values[channel])->render(buffer,
                size,
                start_position,
                PLAY_FORWARD,
@@ -798,9 +836,9 @@ int PluginServer::read_samples(Samples *buffer,
        return 0;
 }
 
-int PluginServer::read_frame(VFrame *buffer, 
-       int channel, 
-       int64_t start_position, 
+int PluginServer::read_frame(VFrame *buffer,
+       int channel,
+       int64_t start_position,
        double frame_rate,
        int use_opengl)
 {
@@ -896,14 +934,14 @@ void PluginServer::show_gui()
        if(video)
        {
                client->source_position = Units::to_int64(
-                       mwindow->edl->local_session->get_selectionstart(1) * 
+                       mwindow->edl->local_session->get_selectionstart(1) *
                                mwindow->edl->session->frame_rate);
        }
        else
        if(audio)
        {
                client->source_position = Units::to_int64(
-                       mwindow->edl->local_session->get_selectionstart(1) * 
+                       mwindow->edl->local_session->get_selectionstart(1) *
                                mwindow->edl->session->sample_rate);
        }
 
@@ -928,14 +966,14 @@ void PluginServer::update_gui()
        if(video)
        {
                client->source_position = Units::to_int64(
-                       mwindow->edl->local_session->get_selectionstart(1) * 
+                       mwindow->edl->local_session->get_selectionstart(1) *
                                mwindow->edl->session->frame_rate);
        }
        else
        if(audio)
        {
                client->source_position = Units::to_int64(
-                       mwindow->edl->local_session->get_selectionstart(1) * 
+                       mwindow->edl->local_session->get_selectionstart(1) *
                                mwindow->edl->session->sample_rate);
        }
 
@@ -945,7 +983,7 @@ void PluginServer::update_gui()
 void PluginServer::update_title()
 {
        if(!plugin_open) return;
-       
+
        client->update_display_title();
 }
 
@@ -1030,7 +1068,7 @@ double PluginServer::get_framerate()
        else
        if(mwindow)
                return mwindow->edl->session->frame_rate;
-       else 
+       else
        {
                printf("PluginServer::get_framerate video and mwindow == NULL\n");
                return 1;
@@ -1078,7 +1116,7 @@ int PluginServer::detach_buffers()
        offset_in_render.remove_all();
        double_buffer_in_render.remove_all();
        realtime_in_size.remove_all();
-       
+
        out_buffer_size = 0;
        shared_buffers = 0;
        total_out_buffers = 0;
@@ -1087,8 +1125,8 @@ int PluginServer::detach_buffers()
        return 0;
 }
 
-int PluginServer::arm_buffer(int buffer_number, 
-               int64_t offset_in, 
+int PluginServer::arm_buffer(int buffer_number,
+               int64_t offset_in,
                int64_t offset_out,
                int double_buffer_in,
                int double_buffer_out)
@@ -1203,67 +1241,43 @@ Theme* PluginServer::get_theme()
 }
 
 
-int PluginServer::get_theme_png_path(char *png_path, const char *theme_dir)
+void PluginServer::get_plugin_png_name(char *png_name)
 {
-       char *bp = strrchr(path, '/');
-       if( !bp ) bp = path; else ++bp;
-       char *sp = strrchr(bp,'.');
-       if( !sp || ( strcmp(sp, ".plugin") && strcmp(sp,".so") ) ) return 0;
-       char *cp = png_path, *dp = bp;
-       cp += sprintf(cp,"%s/%s/", mwindow->preferences->plugin_dir, theme_dir);
-       while( dp < sp ) *cp++ = *dp++;
-       strcpy(cp, ".png");
-       struct stat st;
-       if( stat(png_path, &st) ) return 0;
-       if( !S_ISREG(st.st_mode) ) return 0;
-       if( st.st_size == 0 ) return 0;
-       return st.st_size;
+       char *pp = png_name, *ep = pp + BCSTRLEN-1;
+       char *cp = strrchr(path, '/');
+       cp = !cp ? path : cp+1;
+       char *sp = strrchr(cp, '.');
+       if( !sp ) sp = cp+strlen(cp);
+       while( pp < ep && cp < sp ) *pp++ = *cp++;
+       snprintf(pp, ep-pp, ".png");
 }
 
-int PluginServer::get_theme_png_path(char *png_path, Theme *theme)
+int PluginServer::get_plugin_png_path(char *png_path, const char *plugin_icons)
 {
-       char *bp = strrchr(theme->path, '/');
-       if( !bp ) bp = theme->path; else ++bp;
-       char *sp = strrchr(bp,'.');
-       if( !sp || ( strcmp(sp, ".plugin") && strcmp(sp,".so") ) ) return 0;
-       char theme_dir[BCTEXTLEN], *cp = theme_dir;
-       while( bp < sp ) *cp++ = *bp++;
-       *cp = 0;
-       return get_theme_png_path(png_path, theme_dir);
+       char png_name[BCSTRLEN];
+       get_plugin_png_name(png_name);
+       char *pp = png_path, *ep = pp + BCTEXTLEN-1;
+       pp += snprintf(pp, ep-pp, "%s/picon/%s/%s",
+               File::get_plugin_path(), plugin_icons, png_name);
+       return access(png_path,R_OK) ? 1 : 0;
 }
 
 int PluginServer::get_plugin_png_path(char *png_path)
 {
-       int len = get_theme_png_path(png_path, mwindow->theme);
-       if( !len )
-               len = get_theme_png_path(png_path, "picon");
-       return len;
+       int ret = get_plugin_png_path(png_path, mwindow->preferences->plugin_icons);
+       if( ret ) ret = get_plugin_png_path(png_path, DEFAULT_PICON);
+       return ret;
 }
 
 VFrame *PluginServer::get_plugin_images()
 {
        char png_path[BCTEXTLEN];
-       int len = get_plugin_png_path(png_path);
-       if( !len ) return 0;
-       int ret = 0, w = 0, h = 0;
-       unsigned char *bfr = 0;
-       int fd = ::open(png_path, O_RDONLY);
-       if( fd < 0 ) ret = 1;
-       if( !ret ) {
-               bfr = (unsigned char *) ::mmap (NULL, len, PROT_READ, MAP_SHARED, fd, 0); 
-               if( bfr == MAP_FAILED ) ret = 1;
-       }
-       VFrame *vframe = 0;
-       if( !ret ) {
-               double scale = BC_WindowBase::get_resources()->icon_scale;
-               vframe = new VFramePng(bfr, len, scale, scale);
-               if( (w=vframe->get_w()) <= 0 || (h=vframe->get_h()) <= 0 ||
-                   vframe->get_data() == 0 ) ret = 1;
-       }
-       if( bfr && bfr != MAP_FAILED ) ::munmap(bfr, len);
-       if( fd >= 0 ) ::close(fd);
-       if( ret ) { delete vframe;  vframe = 0; }
-       return vframe;
+       if( !get_plugin_png_path(png_path) )
+               return VFramePng::vframe_png(png_path,0,0);
+       char png_name[BCSTRLEN];
+       get_plugin_png_name(png_name);
+       unsigned char *data = mwindow->theme->get_image_data(png_name, 0);
+       return data ? new VFramePng(data, 0.) : 0;
 }
 
 VFrame *PluginServer::get_picon()
@@ -1291,6 +1305,6 @@ void PluginServer::sync_parameters()
 
 void PluginServer::dump(FILE *fp)
 {
-       fprintf(fp,"    PluginServer %d %p %s %s %d\n", 
+       fprintf(fp,"    PluginServer %d %p %s %s %d\n",
                __LINE__, this, path, title, realtime);
 }