Adding support for Steve's cool liblrdf - Alex
authorterminatorX <>
Sat, 22 Mar 2003 23:15:36 +0000 (23:15 +0000)
committerterminatorX <>
Sat, 22 Mar 2003 23:15:36 +0000 (23:15 +0000)
configure.in
src/Makefile.am
src/main.cc
src/tX_global.c
src/tX_global.h
src/tX_ladspa.cc
src/tX_ladspa_class.cc [new file with mode: 0644]
src/tX_ladspa_class.h [new file with mode: 0644]
src/tX_midiin.cc
src/tX_seqpar.cc
src/tX_vttgui.cc

index 21dda23145d1485ccf305a699eb1f250191767dd..136c87b4799edee2b3833f22f7073bfe6802226a 100644 (file)
@@ -24,6 +24,7 @@ AC_ARG_ENABLE(vorbis, [  --disable-vorbis        disable libvorbis support (defa
 AC_ARG_ENABLE(audiofile,       [  --disable-audiofile     disable audiofile support (default=auto) ])
 AC_ARG_ENABLE(legacy,          [  --disable-legacy        disable support for old terminatorX files (default=on) ])
 AC_ARG_ENABLE(alsamidi,                [  --disable-alsamidi      disable support  ALSA MIDI in (default=auto) ])
+AC_ARG_ENABLE(lrdf,                    [  --disable-lrdf          disable support for liblrdf (default=auto) ])
 
 dnl Checks for programs.
 AC_PROG_AWK
@@ -44,6 +45,7 @@ OPTION_GNOME="no"
 OPTION_SCHEDULER="no"
 OPTION_ALSAMIDI="no"
 OPTION_LEGACY="no"
+OPTION_LRDF="no"
 
 dnl Checks for libraries.
 AC_CHECK_LIB(m, floor,, AC_MSG_ERROR([** math-lib not installed or broken **]))
@@ -471,6 +473,27 @@ else
        inst_pref="\\\"/usr/local/share\\\""
 fi
 
+if test "$enable_lrdf" != "no"; then
+    AC_MSG_CHECKING(for liblrdf >= 0.2.4)
+       LRDF_VERS=`$PKG_CONFIG --modversion lrdf | sed -e "s/libxml //" | awk 'BEGIN {FS=".";} { printf "%d", ($1 * 1000 + $2) * 1000 + $3;}'`
+       if test "$LRDF_VERS" -ge 2004; then
+               AC_MSG_RESULT(yes)
+               OPTION_LRDF=yes
+
+               lrdf_cflags=`$PKG_CONFIG --cflags lrdf`
+               if test "$lrdf_cflags" != ""; then
+                       CFLAGS="$CFLAGS $lrdf_cflags"
+               fi
+               lrdf_libs=`$PKG_CONFIG --libs lrdf`
+               LIBS="$LIBS $lrdf_libs"
+               AC_DEFINE_UNQUOTED([USE_LRDF], 1, [Define to compile librdf support])
+               OPTION_AUDIOFILE="yes"
+       else
+               AC_MSG_RESULT(no)
+       fi
+
+fi
+
 dnl Scrollkeeper
 AC_PATH_PROG(SK_CONFIG,scrollkeeper-config,no)
 if test x$SK_CONFIG = xno; then
@@ -550,6 +573,9 @@ option_info;
 option="ALSA (MIDI in)"; option_val=$OPTION_ALSAMIDI; option_url=http://www.alsa-project.org
 option_info;
 
+option=lrdf; option_val=$OPTION_LRDF; option_url=http://plugin.org.uk/releases/lrdf/
+option_info;
+
 echo "legacy files supprt: $OPTION_LEGACY"
 echo "builtin-wav support: $OPTION_WAV"
 echo "enhanced scheduling support: $OPTION_SCHEDULER"
index 45657f5ff262acf3d0766b4d04a1641b50ab58b5..c0fb6742cc0c696ea8ddd0c7c6cf2486e9e5fb49 100644 (file)
@@ -38,4 +38,4 @@ terminatorX_SOURCES = tX_endian.c tX_dialog.cc tX_widget.c wav_write.c \
                        tX_midiin.h tX_midiin.cc tX_glade_interface.cc \
                        tX_glade_interface.h tX_glade_callbacks.cc \
                        tX_glade_callbacks.h tX_glade_support.cc \
-                       tX_glade_support.h
+                       tX_glade_support.h tX_ladspa_class.h tX_ladspa_class.cc
index 33f5878cf34864259fa34305a9bf7a55fb2a445f..6adb227e3e30a1c7df58d6608b05da0af22c50e4 100644 (file)
@@ -63,7 +63,7 @@
 #include <glib.h>
 
 #include "tX_ladspa.h"
-
+#include "tX_ladspa_class.h"
 #include "tX_engine.h"
 
 #ifdef CREATE_BENCHMARK 
@@ -389,9 +389,11 @@ int main(int argc, char **argv)
                idle_tag=gtk_idle_add((GtkFunction)idle, NULL);
        }
        
+       LADSPA_Class :: init();
        LADSPA_Plugin :: init();
 //     LADSPA_Plugin :: status();
-                       
+//     LADSPA_Class :: dump();
+       
        create_mastergui(globals.width, globals.height);
                
        if (!globals.show_nag)  display_mastergui();
index 49b2272445a08d55f6fb6a07df108aa5d3ab3284..b0ab2f44f7f334630360fae037b5539a21fca360 100644 (file)
@@ -126,6 +126,8 @@ void set_global_defaults() {
        globals.current_path = NULL;
        globals.pitch=1.0;
        globals.volume=1.0;
+       
+       strcpy(globals.lrdf_path, "/usr/share/ladspa/rdf:/usr/local/share/ladspa/rdf");
        globals.fullscreen_enabled=1;
        
        if (!globals.true_block_size) globals.true_block_size=1<globals.oss_buff_size;
@@ -201,6 +203,8 @@ int load_globals_xml() {
                        restore_string("tables_filename", globals.tables_filename);
                        restore_string("record_filename", globals.record_filename);
                        restore_string("file_editor", globals.file_editor);
+                       restore_string("lrdf_path", globals.lrdf_path);
+                       
                        restore_int("fullscreen_enabled", globals.fullscreen_enabled);
 
                        if (!elementFound) {
@@ -283,6 +287,7 @@ void store_globals() {
                store_string("tables_filename", globals.tables_filename);
                store_string("record_filename", globals.record_filename);
                store_string("file_editor", globals.file_editor);
+               store_string("lrdf_path", globals.lrdf_path);
                store_int("fullscreen_enabled", globals.fullscreen_enabled);
                
                fprintf(rc,"</terminatorXrc>\n");
index bccd8e198c185106bf896264a34aab6e37f5ebec..a611ca6759587bfe103c1dc9a9b6e350ef4b16bc 100644 (file)
@@ -131,6 +131,8 @@ typedef struct {
        int alsa_buff_size; // In Samples
        int alsa_samplerate;
        
+       char lrdf_path[PATH_MAX];
+       
        int fullscreen_enabled;
 } tx_global;
 
index c533cd18dd0818b1c2d0202afa0c8d2d6e518387..048aa2b50b4b2c40bc93e48dcdc5246873b2f7d5 100644 (file)
 */
 
 #include <tX_ladspa.h>
+#include <tX_ladspa_class.h>
 #include <dirent.h>
 #include <dlfcn.h>
 #include <stdio.h>
 #include <stdlib.h>
 #include <string.h>
 
-list <LADSPA_Plugin *> LADSPA_Plugin :: plugin_list;
+std::list <LADSPA_Plugin *> LADSPA_Plugin :: plugin_list;
 
 void LADSPA_Plugin :: init ()
 {
@@ -39,14 +40,11 @@ void LADSPA_Plugin :: init ()
        char ladspa_path[PATH_MAX];
        char *start, *end, *buffer;
 
-       printf("tX: Looking for LADSPA plugins.\n");
-       
        /* Finding the LADSPA Path */
        ladspa_path_ptr=getenv("LADSPA_PATH");
        
-       if (!ladspa_path_ptr) 
-       {
-               fprintf(stderr, "tX: Warning: LADSPA_PATH not set. Trying /usr/lib/ladspa:/usr/local/lib/ladspa.\n");
+       if (!ladspa_path_ptr)  {
+               tX_warning("LADSPA_PATH not set. Trying /usr/lib/ladspa:/usr/local/lib/ladspa");
                strcpy(ladspa_path, "/usr/lib/ladspa:/usr/local/lib/ladspa");
        }
        else strcpy(ladspa_path, ladspa_path_ptr);
@@ -84,9 +82,8 @@ void LADSPA_Plugin :: handlelib(void *lib, LADSPA_Descriptor_Function desc_func,
        
        for (i=0; (descriptor = desc_func(i)) != NULL; i++)
        {               
-               if (LADSPA_IS_INPLACE_BROKEN(descriptor->Properties))
-               {
-                       fprintf(stderr, "tX: Plugin \"%s\" disabled. No in-place processing support.\n", descriptor->Name);
+               if (LADSPA_IS_INPLACE_BROKEN(descriptor->Properties)) {
+                       tX_warning("Plugin \"%s\" disabled. No in-place processing support.", descriptor->Name);
                }
                else
                {               
@@ -104,12 +101,10 @@ void LADSPA_Plugin :: handlelib(void *lib, LADSPA_Descriptor_Function desc_func,
                                if (LADSPA_IS_PORT_CONTROL(descriptor->PortDescriptors[port]) && LADSPA_IS_PORT_INPUT(descriptor->PortDescriptors[port])) in_ctrl++;                    
                        }
                        
-                       if ((in_audio == 1) && (out_audio == 1))
-                       {
-                               printf("tX: Plugin \"%s\" loaded.\n", descriptor->Name);
+                       if ((in_audio == 1) && (out_audio == 1)) {
                                new LADSPA_Plugin(descriptor, filename);
                        }
-                       else fprintf(stderr, "tX: Plugin \"%s\" disabled. Not a 1-in/1-out plugin.\n", descriptor->Name);
+                       else { tX_warning("Plugin \"%s\" disabled. Not a 1-in/1-out plugin.", descriptor->Name); }
                }
        }
 }
@@ -123,16 +118,14 @@ void LADSPA_Plugin :: scandir(char *dirname)
        char *filename;
        void *handle;
        LADSPA_Descriptor_Function desc_func;
-
-       printf("tX: Scanning %s for LADSPA plugins.\n", dirname);
        
-       if (!dirlen) { fprintf(stderr, "tX: Error: empty directory name?\n"); return; };
+       if (!dirlen) { tX_error("tX: Error: empty directory name?"); return; };
 
        if (dirname[dirlen - 1] != '/') needslash=1;
        
        dir = opendir(dirname);
        
-       if (!dir) { fprintf(stderr, "tX: Error: couldn't access directory.\n"); return; };
+       if (!dir) { tX_error("tX: Error: couldn't access directory \"%s\".", dirname); return; };
        
        while (1)
        {
@@ -156,14 +149,10 @@ void LADSPA_Plugin :: scandir(char *dirname)
                        /* check wether this is a LADSPA lib */
                        desc_func = (LADSPA_Descriptor_Function) dlsym(handle, "ladspa_descriptor");
                        
-                       if (dlerror() == NULL && desc_func)
-                       {
-                               printf("tX: Analyzing LADSPA plugin library %s.\n", filename);
+                       if (dlerror() == NULL && desc_func) {
                                LADSPA_Plugin :: handlelib(handle, desc_func, entry->d_name);
-                       }
-                       else
-                       {
-                               fprintf(stderr, "tX: Error: %s is not a LADSPA plugin library.", filename);
+                       } else {
+                               tX_error("tX: Error: %s is not a LADSPA plugin library.", filename);
                                dlclose(handle);
                        }
                }
@@ -180,7 +169,7 @@ void LADSPA_Plugin :: status ()
 
 void LADSPA_Plugin :: debug_display()
 {
-       list <LADSPA_Plugin *> :: iterator plugin;
+       std::list <LADSPA_Plugin *> :: iterator plugin;
        
        for (plugin=plugin_list.begin(); plugin != plugin_list.end(); plugin++)
        {
@@ -194,11 +183,12 @@ LADSPA_Plugin :: LADSPA_Plugin (const LADSPA_Descriptor *ld, char *filename)
        plugin_list.push_back(this);
        strcpy(file, filename);
        sprintf (info_string, "   LADSPA-Plugin: %s   \n   Label: %s   \n   File: %s   \n   Unique ID: %li   \n   Maker: %s   \n   Copyright: %s   ", ld->Name, ld->Label, file, ld->UniqueID, ld->Maker, ld->Copyright);
+       LADSPA_Class::add_plugin(this);
 }
 
 LADSPA_Plugin * LADSPA_Plugin :: getPluginByIndex(int i)
 {
-       list <LADSPA_Plugin *> :: iterator plugin;
+       std::list <LADSPA_Plugin *> :: iterator plugin;
        int p;
        
        plugin = plugin_list.begin();
@@ -211,7 +201,7 @@ LADSPA_Plugin * LADSPA_Plugin :: getPluginByIndex(int i)
 
 LADSPA_Plugin * LADSPA_Plugin :: getPluginByUniqueID(long ID)
 {
-       list <LADSPA_Plugin *> :: iterator plugin;
+       std::list <LADSPA_Plugin *> :: iterator plugin;
        
        for (plugin=plugin_list.begin(); plugin != plugin_list.end(); plugin++)
        {
diff --git a/src/tX_ladspa_class.cc b/src/tX_ladspa_class.cc
new file mode 100644 (file)
index 0000000..9601ef7
--- /dev/null
@@ -0,0 +1,331 @@
+/*
+    terminatorX - realtime audio scratching software
+    Copyright (C) 1999-2003  Alexander König
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+    File: tX_ladspa_class.cc
+*/
+
+#include "tX_ladspa_class.h"
+#include "tX_global.h"
+#include <dirent.h>
+#include <dlfcn.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifdef USE_LRDF
+#include <lrdf.h>
+#endif
+
+LADSPA_Class * LADSPA_Class::root=NULL;
+LADSPA_Class * LADSPA_Class::unclassified=NULL;
+std::list <char *> LADSPA_Class::rdf_files;
+vtt_class *LADSPA_Class::current_vtt;
+
+/* Why do have to code this myself? */
+static int compare(const char *a, const char *b) {
+       int lena, lenb, i;
+
+       if (!a && !b) return 0;
+       if (!a) return 2;
+       if (!b) return 1;
+       
+       lena=strlen(a);
+       lenb=strlen(b);
+       
+       for (i=0; (i<lena) && (i<lenb); i++) {
+               if (a[i]>b[i]) {
+                       return 2;
+               } else if (a[i]<b[i]) {
+                       return 1;
+               }
+       }
+       
+       if (lena>lenb) return 1;
+       else if (lenb>lena) return 2;
+       return 0;
+}
+
+void LADSPA_Class::init() {
+       char *start, *end, *buffer;
+
+#ifdef USE_LRDF
+       /* Scanning every dir in path */
+       start = globals.lrdf_path;
+       
+       while (*start != '\0') {
+               end = start;
+               while (*end != ':' && *end != '\0') end++;
+    
+               buffer = (char *) malloc(1 + end - start);
+               if (end > start) strncpy(buffer, start, end - start);
+                       
+               buffer[end - start] = '\0';
+               LADSPA_Class::scandir(buffer);
+               free (buffer); 
+    
+       start = end;
+       if (*start == ':') start++;
+       }
+       
+       if (rdf_files.size() > 0) {
+               char *uris[rdf_files.size()+1];
+               std::list <char *> :: iterator i;
+               int t;
+               
+               for (i=rdf_files.begin(), t=0; i!=rdf_files.end(); i++, t++) {
+                       uris[t]=(*i);
+               }
+               uris[t]=NULL;
+               
+               lrdf_init();
+       
+               if (lrdf_read_files((const char **) uris)) {
+                       tX_error("liblrdf had problems reading the rdf files");
+        }
+#endif
+               root=new LADSPA_Class("http://ladspa.org/ontology#Plugin");
+#ifdef USE_LRDF                
+               lrdf_cleanup();
+       } else {
+               tX_error("No RDF files found");
+       }
+#endif
+       
+       unclassified=new LADSPA_Class();
+       /* This is the last class to accpet all plugins not accepted by other classes. */
+       root->subclasses.push_back(unclassified);
+}
+
+void LADSPA_Class::scandir(char *dirname) {
+       int dirlen=strlen(dirname);
+       int needslash=0;
+       DIR * dir;
+       struct dirent * entry;
+       char *filename;
+       
+       if (!dirlen) { tX_error("LADSPA_Class::scandir() Empty directory name"); return; };
+
+       if (dirname[dirlen - 1] != '/') needslash=1;
+       
+       dir = opendir(dirname);
+       
+       if (!dir) { tX_error("LADSPA_Class::scandir() couldn't access directory \"%s\"", dirname); return; };
+       
+       while (1) {
+               entry=readdir(dir);
+               
+               if (!entry) { closedir(dir); return; }
+               
+               if ((strcmp(entry->d_name, ".")==0) ||
+                       (strcmp(entry->d_name, "..")==0)) continue;
+               
+               filename = (char *) malloc (dirlen + strlen(entry->d_name) + 1 + needslash);
+               
+               strcpy(filename, "file:");
+               strcat(filename, dirname);
+               if (needslash) strcat(filename, "/");
+               strcat(filename, entry->d_name);
+               
+               tX_debug("Found RDF file: %s", filename);
+               rdf_files.push_back(filename);          
+       }       
+}
+
+void LADSPA_Class::insert_class(LADSPA_Class *cls) {
+       std::list <LADSPA_Class *> :: iterator i;
+       
+       for (i=subclasses.begin(); i!=subclasses.end(); i++) {
+               LADSPA_Class *a_class=(*i);
+               int res=compare(cls->label, a_class->label);
+               
+               if (res < 2) {
+                       subclasses.insert(i, cls);
+                       return;
+               }
+       }
+       
+       subclasses.push_back(cls);
+}
+
+LADSPA_Class :: LADSPA_Class (char *uri) : label(NULL), accept_all(false) {
+#ifdef USE_LRDF        
+       lrdf_uris *ulist;
+       char *urilabel;
+       int i;
+       
+       urilabel=lrdf_get_label(uri);
+       
+       if (urilabel) {
+               label=strdup(urilabel);
+       }
+       
+       /* Finding subclasses... */
+       ulist = lrdf_get_subclasses(uri);
+       
+       for (i = 0; ulist && i < ulist->count; i++) {
+               insert_class(new LADSPA_Class(ulist->items[i]));
+       }
+
+       lrdf_free_uris(ulist);
+
+       /* Finding instances... */
+       ulist=lrdf_get_instances(uri);
+       
+       for (i = 0; ulist && i < ulist->count; i++) {
+               registered_ids.push_back(lrdf_get_uid(ulist->items[i]));
+       }
+
+       lrdf_free_uris(ulist);
+#endif 
+}
+
+LADSPA_Class :: LADSPA_Class() : label("Unclassified"), accept_all(true) {
+}
+
+bool LADSPA_Class :: add_plugin(LADSPA_Plugin *plugin) {
+       return root->add_plugin_instance(plugin);
+}
+
+bool LADSPA_Class :: add_plugin_instance(LADSPA_Plugin *plugin) {
+       if (accept_all) {
+               insert_plugin(plugin);
+               return true;
+       }
+       
+       long id=plugin->getUniqueID();
+       std::list <long> :: iterator i;
+       
+       /* Is this plugin an instance of this class? */
+       
+       for (i=registered_ids.begin(); i!=registered_ids.end(); i++) {
+               if ((*i)==id) {
+                       /* The plugin belongs to this class... */
+                       insert_plugin(plugin);
+                       return true;
+               }
+       }
+       
+       /* Try to insert the plugin in subclasses */
+       std::list <LADSPA_Class *> :: iterator cls;
+       
+       for (cls=subclasses.begin(); cls!=subclasses.end(); cls++) {
+               LADSPA_Class *lrdf_class=(*cls);
+               
+               if (lrdf_class->add_plugin_instance(plugin)) return true;
+       }
+       
+       /* Giving up... */
+       
+       return false;
+}
+
+void LADSPA_Class::insert_plugin(LADSPA_Plugin *plugin) {
+       std::list <LADSPA_Plugin *> :: iterator i;
+       
+       for (i=plugins.begin(); i!=plugins.end(); i++) {
+               LADSPA_Plugin *a_plug=(*i);
+               int res=compare(plugin->getName(), a_plug->getName());
+               
+               if (res < 2) {
+                       plugins.insert(i, plugin);
+                       return;
+               }
+       }
+       
+       plugins.push_back(plugin);
+}
+
+void LADSPA_Class::list(char *buffer) {
+       strcat(buffer, "\t");
+       
+       printf("%s class %s {\n", buffer, label);
+
+       std::list <LADSPA_Plugin *> :: iterator i;      
+       
+       for (i=plugins.begin(); i!=plugins.end(); i++) {
+               printf("%s - plugin: %s\n", buffer, (*i)->getName());
+       }
+       
+       std::list <LADSPA_Class *> :: iterator c;
+       
+       for (c=subclasses.begin(); c!=subclasses.end(); c++) (*c)->list(buffer);
+       
+       printf("%s}\n", buffer);
+       
+       buffer[strlen(buffer)-1]=0;
+}
+
+void LADSPA_Class::dump() {
+       char buffer[256]="";
+       root->list(buffer);
+}
+
+static void menu_callback(GtkWidget *wid, LADSPA_Plugin *plugin) {
+       vtt_class *vtt=LADSPA_Class::get_current_vtt();
+       
+       if (vtt) {
+               vtt->add_effect(plugin);
+       } else {
+               tX_error("LADSPA_Class::menu_callback() no vtt");
+       }
+}
+
+
+GtkWidget * LADSPA_Class :: get_menu() {
+       std::list <LADSPA_Class *> :: iterator cls;
+       GtkWidget *menu=gtk_menu_new();
+       GtkWidget *item;
+       
+       for (cls=subclasses.begin(); cls!=subclasses.end(); cls++) {
+               LADSPA_Class *c=(*cls);
+               
+               if (c->plugins.size() || c->subclasses.size()) {
+                       item=gtk_menu_item_new_with_label(c->label);
+                       GtkWidget *submenu=c->get_menu();
+                       gtk_menu_item_set_submenu(GTK_MENU_ITEM(item), submenu);
+                       gtk_menu_append(menu, item);
+                       gtk_widget_show(item);
+               }
+       }
+       
+       if (subclasses.size() && plugins.size()) {
+               item = gtk_menu_item_new();
+               gtk_menu_append(menu, item);
+               gtk_widget_set_sensitive (item, FALSE);
+               gtk_widget_show (item);
+       }
+       
+       std::list <LADSPA_Plugin *> :: iterator plugin;
+       
+       for (plugin=plugins.begin(); plugin != plugins.end(); plugin++) {
+               char buffer[512];
+               LADSPA_Plugin *p=(*plugin);
+               
+               sprintf(buffer, "%s - (%s, %i)", p->getName(), p->getLabel(), p->getUniqueID());
+               item=gtk_menu_item_new_with_label(buffer);
+               gtk_menu_append(menu, item);
+               gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(menu_callback), p);            
+               gtk_widget_show(item);
+       }
+       
+       return menu;
+}
+
+GtkWidget * LADSPA_Class :: get_ladspa_menu() {
+       return root->get_menu();
+}
diff --git a/src/tX_ladspa_class.h b/src/tX_ladspa_class.h
new file mode 100644 (file)
index 0000000..ca96c65
--- /dev/null
@@ -0,0 +1,68 @@
+/*
+    terminatorX - realtime audio scratching software
+    Copyright (C) 1999-2003  Alexander König
+    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., 675 Mass Ave, Cambridge, MA 02139, USA.
+    File: tX_ladspa_class.h
+    Description: Header to tX_ladspa_class.cc - see there for more info
+*/
+
+#ifndef _h_tx_ladspa_class
+#define _h_tx_ladspa_class 1
+
+#ifdef HAVE_CONFIG_H
+#include <config.h>
+#endif
+
+#include "tX_ladspa.h"
+#include <list>
+#include <gtk/gtk.h>
+#include "tX_vtt.h"
+
+class LADSPA_Class { // Yeah, I know "class" name for C++ class - but it just seems to fit best...
+       protected:
+       static LADSPA_Class *root;
+       static LADSPA_Class *unclassified;
+       static std::list <char *> rdf_files;
+       static vtt_class *current_vtt;
+       
+       char *label;
+       bool accept_all;
+       std::list <LADSPA_Class *> subclasses;
+       std::list <long> registered_ids;
+       std::list <LADSPA_Plugin *> plugins;
+       
+       static void scandir(char *dir);
+       bool add_plugin_instance(LADSPA_Plugin *);
+       void insert_class(LADSPA_Class *);
+       void insert_plugin(LADSPA_Plugin *);
+       void list(char *);
+       GtkWidget *get_menu();
+       
+       public:
+       LADSPA_Class(char *uri);
+       LADSPA_Class(); // For the unclassified class;  
+       
+       static bool add_plugin(LADSPA_Plugin *plugin);
+       static void init();
+       static void dump();
+       static GtkWidget *get_ladspa_menu();
+       static void set_current_vtt(vtt_class *vtt) { current_vtt=vtt; }
+       static vtt_class *get_current_vtt() { return current_vtt; }
+};
+
+#endif
index 7de8f55f9b2691b6353eebdd3c63dc917441a99a..97a9d329a00f3fd380978ea37f6587bb2d3ce31c 100644 (file)
@@ -195,73 +195,74 @@ void tX_midiin::configure_bindings( vtt_class* vtt )
 tX_midiin::midi_binding_gui::midi_binding_gui ( GtkTreeModel* _model, tX_midiin* _midi )
        : model(_model), midi( _midi )
 {
-  GtkWidget *hbox1;
-  GtkWidget *scrolledwindow1;
-  GtkWidget *vbox1;
-  GtkWidget *label1;
-  GtkWidget *frame1;
-
-  window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
-  gtk_window_set_title (GTK_WINDOW (window), "Configure MIDI Bindings");
-
-  hbox1 = gtk_hbox_new (FALSE, 0);
-  gtk_widget_show (hbox1);
-  gtk_container_add (GTK_CONTAINER (window), hbox1);
-
-  scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
-  gtk_widget_show (scrolledwindow1);
-  gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
-
-  parameter_treeview = gtk_tree_view_new_with_model (model);
-    gtk_widget_show (parameter_treeview);
-  gtk_container_add (GTK_CONTAINER (scrolledwindow1), parameter_treeview);
-
-  GtkCellRenderer   *renderer = gtk_cell_renderer_text_new ();
-  gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( parameter_treeview ),
+       GtkWidget *hbox1;
+       GtkWidget *scrolledwindow1;
+       GtkWidget *vbox1;
+       GtkWidget *label1;
+       GtkWidget *frame1;
+       
+       window = gtk_window_new (GTK_WINDOW_TOPLEVEL);
+       gtk_window_set_title (GTK_WINDOW (window), "Configure MIDI Bindings");
+       gtk_window_set_default_size(GTK_WINDOW(window), 400, 260);
+       
+       hbox1 = gtk_hbox_new (FALSE, 0);
+       gtk_widget_show (hbox1);
+       gtk_container_add (GTK_CONTAINER (window), hbox1);
+       
+       scrolledwindow1 = gtk_scrolled_window_new (NULL, NULL);
+       gtk_widget_show (scrolledwindow1);
+       gtk_box_pack_start (GTK_BOX (hbox1), scrolledwindow1, TRUE, TRUE, 0);
+       
+       parameter_treeview = gtk_tree_view_new_with_model (model);
+       gtk_widget_show (parameter_treeview);
+       gtk_container_add (GTK_CONTAINER (scrolledwindow1), parameter_treeview);
+       
+       GtkCellRenderer   *renderer = gtk_cell_renderer_text_new ();
+       gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( parameter_treeview ),
                                                                                           -1, "Parameter", renderer,
                                                                                           "text", 0,
                                                                                           NULL );
-  gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( parameter_treeview ),
+       gtk_tree_view_insert_column_with_attributes( GTK_TREE_VIEW( parameter_treeview ),
                                                                                           -1, "Event", renderer,
                                                                                           "text", 1,
                                                                                           NULL );
-  gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(parameter_treeview), TRUE );
-
-  vbox1 = gtk_vbox_new (FALSE, 0);
-  gtk_widget_show (vbox1);
-  gtk_box_pack_start (GTK_BOX (hbox1), vbox1, FALSE, FALSE, 0);
-
-  label1 = gtk_label_new ("Selected MIDI Event:");
-  gtk_widget_show (label1);
-  gtk_box_pack_start (GTK_BOX (vbox1), label1, FALSE, FALSE, 0);
-  gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT);
-
-  frame1 = gtk_frame_new (NULL);
-  gtk_widget_show (frame1);
-  gtk_box_pack_start (GTK_BOX (vbox1), frame1, TRUE, TRUE, 0);
-  gtk_container_set_border_width (GTK_CONTAINER (frame1), 1);
-  gtk_frame_set_label_align (GTK_FRAME (frame1), 0, 0);
-  gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
-
-  midi_event_info = gtk_label_new ("Use a MIDI thing to select it.");
-  gtk_widget_show (midi_event_info);
-  gtk_container_add (GTK_CONTAINER (frame1), midi_event_info);
-  gtk_label_set_justify (GTK_LABEL (midi_event_info), GTK_JUSTIFY_LEFT);
-
-  bind_button = gtk_button_new_with_mnemonic ("Bind");
-  gtk_widget_show (bind_button);
-  gtk_box_pack_start (GTK_BOX (vbox1), bind_button, FALSE, FALSE, 0);
-
-  GtkWidget* close_button = gtk_button_new_with_mnemonic ("Close");
-  gtk_widget_show (close_button);
-  gtk_box_pack_start (GTK_BOX (vbox1), close_button, FALSE, FALSE, 0);
-
-  gtk_signal_connect(GTK_OBJECT(bind_button), "clicked", (GtkSignalFunc) bind_clicked, (void *) this);
-  gtk_signal_connect(GTK_OBJECT(close_button), "clicked", (GtkSignalFunc) close_clicked, (void *) this);
-
-  timer_tag = gtk_timeout_add( 100, (GtkFunction) timer, (void *) this);
-
-  gtk_widget_show_all( GTK_WIDGET( window ) );
+       gtk_tree_view_set_headers_visible( GTK_TREE_VIEW(parameter_treeview), TRUE );
+       
+       vbox1 = gtk_vbox_new (FALSE, 0);
+       gtk_widget_show (vbox1);
+       gtk_box_pack_start (GTK_BOX (hbox1), vbox1, FALSE, FALSE, 0);
+       
+       label1 = gtk_label_new ("Selected MIDI Event:");
+       gtk_widget_show (label1);
+       gtk_box_pack_start (GTK_BOX (vbox1), label1, FALSE, FALSE, 0);
+       gtk_label_set_justify (GTK_LABEL (label1), GTK_JUSTIFY_LEFT);
+       
+       frame1 = gtk_frame_new (NULL);
+       gtk_widget_show (frame1);
+       gtk_box_pack_start (GTK_BOX (vbox1), frame1, TRUE, TRUE, 0);
+       gtk_container_set_border_width (GTK_CONTAINER (frame1), 1);
+       gtk_frame_set_label_align (GTK_FRAME (frame1), 0, 0);
+       gtk_frame_set_shadow_type (GTK_FRAME (frame1), GTK_SHADOW_IN);
+       
+       midi_event_info = gtk_label_new ("Use a MIDI thing to select it.");
+       gtk_widget_show (midi_event_info);
+       gtk_container_add (GTK_CONTAINER (frame1), midi_event_info);
+       gtk_label_set_justify (GTK_LABEL (midi_event_info), GTK_JUSTIFY_LEFT);
+       
+       bind_button = gtk_button_new_with_mnemonic ("Bind");
+       gtk_widget_show (bind_button);
+       gtk_box_pack_start (GTK_BOX (vbox1), bind_button, FALSE, FALSE, 0);
+       
+       GtkWidget* close_button = gtk_button_new_with_mnemonic ("Close");
+       gtk_widget_show (close_button);
+       gtk_box_pack_start (GTK_BOX (vbox1), close_button, FALSE, FALSE, 0);
+       
+       gtk_signal_connect(GTK_OBJECT(bind_button), "clicked", (GtkSignalFunc) bind_clicked, (void *) this);
+       gtk_signal_connect(GTK_OBJECT(close_button), "clicked", (GtkSignalFunc) close_clicked, (void *) this);
+       
+       timer_tag = gtk_timeout_add( 100, (GtkFunction) timer, (void *) this);
+       
+       gtk_widget_show_all( GTK_WIDGET( window ) );
 }
 
 void tX_midiin::midi_binding_gui::bind_clicked( GtkButton *button, gpointer _this )
index 833591155962519ae62151e7cc412bc18ae8f939..ad565cb2cb213023e2c8f24db8b88947b061ec64 100644 (file)
@@ -965,16 +965,17 @@ void tX_seqpar_vttfx_int :: create_widget()
 
        *fx_value=min_value;
        myadj=GTK_ADJUSTMENT(gtk_adjustment_new(*fx_value, min_value, max_value, tmp, tmp, tmp));
-       widget=gtk_hbox_new(FALSE, 2);
-        tmpwid=gtk_label_new(label_name);
-       gtk_widget_show(tmpwid);
-       gtk_box_pack_start(GTK_BOX(widget), tmpwid, WID_FIX);
+       widget=gtk_vbox_new(FALSE, 2);
 
        tmpwid=gtk_spin_button_new(myadj,1.0,0);
        gtk_widget_show(tmpwid);
        gtk_box_pack_start(GTK_BOX(widget), tmpwid, WID_DYN);
        
        gtk_signal_connect(GTK_OBJECT(myadj), "value_changed", (GtkSignalFunc) tX_seqpar_vttfx_int :: gtk_callback, this);
+
+    tmpwid=gtk_label_new(label_name);
+       gtk_widget_show(tmpwid);
+       gtk_box_pack_start(GTK_BOX(widget), tmpwid, WID_FIX);
 }
 
 tX_seqpar_vttfx_int :: ~tX_seqpar_vttfx_int()
index ac8b3ea94915ef530a8438d138fb2cb564937dbb..d3c117b664e4d718560582d2f0e77460631024a5 100644 (file)
@@ -47,6 +47,7 @@
 #include "tX_extdial.h"
 #include "tX_panel.h"
 #include "tX_ladspa.h"
+#include "tX_ladspa_class.h"
 #include "tX_engine.h"
 
 #ifdef USE_DIAL
@@ -616,13 +617,6 @@ void vg_adjust_zoom(GtkWidget *wid, vtt_class *vtt) {
        gtk_tx_set_zoom(GTK_TX(vtt->gui.display), adj->value/100.0);
 }
 
-static vtt_class * fx_vtt;
-
-void new_effect(GtkWidget *wid, LADSPA_Plugin *plugin)
-{
-       fx_vtt->add_effect(plugin);
-}
-
 void fx_button_pressed(GtkWidget *wid, vtt_class *vtt)
 {
        vtt_gui *g=&vtt->gui;
@@ -633,30 +627,10 @@ void fx_button_pressed(GtkWidget *wid, vtt_class *vtt)
        char oldfile[1024]="";
        GtkWidget *submenu=NULL;
 
-       fx_vtt=vtt; /* AAAAARGH - Long live ugly code */
+       LADSPA_Class::set_current_vtt(vtt);
 
        if (g->ladspa_menu) gtk_object_destroy(GTK_OBJECT(g->ladspa_menu));
-       g->ladspa_menu=gtk_menu_new();
-       
-       for (i=0; i<LADSPA_Plugin::getPluginCount(); i++)
-       {
-               plugin=LADSPA_Plugin::getPluginByIndex(i);
-               if (strcmp(plugin->get_file_name(), oldfile))
-               {
-                       strcpy(oldfile, plugin->get_file_name());
-                       item = gtk_menu_item_new_with_label(oldfile);
-                       submenu=gtk_menu_new();
-                       gtk_menu_item_set_submenu (GTK_MENU_ITEM (item), submenu);
-                       gtk_menu_append(GTK_MENU(g->ladspa_menu), item);
-                       gtk_widget_show(item);
-               }
-               sprintf(buffer, "%s - [%li, %s]", plugin->getName(), plugin->getUniqueID(), plugin->getLabel());
-               item=gtk_menu_item_new_with_label(buffer);
-               gtk_menu_append(GTK_MENU(submenu), item);
-               gtk_widget_show(item);
-               gtk_signal_connect(GTK_OBJECT(item), "activate", GTK_SIGNAL_FUNC(new_effect), plugin);
-       }
-       
+       g->ladspa_menu=LADSPA_Class::get_ladspa_menu();
        gtk_menu_popup (GTK_MENU(g->ladspa_menu), NULL, NULL, NULL, NULL, 0, 0);
 
        /* gtk+ is really waiting for this.. */