traverso-commit
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[Traverso-commit] traverso/src/3rdparty/slv2 CMakeLists.txt slv2/...


From: Remon Sijrier
Subject: [Traverso-commit] traverso/src/3rdparty/slv2 CMakeLists.txt slv2/...
Date: Sat, 21 Feb 2009 21:07:00 +0000

CVSROOT:        /sources/traverso
Module name:    traverso
Changes by:     Remon Sijrier <r_sijrier>       09/02/21 21:07:00

Modified files:
        src/3rdparty/slv2: CMakeLists.txt 
        src/3rdparty/slv2/slv2: pluginclasses.h pluginclass.h plugin.h 
                                plugininstance.h plugins.h pluginui.h 
                                pluginuiinstance.h pluginuis.h port.h 
                                slv2.h types.h util.h value.h values.h 
                                world.h 
        src/3rdparty/slv2/src: plugin.c pluginclass.c pluginclasses.c 
                               plugininstance.c plugins.c pluginui.c 
                               pluginuiinstance.c pluginuis.c port.c 
                               query.c slv2_internal.h util.c value.c 
                               values.c world.c 
Added files:
        src/3rdparty/slv2/slv2: lv2_ui.h scalepoint.h scalepoints.h 
        src/3rdparty/slv2/src: scalepoint.c scalepoints.c 

Log message:
        * update internal slv2 copy to the newest release

CVSWeb URLs:
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/CMakeLists.txt?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/pluginclasses.h?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/pluginclass.h?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/plugin.h?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/plugininstance.h?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/plugins.h?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/pluginui.h?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/pluginuiinstance.h?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/pluginuis.h?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/port.h?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/slv2.h?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/types.h?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/util.h?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/value.h?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/values.h?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/world.h?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/lv2_ui.h?cvsroot=traverso&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/scalepoint.h?cvsroot=traverso&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/slv2/scalepoints.h?cvsroot=traverso&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/plugin.c?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/pluginclass.c?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/pluginclasses.c?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/plugininstance.c?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/plugins.c?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/pluginui.c?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/pluginuiinstance.c?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/pluginuis.c?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/port.c?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/query.c?cvsroot=traverso&r1=1.4&r2=1.5
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/slv2_internal.h?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/util.c?cvsroot=traverso&r1=1.1&r2=1.2
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/value.c?cvsroot=traverso&r1=1.3&r2=1.4
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/values.c?cvsroot=traverso&r1=1.2&r2=1.3
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/world.c?cvsroot=traverso&r1=1.5&r2=1.6
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/scalepoint.c?cvsroot=traverso&rev=1.1
http://cvs.savannah.gnu.org/viewcvs/traverso/src/3rdparty/slv2/src/scalepoints.c?cvsroot=traverso&rev=1.1

Patches:
Index: CMakeLists.txt
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/CMakeLists.txt,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- CMakeLists.txt      7 Dec 2007 15:31:43 -0000       1.4
+++ CMakeLists.txt      21 Feb 2009 21:06:57 -0000      1.5
@@ -3,21 +3,26 @@
 
 SET(TRAVERSO_SLV2_SOURCES
 src/plugin.c
-src/pluginui.c
-src/pluginuiinstance.c
-src/pluginuis.c
 src/pluginclass.c
 src/pluginclasses.c
 src/plugininstance.c
 src/plugins.c
+src/pluginui.c
+src/pluginuiinstance.c
+src/pluginuis.c
 src/port.c
 src/query.c
+src/scalepoint.c
+src/scalepoints.c
 src/util.c
 src/value.c
 src/values.c
 src/world.c
 )
 
+
+
+
 SET(CMAKE_C_FLAGS_DEBUG "-std=c99")
 SET(CMAKE_C_FLAGS_RELEASE "-std=c99")
 

Index: slv2/pluginclasses.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/pluginclasses.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- slv2/pluginclasses.h        7 Nov 2007 11:41:50 -0000       1.2
+++ slv2/pluginclasses.h        21 Feb 2009 21:06:57 -0000      1.3
@@ -19,42 +19,42 @@
 #ifndef __SLV2_PLUGIN_CLASSES_H__
 #define __SLV2_PLUGIN_CLASSES_H__
 
-#include <slv2/pluginclass.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** \addtogroup collections
+#include "slv2/pluginclass.h"
+
+/** \addtogroup slv2_collections
  * @{
  */
 
 
-/** Get the number of plugins in the list.
+/** Get the number of plugins in the collection.
  */
 unsigned
-slv2_plugin_classes_size(SLV2PluginClasses list);
+slv2_plugin_classes_size(SLV2PluginClasses classes);
 
 
-/** Get a plugin class from the list by URI.
+/** Get a plugin class from the collection by URI.
  *
- * Return value is shared (stored in \a list) and must not be freed or
+ * Return value is shared (stored in \a classes) and must not be freed or
  * modified by the caller in any way.
  *
  * Time = O(log2(n))
  * 
- * \return NULL if plugin with \a url not found in \a list.
+ * \return NULL if plugin with \a url not found in \a classes.
  */
 SLV2PluginClass
-slv2_plugin_classes_get_by_uri(SLV2PluginClasses list,
-                               const char*       uri);
+slv2_plugin_classes_get_by_uri(SLV2PluginClasses classes,
+                               SLV2Value         uri);
 
 
-/** Get a plugin from the list by index.
+/** Get a plugin from the collection by index.
  *
- * \a index has no significance other than as an index into this list.
- * Any \a index not less than slv2_plugin_classes_get_length(list) will return 
NULL,
- * so all plugin_classes in a list can be enumerated by repeated calls
+ * \a index has no significance other than as an index into \a classes.
+ * Any \a index not less than slv2_plugin_classes_get_length(classes) will 
return NULL,
+ * so all plugin_classes in a classes can be enumerated by repeated calls
  * to this function starting with \a index = 0.
  *
  * Time = O(1)
@@ -62,14 +62,14 @@
  * \return NULL if \a index out of range.
  */
 SLV2PluginClass
-slv2_plugin_classes_get_at(SLV2PluginClasses list,
+slv2_plugin_classes_get_at(SLV2PluginClasses classes,
                            unsigned          index);
 
 
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_PLUGIN_CLASSES_H__ */

Index: slv2/pluginclass.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/pluginclass.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- slv2/pluginclass.h  7 Nov 2007 11:41:50 -0000       1.2
+++ slv2/pluginclass.h  21 Feb 2009 21:06:57 -0000      1.3
@@ -23,9 +23,9 @@
 extern "C" {
 #endif
 
-#include <slv2/types.h>
+#include "slv2/types.h"
 
-/** \addtogroup data
+/** \addtogroup slv2_data
  * @{
  */
 
@@ -37,7 +37,7 @@
  *
  * Time = O(1)
  */
-const char* slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class);
+SLV2Value slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class);
 
 
 /** Get the URI of this plugin class.
@@ -46,7 +46,7 @@
  *
  * Time = O(1)
  */
-const char* slv2_plugin_class_get_uri(SLV2PluginClass plugin_class);
+SLV2Value slv2_plugin_class_get_uri(SLV2PluginClass plugin_class);
 
 
 /** Get the label of this plugin class, ie "Oscillators".
@@ -55,7 +55,7 @@
  *
  * Time = O(1)
  */
-const char* slv2_plugin_class_get_label(SLV2PluginClass plugin_class);
+SLV2Value slv2_plugin_class_get_label(SLV2PluginClass plugin_class);
 
 
 /** Get the subclasses of this plugin class.
@@ -71,7 +71,7 @@
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_PLUGIN_CLASS_H__ */

Index: slv2/plugin.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/plugin.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- slv2/plugin.h       7 Nov 2007 11:41:50 -0000       1.4
+++ slv2/plugin.h       21 Feb 2009 21:06:57 -0000      1.5
@@ -25,14 +25,14 @@
 
 #include <stdint.h>
 #include <stdbool.h>
-#include <slv2/types.h>
-#include <slv2/port.h>
-#include <slv2/values.h>
+#include "slv2/types.h"
+#include "slv2/port.h"
+#include "slv2/values.h"
 
-/** \defgroup data Plugin data access
+/** \defgroup slv2_data Plugin data access
  *
- * These functions work exclusively with the plugin's RDF data.
- * They do not load or access the plugin dynamic library in any way.
+ * These functions work exclusively with the plugin's RDF data,
+ * they do not access the plugin's shared library in any way.
  *
  * An SLV2Plugin contains an in-memory cache of the plugin data, loaded
  * on demand.  Duplicating plugins should be avoided when possible for
@@ -76,7 +76,7 @@
  *
  * Time = O(1)
  */
-const char*
+SLV2Value
 slv2_plugin_get_uri(SLV2Plugin plugin);
 
 
@@ -95,7 +95,7 @@
  *
  * Time = O(1)
  */
-const char*
+SLV2Value
 slv2_plugin_get_bundle_uri(SLV2Plugin plugin);
 
 
@@ -124,11 +124,10 @@
  *
  * Time = O(1)
  */
-const char*
+SLV2Value
 slv2_plugin_get_library_uri(SLV2Plugin plugin);
 
 
-
 /** Get the name of \a plugin.
  *
  * This is guaranteed to return the untranslated name (the doap:name in the
@@ -137,7 +136,7 @@
  *
  * Time = Query
  */
-char*
+SLV2Value
 slv2_plugin_get_name(SLV2Plugin plugin);
 
 
@@ -165,7 +164,29 @@
  */
 SLV2Values
 slv2_plugin_get_value(SLV2Plugin  p,
-                      SLV2URIType predicate_type,
+                      SLV2Value  predicate);
+
+
+/** Get a value associated with the plugin in a plugin's data files.
+ *
+ * This function is identical to slv2_plugin_get_value, but takes a QName
+ * string parameter for a predicate instead of an SLV2Value, which may be
+ * more convenient.
+ */
+SLV2Values
+slv2_plugin_get_value_by_qname(SLV2Plugin  p,
+                               const char* predicate);
+
+
+/** Get a translated value associated with the plugin in a plugin's data files.
+ *
+ * This function is identical to slv2_plugin_get_value, but takes a QName
+ * string parameter for a predicate instead of an SLV2Value, which may be
+ * more convenient. It returns the value translated to the current language
+ * if possible.
+ */
+SLV2Values
+slv2_plugin_get_value_by_qname_i18n(SLV2Plugin  p,
                       const char* predicate);
 
 
@@ -190,9 +211,20 @@
  */
 SLV2Values
 slv2_plugin_get_value_for_subject(SLV2Plugin  p,
-                                  SLV2Value   subject,
-                                  SLV2URIType predicate_type,
-                                  const char* predicate);
+                                  SLV2Value   subject_uri,
+                                  SLV2Value   predicate_uri);
+
+
+/** Return whether a feature is supported by a plugin.
+ *
+ * This will return true if the feature is an optional or required feature
+ * of the plugin.
+ *
+ * Time = Query
+ */
+bool
+slv2_plugin_has_feature(SLV2Plugin p,
+                        SLV2Value  feature_uri);
 
 
 /** Get the LV2 Features supported (required or optionally) by a plugin.
@@ -250,6 +282,38 @@
 slv2_plugin_get_num_ports(SLV2Plugin p);
 
 
+/** Get the port ranges (minimum, maximum and default values) for all ports.
+ *
+ * \a min_values, \a max_values and \a def_values must either point to an array
+ * of N floats, where N is the value returned by slv2_plugin_get_num_ports()
+ * for this plugin, or NULL.  The elements of the array will be set to the
+ * the minimum, maximum and default values of the ports on this plugin,
+ * with array index corresponding to port index.  If a port doesn't have a
+ * minimum, maximum or default value, or the port's type is not float, the
+ * corresponding array element will be set to NAN.
+ * 
+ * This is a convenience method for the common case of getting the range of
+ * all float ports on a plugin, and may be significantly faster than
+ * repeated calls to slv2_port_get_range.
+ */
+void
+slv2_plugin_get_port_ranges_float(SLV2Plugin p, 
+                                  float*     min_values, 
+                                  float*     max_values,
+                                  float*     def_values);
+
+/** Get the number of ports on this plugin that are members of some class(es).
+ *
+ * Note that this is a varargs function so ports fitting any type 'profile'
+ * desired can be found quickly.  REMEMBER TO TERMINATE THE PARAMETER LIST
+ * OF THIS FUNCTION WITH NULL OR VERY NASTY THINGS WILL HAPPEN.
+ *
+ * Time = O(1)
+ */
+uint32_t
+slv2_plugin_get_num_ports_of_class(SLV2Plugin p,
+                                   SLV2Value  class_1, ...);
+
 /** Return whether or not the plugin introduces (and reports) latency.
  *
  * The index of the latency port can be found with slv2_plugin_get_latency_port
@@ -273,29 +337,32 @@
  * Time = Query
  */
 uint32_t
-slv2_plugin_get_latency_port(SLV2Plugin p);
+slv2_plugin_get_latency_port_index(SLV2Plugin p);
 
 
-/** Query a plugin for a single variable.
+/** Query a plugin for a single variable (i.e. SELECT a single ?value).
  *
  * \param plugin The plugin to query.
  * \param sparql_str A SPARQL SELECT query.
  * \param variable The index of the variable to return results for
- *     (i.e. with "<code>SELECT ?foo ?bar</code>" foo is 0, and bar is 1).
+ *        (e.g. with "<code>SELECT ?foo ?bar</code>" foo=0, bar=1).
  * \return All matches for \a variable.
  *
  * Time = Query
  */
 SLV2Values
-slv2_plugin_simple_query(SLV2Plugin  plugin,
+slv2_plugin_query_variable(SLV2Plugin  plugin,
                          const char* sparql_str,
                          unsigned    variable);
 
 
 /** Query a plugin and return the number of results found.
  *
+ * Note that this function will work, but is mostly meaningless for queries
+ * that are not SELECT DISTINCT.
+ *
  * \param plugin The plugin to query.
- * \param sparql_str A SPARQL SELECT query.
+ * \param sparql_str A SPARQL SELECT DISTINCT query.
  *
  * Time = Query
  */
@@ -319,13 +386,15 @@
 /** Get a port on this plugin by \a symbol.
  *
  * To perform multiple calls on a port, the returned value should
- * be cached and used repeatedly.
+ * be cached and used repeatedly.  Note this function is slower
+ * than slv2_plugin_get_port_by_index, especially on plugins
+ * with a very large number of ports.
  *
  * Time = O(n)
  */
 SLV2Port
 slv2_plugin_get_port_by_symbol(SLV2Plugin  plugin,
-                               const char* symbol);
+                               SLV2Value  symbol);
 
 
 /** Get a list of all UIs available for this plugin.
@@ -344,10 +413,43 @@
 slv2_plugin_get_uis(SLV2Plugin plugin);
 
 
+/** Get the full name of the plugin's author.
+ *
+ * Returns NULL if author name is not present.
+ * Returned value must be freed by caller.
+ *
+ * Time = Query
+ */
+SLV2Value
+slv2_plugin_get_author_name(SLV2Plugin plugin);
+
+
+/** Get the email address of the plugin's author.
+ *
+ * Returns NULL if author email address is not present.
+ * Returned value must be freed by caller.
+ *
+ * Time = Query
+ */
+SLV2Value
+slv2_plugin_get_author_email(SLV2Plugin plugin);
+
+
+/** Get the email address of the plugin's author.
+ *
+ * Returns NULL if author homepage is not present.
+ * Returned value must be freed by caller.
+ *
+ * Time = Query
+ */
+SLV2Value
+slv2_plugin_get_author_homepage(SLV2Plugin plugin);
+
+
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_PLUGIN_H__ */

Index: slv2/plugininstance.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/plugininstance.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- slv2/plugininstance.h       7 Nov 2007 11:41:50 -0000       1.4
+++ slv2/plugininstance.h       21 Feb 2009 21:06:58 -0000      1.5
@@ -24,29 +24,21 @@
 #endif
 
 #include <assert.h>
-#include <slv2/lv2.h>
-#include <slv2/plugin.h>
-#include <slv2/port.h>
-
-/** \defgroup lib Plugin library access
- *
- * An SLV2Instance is an instantiated SLV2Plugin (ie a loaded dynamic
- * library).  These functions interact with the binary library code only,
- * they do not read data files in any way.
- * 
- * @{
- */
-
+#include "lv2.h"
+#include "slv2/plugin.h"
+#include "slv2/port.h"
 
 typedef struct _InstanceImpl* SLV2InstanceImpl;
 
+/** \cond IGNORE */
 
-/** Instance of a plugin.
+/* Instance of a plugin.
  *
  * The LV2 descriptor and handle of this are exposed to allow inlining of
  * performance critical functions like slv2_instance_run (which are exposed
- * in lv2.h anyway).  The remaining implementation details are
- * in the opaque pimpl member.
+ * in lv2.h anyway).  This is for performance only, this struct is not
+ * documented and should not be used directly.  The remaining implementation
+ * details are in the opaque pimpl member.
  */
 typedef struct _Instance {
        const LV2_Descriptor* lv2_descriptor;
@@ -54,8 +46,18 @@
        SLV2InstanceImpl      pimpl; ///< Private implementation
 }* SLV2Instance;
 
+/** \endcond */
 
 
+/** \defgroup slv2_library Plugin library access
+ *
+ * An SLV2Instance is an instantiated SLV2Plugin (ie a loaded dynamic
+ * library).  These functions interact with the binary library code only,
+ * they do not read data files in any way.
+ * 
+ * @{
+ */
+
 /** Instantiate a plugin.
  *
  * The returned object represents shared library objects loaded into memory,
@@ -74,7 +76,7 @@
 SLV2Instance
 slv2_plugin_instantiate(SLV2Plugin          plugin,
                         double              sample_rate,
-                        const LV2_Feature** features);
+                        const LV2_Feature*const* features);
 
 
 /** Free a plugin instance.
@@ -149,7 +151,7 @@
        assert(instance->lv2_descriptor);
        assert(instance->lv2_handle);
 
-       if (instance->lv2_descriptor->run)
+       /*if (instance->lv2_descriptor->run)*/
                instance->lv2_descriptor->run(instance->lv2_handle, 
sample_count);
 }
 
@@ -171,6 +173,25 @@
 }
 
 
+/** Get extension data from the plugin instance.
+ *
+ * The type and semantics of the data returned is specific to the particular
+ * extension, though in all cases it is shared and must not be deleted.
+ */
+static inline const void*
+slv2_instance_get_extension_data(SLV2Instance instance,
+                                 const char*  uri)
+{
+       assert(instance);
+       assert(instance->lv2_descriptor);
+       
+       if (instance->lv2_descriptor->extension_data)
+               return instance->lv2_descriptor->extension_data(uri);
+       else
+               return 0;
+}
+
+
 /** Get the LV2_Descriptor of the plugin instance.
  *
  * Normally hosts should not need to access the LV2_Descriptor directly,
@@ -209,7 +230,7 @@
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 

Index: slv2/plugins.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/plugins.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- slv2/plugins.h      7 Nov 2007 11:41:50 -0000       1.2
+++ slv2/plugins.h      21 Feb 2009 21:06:58 -0000      1.3
@@ -19,53 +19,53 @@
 #ifndef __SLV2_PLUGINS_H__
 #define __SLV2_PLUGINS_H__
 
-#include <slv2/types.h>
-#include <slv2/plugin.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** \addtogroup collections
+#include "slv2/types.h"
+#include "slv2/plugin.h"
+
+/** \addtogroup slv2_collections
  * @{
  */
 
 
-/** Free a plugin list.
+/** Free a plugin plugins.
  *
- * Freeing a plugin list does not destroy the plugins it contains (plugins
- * are owned by the world).  \a list is invalid after this call.
+ * Freeing a plugin collection does not destroy the plugins it contains
+ * (plugins are owned by the world). \a plugins is invalid after this call.
  */
 void
 slv2_plugins_free(SLV2World   world,
-                  SLV2Plugins list);
+                  SLV2Plugins plugins);
 
 
-/** Get the number of plugins in the list.
+/** Get the number of plugins in the collection.
  */
 unsigned
-slv2_plugins_size(SLV2Plugins list);
+slv2_plugins_size(SLV2Plugins plugins);
 
 
-/** Get a plugin from the list by URI.
+/** Get a plugin from the collection by URI.
  *
- * Return value is shared (stored in \a list) and must not be freed or
+ * Return value is shared (stored in \a plugins) and must not be freed or
  * modified by the caller in any way.
  *
  * Time = O(log2(n))
  * 
- * \return NULL if plugin with \a url not found in \a list.
+ * \return NULL if plugin with \a url not found in \a plugins.
  */
 SLV2Plugin
-slv2_plugins_get_by_uri(SLV2Plugins list,
-                        const char* uri);
+slv2_plugins_get_by_uri(SLV2Plugins plugins,
+                        SLV2Value   uri);
 
 
-/** Get a plugin from the list by index.
+/** Get a plugin from the plugins by index.
  *
- * \a index has no significance other than as an index into this list.
- * Any \a index not less than slv2_list_get_length(list) will return NULL,
- * so all plugins in a list can be enumerated by repeated calls
+ * \a index has no significance other than as an index into this plugins.
+ * Any \a index not less than slv2_plugins_get_length(plugins) will return 
NULL,
+ * so all plugins in a plugins can be enumerated by repeated calls
  * to this function starting with \a index = 0.
  *
  * Time = O(1)
@@ -73,14 +73,14 @@
  * \return NULL if \a index out of range.
  */
 SLV2Plugin
-slv2_plugins_get_at(SLV2Plugins list,
+slv2_plugins_get_at(SLV2Plugins plugins,
                     unsigned    index);
 
 
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_PLUGINS_H__ */

Index: slv2/pluginui.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/pluginui.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- slv2/pluginui.h     7 Nov 2007 11:41:50 -0000       1.1
+++ slv2/pluginui.h     21 Feb 2009 21:06:58 -0000      1.2
@@ -23,7 +23,7 @@
 extern "C" {
 #endif
 
-/** \addtogroup data
+/** \addtogroup slv2_data
  * @{
  */
 
@@ -31,58 +31,62 @@
 /** Get the URI of a Plugin UI.
  *
  * \param ui The Plugin UI
+ * \return a shared value which must not be modified or freed.
  *
  * Time = O(1)
  */
-const char*
+SLV2Value
 slv2_ui_get_uri(SLV2UI ui);
 
 
 /** Get the types (URIs of RDF classes) of a Plugin UI.
  *
  * \param ui The Plugin UI
+ * \return a shared value which must not be modified or freed.
  *
  * Time = O(1)
  */
 SLV2Values
-slv2_ui_get_types(SLV2UI ui);
+slv2_ui_get_classes(SLV2UI ui);
 
 
 /** Check whether a plugin UI is a given type.
  *
  * \param ui       The Plugin UI
- * \param type_uri The URI of the LV2 UI type to check this UI against
+ * \param class_uri The URI of the LV2 UI type to check this UI against
  *
  * Time = O(1)
  */
 bool
-slv2_ui_is_type(SLV2UI ui, const char* type_uri);
+slv2_ui_is_a(SLV2UI ui, SLV2Value class_uri);
        
 
 /** Get the URI for a Plugin UI's bundle.
  *
  * \param ui The Plugin UI
+ * \return a shared value which must not be modified or freed.
  *
  * Time = O(1)
  */
-const char*
+SLV2Value
 slv2_ui_get_bundle_uri(SLV2UI ui);
 
 
 /** Get the URI for a Plugin UI's shared library.
  *
  * \param ui The Plugin UI
+ * \return a shared value which must not be modified or freed.
  *
  * Time = O(1)
  */
-const char*
+SLV2Value
 slv2_ui_get_binary_uri(SLV2UI ui);
 
 
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_PLUGIN_UI_H__ */

Index: slv2/pluginuiinstance.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/pluginuiinstance.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- slv2/pluginuiinstance.h     7 Nov 2007 11:41:50 -0000       1.1
+++ slv2/pluginuiinstance.h     21 Feb 2009 21:06:58 -0000      1.2
@@ -1,6 +1,5 @@
 /* SLV2
  * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
- * Author: Lars Luthman
  *  
  * This library 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
@@ -25,19 +24,12 @@
 #endif
 
 #include <assert.h>
-#include <slv2/lv2_gui.h>
-#include <slv2/plugin.h>
-
-/** \addtogroup lib
- * @{
- */
-
+#include "slv2/lv2_ui.h"
+#include "slv2/plugin.h"
 
 typedef struct _SLV2UIInstanceImpl* SLV2UIInstanceImpl;
 
-  
-
-/** Instance of a plugin UI.
+/* Instance of a plugin UI.
  *
  * All details are in hidden in the pimpl member to avoid making the
  * implementation a part of the ABI.
@@ -47,6 +39,10 @@
 }* SLV2UIInstance;
 
 
+/** \addtogroup slv2_library
+ * @{
+ */
+
 
 /** Instantiate a plugin UI.
  *
@@ -67,15 +63,16 @@
 slv2_ui_instantiate(SLV2Plugin                     plugin,
                     SLV2UI                         ui,
                     LV2UI_Write_Function           write_function,
-                    LV2UI_Command_Function         command_function,
-                    LV2UI_Program_Change_Function  program_function,
-                    LV2UI_Program_Save_Function    save_function,
                     LV2UI_Controller               controller,
                     const LV2_Feature* const*      features);
 
 
 /** Free a plugin UI instance.
  *
+ * It is the caller's responsibility to ensure all references to the UI
+ * instance (including any returned widgets) are cut before calling
+ * this function.
+ *
  * \a instance is invalid after this call.
  */
 void
@@ -113,7 +110,7 @@
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 

Index: slv2/pluginuis.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/pluginuis.h,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- slv2/pluginuis.h    7 Nov 2007 11:41:51 -0000       1.1
+++ slv2/pluginuis.h    21 Feb 2009 21:06:58 -0000      1.2
@@ -19,14 +19,14 @@
 #ifndef __SLV2_PLUGIN_UIS_H__
 #define __SLV2_PLUGIN_UIS_H__
 
-#include <slv2/types.h>
-#include <slv2/plugin.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** \addtogroup collections
+#include "slv2/types.h"
+#include "slv2/plugin.h"
+
+/** \addtogroup slv2_collections
  *
  * @{
  */
@@ -58,7 +58,7 @@
  */
 SLV2UI
 slv2_uis_get_by_uri(SLV2UIs     list,
-                    const char* uri);
+                    SLV2Value uri);
 
 
 /** Get a plugin from the list by index.
@@ -80,7 +80,7 @@
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_PLUGIN_UIS_H__ */

Index: slv2/port.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/port.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- slv2/port.h 7 Nov 2007 11:41:51 -0000       1.4
+++ slv2/port.h 21 Feb 2009 21:06:58 -0000      1.5
@@ -23,12 +23,12 @@
 extern "C" {
 #endif
 
-#include <slv2/types.h>
-#include <slv2/plugin.h>
-#include <slv2/port.h>
-#include <slv2/values.h>
+#include "slv2/types.h"
+#include "slv2/plugin.h"
+#include "slv2/port.h"
+#include "slv2/values.h"
 
-/** \addtogroup data
+/** \addtogroup slv2_data
  * @{
  */
 
@@ -40,7 +40,27 @@
 SLV2Values
 slv2_port_get_value(SLV2Plugin  plugin,
                     SLV2Port    port,
-                    const char* property);
+                    SLV2Value  predicate);
+
+
+/** Port analog of slv2_plugin_get_value_by_qname.
+ *
+ * Time = Query
+ */
+SLV2Values
+slv2_port_get_value_by_qname(SLV2Plugin  plugin,
+                             SLV2Port    port,
+                             const char* property_uri);
+
+
+/** Port analog of slv2_plugin_get_value_by_qname_i18n.
+ *
+ * Time = Query
+ */
+SLV2Values
+slv2_port_get_value_by_qname_i18n(SLV2Plugin  plugin,
+                                 SLV2Port    port,
+                                 const char* property_uri);
 
 
 /** Return the LV2 port properties of a port.
@@ -52,7 +72,6 @@
                          SLV2Port   port);
 
 
-#if 0
 /** Return whether a port has a certain property.
  *
  * Time = Query
@@ -60,20 +79,27 @@
 bool
 slv2_port_has_property(SLV2Plugin p,
                        SLV2Port   port,
-                       SLV2Value  hint)
-#endif
+                       SLV2Value  property_uri);
 
 
-/** Get the symbol of a port given the index.
+/** Return whether a port is an event port and supports a certain event type.
  *
- * The 'symbol' is a short string, a valid C identifier.
- * Returned string must be free()'d by caller.
+ * Time = Query
+ */
+bool
+slv2_port_supports_event(SLV2Plugin p,
+                         SLV2Port   port,
+                         SLV2Value  event_uri);
+
+
+/** Get the symbol of a port.
  *
- * \return NULL when index is out of range
+ * The 'symbol' is a short string, a valid C identifier.
+ * Returned value is owned by \a port and must not be freed.
  *
  * Time = Query
  */
-char*
+SLV2Value
 slv2_port_get_symbol(SLV2Plugin plugin,
                      SLV2Port   port);
 
@@ -85,65 +111,77 @@
  *
  * Time = Query
  */
-char*
+SLV2Value
 slv2_port_get_name(SLV2Plugin plugin,
                    SLV2Port   port);
 
 
-/** Get the direction (input, output) of a port.
+/** Get all the classes of a port.
  *
- * Time = Query
- */
-SLV2PortDirection
-slv2_port_get_direction(SLV2Plugin plugin,
-                        SLV2Port   port);
-
-/** Get the data type of a port.
+ * This can be used to determine if a port is an input, output, audio,
+ * control, midi, etc, etc, though it's simpler to use slv2_port_is_a.
+ * The returned list does not include lv2:Port, which is implied.
  *
- * Time = Query
+ * Returned value is shared and must not be destroyed by caller.
+ *
+ * Time = O(1)
  */
-SLV2PortDataType
-slv2_port_get_data_type(SLV2Plugin plugin,
+SLV2Values
+slv2_port_get_classes(SLV2Plugin plugin,
                         SLV2Port   port);
 
 
-/** Get the default value of a port.
+/** Determine if a port is of a given class (input, output, audio, etc).
  *
- * Only valid for ports with a data type of lv2:float.
+ * For convenience/performance/extensibility reasons, hosts are expected to
+ * create an SLV2Value for each port class they "care about".  Well-known type
+ * URI strings are defined (e.g. SLV2_PORT_CLASS_INPUT) for convenience, but
+ * this function is designed so that SLV2 is usable with any port types
+ * without requiring explicit support in SLV2.
  *
- * Time = Query
+ * Time = O(n) (n pointer comparisons where n is the number of classes of
+ * this port, so this method is suitable for realtime use on any sane port).
  */
-float
-slv2_port_get_default_value(SLV2Plugin plugin, 
-                            SLV2Port   port);
+bool
+slv2_port_is_a(SLV2Plugin plugin,
+               SLV2Port   port,
+               SLV2Value  port_class);
 
 
-/** Get the minimum value of a port.
+/** Get the default, minimum, and maximum values of a port.
  *
- * Only valid for ports with a data type of lv2:float.
+ * @a def, @a min, and @a max are outputs, pass pointers to uninitialized
+ * (i.e. NOT created with slv2_value_new) SLV2Value variables.  These will
+ * be set to point at new values (which must be freed by the caller using
+ * slv2_value_free), or NULL if the value does not exist.
  *
  * Time = Query
  */
-float
-slv2_port_get_minimum_value(SLV2Plugin plugin, 
-                            SLV2Port   port);
+void
+slv2_port_get_range(SLV2Plugin plugin, 
+                    SLV2Port   port,
+                    SLV2Value* def,
+                    SLV2Value* min,
+                    SLV2Value* max);
 
 
-/** Get the maximum value of a port.
+/** Get the scale points (enumeration values) of a port.
  *
- * Only valid for ports with a data type of lv2:float.
+ * This returns a collection of 'interesting' named values of a port
+ * (e.g. appropriate entries for a UI selector associated with this port).
  *
- * Time = Query
+ * Returned value may be NULL if @a port has no scale points, otherwise it
+ * must be freed by caller with slv2_scale_points_free.
  */
-float
-slv2_port_get_maximum_value(SLV2Plugin plugin, 
+SLV2ScalePoints
+slv2_port_get_scale_points(SLV2Plugin plugin,
                             SLV2Port   port);
 
 
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_PORT_H__ */

Index: slv2/slv2.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/slv2.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- slv2/slv2.h 7 Nov 2007 11:41:51 -0000       1.4
+++ slv2/slv2.h 21 Feb 2009 21:06:58 -0000      1.5
@@ -23,22 +23,24 @@
 extern "C" {
 #endif
 
-#include <slv2/types.h>
-#include <slv2/world.h>
-#include <slv2/pluginclass.h>
-#include <slv2/plugin.h>
-#include <slv2/pluginui.h>
-#include <slv2/pluginuis.h>
-#include <slv2/port.h>
-#include <slv2/plugins.h>
-#include <slv2/pluginuiinstance.h>
-#include <slv2/plugininstance.h>
-#include <slv2/value.h>
-#include <slv2/values.h>
-#include <slv2/util.h>
+#include "slv2/plugin.h"
+#include "slv2/pluginclass.h"
+#include "slv2/plugininstance.h"
+#include "slv2/plugins.h"
+#include "slv2/pluginui.h"
+#include "slv2/pluginuiinstance.h"
+#include "slv2/pluginuis.h"
+#include "slv2/port.h"
+#include "slv2/types.h"
+#include "slv2/util.h"
+#include "slv2/value.h"
+#include "slv2/values.h"
+#include "slv2/scalepoint.h"
+#include "slv2/scalepoints.h"
+#include "slv2/world.h"
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_H__ */

Index: slv2/types.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/types.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- slv2/types.h        7 Nov 2007 11:41:51 -0000       1.4
+++ slv2/types.h        21 Feb 2009 21:06:58 -0000      1.5
@@ -19,54 +19,20 @@
 #ifndef __SLV2_TYPES_H__
 #define __SLV2_TYPES_H__
 
-#include <stdbool.h>
-#include <stdint.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
+#include <stdint.h>
 
-/** (Data) Type of a port
- *
- * SLV2_UNKNOWN_PORT_TYPE means the Port is not of any type SLV2 understands
- * (currently Control, Audio, MIDI, and OSC).
- *
- * Further class information can be using slv2_port_get_value(p, "rdf:type")
- * or a custom query.
- */
-typedef enum _SLV2PortDataType {
-       SLV2_PORT_DATA_TYPE_UNKNOWN,
-       SLV2_PORT_DATA_TYPE_CONTROL, /**< One float per block */
-       SLV2_PORT_DATA_TYPE_AUDIO,   /**< One float per frame */
-       SLV2_PORT_DATA_TYPE_MIDI,    /**< A buffer of MIDI data (LL extension) 
*/
-       SLV2_PORT_DATA_TYPE_OSC,     /**< A buffer of OSC data (DR extension) */
-} SLV2PortDataType;
-
-/** Direction (input or output) of a port
- *
- * SLV2_UNKNOWN_PORT_DIRECTION means the Port is only of type lv2:Port
- * (neither lv2:Input or lv2:Output) as far as SLV2 understands.
- *
- * Further class information can be using slv2_port_get_value(p, "rdf:type")
- * or a custom query.
- */
-typedef enum _SLV2PortDirection {
-       SLV2_PORT_DIRECTION_UNKNOWN, /**< Neither input or output */
-       SLV2_PORT_DIRECTION_INPUT,   /**< Plugin reads from port when run */
-       SLV2_PORT_DIRECTION_OUTPUT,  /**< Plugin writes to port when run */
-} SLV2PortDirection;
-
-
-/** The format of a URI string.
- *
- * Full URI: http://example.org/foo
- * QName: lv2:Plugin
- */
-typedef enum _SLV2URIType {
-       SLV2_URI,
-       SLV2_QNAME
-} SLV2URIType;
+#define SLV2_NAMESPACE_LV2      "http://lv2plug.in/ns/lv2core#";
+#define SLV2_PORT_CLASS_PORT    "http://lv2plug.in/ns/lv2core#Port";
+#define SLV2_PORT_CLASS_INPUT   "http://lv2plug.in/ns/lv2core#InputPort";
+#define SLV2_PORT_CLASS_OUTPUT  "http://lv2plug.in/ns/lv2core#OutputPort";
+#define SLV2_PORT_CLASS_CONTROL "http://lv2plug.in/ns/lv2core#ControlPort";
+#define SLV2_PORT_CLASS_AUDIO   "http://lv2plug.in/ns/lv2core#AudioPort";
+#define SLV2_PORT_CLASS_EVENT   "http://lv2plug.in/ns/ext/event#EventPort";
+#define SLV2_EVENT_CLASS_MIDI   "http://lv2plug.in/ns/ext/midi#MidiEvent";
 
 
 /** A port on a plugin.  Opaque, but valid to compare to NULL. */
@@ -101,6 +67,14 @@
 typedef void* SLV2Values;
 
 
+/** A scale point */
+typedef struct _SLV2ScalePoint* SLV2ScalePoint;
+
+
+/** A collection of scale points. */
+typedef void* SLV2ScalePoints;
+
+
 /** A plugin UI */
 typedef struct _SLV2UI* SLV2UI;
 
@@ -110,7 +84,7 @@
 
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 

Index: slv2/util.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/util.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- slv2/util.h 8 Jun 2007 09:29:07 -0000       1.2
+++ slv2/util.h 21 Feb 2009 21:06:58 -0000      1.3
@@ -19,13 +19,14 @@
 #ifndef __SLV2_UTIL_H__
 #define __SLV2_UTIL_H__
 
-#include <stdarg.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** \defgroup util Utility functions
+#include <stdarg.h>
+
+
+/** \defgroup slv2_util Utility functions
  *
  * @{
  */
@@ -39,31 +40,10 @@
 const char* slv2_uri_to_path(const char* uri);
 
 
-/** Append \a suffix to \a *dst, reallocating \a dst as necessary.
- *
- * \a dst will (possibly) be freed, it must be dynamically allocated with 
malloc
- * or NULL.
- */
-void
-slv2_strappend(char** dst, const char* suffix);
-
-
-/** Join all arguments into one string.
- *
- * Arguments are not modified, return value must be free()'d.
- */
-char*
-slv2_strjoin(const char* first, ...);
-
-
-char*
-slv2_vstrjoin(const char** first, va_list args_list);
-
-
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_UTIL_H__ */

Index: slv2/value.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/value.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- slv2/value.h        7 Nov 2007 11:41:51 -0000       1.3
+++ slv2/value.h        21 Feb 2009 21:06:58 -0000      1.4
@@ -24,15 +24,19 @@
 #endif
 
 #include <stdbool.h>
-#include <slv2/types.h>
+#include "slv2/types.h"
 
-/** \addtogroup data
+/** \addtogroup slv2_data
  * @{
  */
 
 
-/*SLV2Value
-slv2_value_new_uri(const char* uri);*/
+/** Create a new URI value.
+ *
+ * Returned value must be freed by called with slv2_value_free.
+ */
+SLV2Value
+slv2_value_new_uri(SLV2World world, const char* uri);
 
 
 /** Free an SLV2Value.
@@ -178,7 +182,7 @@
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_VALUE_H__ */

Index: slv2/values.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/values.h,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- slv2/values.h       7 Nov 2007 11:41:51 -0000       1.2
+++ slv2/values.h       21 Feb 2009 21:06:59 -0000      1.3
@@ -19,14 +19,14 @@
 #ifndef __SLV2_VALUES_H__
 #define __SLV2_VALUES_H__
 
-#include <stdbool.h>
-#include <slv2/value.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** \defgroup collections Collections of values/objects
+#include <stdbool.h>
+#include "slv2/value.h"
+
+/** \defgroup slv2_collections Collections of values/objects
  *
  * Ordered collections of typed values which are fast for random
  * access by index (i.e. a fancy array).
@@ -41,40 +41,40 @@
 slv2_values_new();
 
 
-/** Get the number of elements in a string list.
+/** Free an SLV2Values.
+ */
+void
+slv2_values_free(SLV2Values values);
+
+
+/** Get the number of elements in a value collection.
  */
 unsigned
-slv2_values_size(SLV2Values list);
+slv2_values_size(SLV2Values values);
 
 
-/** Get a string from a string list at the given index.
+/** Get the value at a given index in the collection.
  *
  * @return the element at \a index, or NULL if index is out of range.
  *
  * Time = O(1)
  */
 SLV2Value
-slv2_values_get_at(SLV2Values list, unsigned index);
+slv2_values_get_at(SLV2Values values, unsigned index);
 
 
-/** Return whether \a list contains \a string.
+/** Return whether \a values contains \a value.
  *
  * Time = O(n)
  */
 bool
-slv2_values_contains(SLV2Values list, SLV2Value value);
-
-
-/** Free a string list.
- */
-void
-slv2_values_free(SLV2Values);
+slv2_values_contains(SLV2Values values, SLV2Value value);
 
 
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_VALUES_H__ */

Index: slv2/world.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/slv2/world.h,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- slv2/world.h        7 Nov 2007 11:41:51 -0000       1.4
+++ slv2/world.h        21 Feb 2009 21:06:59 -0000      1.5
@@ -19,15 +19,15 @@
 #ifndef __SLV2_WORLD_H__
 #define __SLV2_WORLD_H__
 
-#include <slv2/plugins.h>
-#include <slv2/pluginclasses.h>
-#include <librdf.h>
-
 #ifdef __cplusplus
 extern "C" {
 #endif
 
-/** \defgroup world Global library state
+#include <librdf.h>
+#include "slv2/plugins.h"
+#include "slv2/pluginclasses.h"
+
+/** \defgroup slv2_world Global library state
  * 
  * The "world" represents all library state, and the data found in bundles'
  * manifest.ttl (ie it is an in-memory index of all things LV2 found).
@@ -108,7 +108,7 @@
  */
 void
 slv2_world_load_bundle(SLV2World   world,
-                       const char* bundle_uri);
+                       SLV2Value bundle_uri);
 
 
 /** Get the parent of all other plugin classes, lv2:Plugin.
@@ -204,7 +204,7 @@
 /** @} */
 
 #ifdef __cplusplus
-}
+} /* extern "C" */
 #endif
 
 #endif /* __SLV2_WORLD_H__ */

Index: src/plugin.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/plugin.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- src/plugin.c        7 Nov 2007 11:41:51 -0000       1.4
+++ src/plugin.c        21 Feb 2009 21:06:59 -0000      1.5
@@ -18,29 +18,32 @@
 
 #define _XOPEN_SOURCE 500
 
+#include <math.h>
 #include <string.h>
 #include <stdlib.h>
 #include <assert.h>
 #include <librdf.h>
 #include "slv2_internal.h"
-#include <slv2/plugin.h>
-#include <slv2/types.h>
-#include <slv2/util.h>
-#include <slv2/values.h>
-#include <slv2/pluginclass.h>
-#include <slv2/pluginclasses.h>
-#include <slv2/pluginuis.h>
+#include "slv2/plugin.h"
+#include "slv2/types.h"
+#include "slv2/util.h"
+#include "slv2/values.h"
+#include "slv2/pluginclass.h"
+#include "slv2/pluginclasses.h"
+#include "slv2/pluginuis.h"
 
 
-/* private */
+/* private
+ * ownership of uri is taken */
 SLV2Plugin
-slv2_plugin_new(SLV2World world, librdf_uri* uri, librdf_uri* bundle_uri, 
librdf_uri* binary_uri)
+slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* bundle_uri)
 {
+       assert(bundle_uri);
        struct _SLV2Plugin* plugin = malloc(sizeof(struct _SLV2Plugin));
        plugin->world = world;
-       plugin->plugin_uri = librdf_new_uri_from_uri(uri);
-       plugin->bundle_uri = librdf_new_uri_from_uri(bundle_uri);
-       plugin->binary_uri = librdf_new_uri_from_uri(binary_uri);
+       plugin->plugin_uri = uri;
+       plugin->bundle_uri = slv2_value_new_librdf_uri(world, bundle_uri);
+       plugin->binary_uri = NULL;
        plugin->plugin_class = NULL;
        plugin->data_uris = slv2_values_new();
        plugin->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, 
NULL);
@@ -55,13 +58,13 @@
 void
 slv2_plugin_free(SLV2Plugin p)
 {
-       librdf_free_uri(p->plugin_uri);
+       slv2_value_free(p->plugin_uri);
        p->plugin_uri = NULL;
        
-       librdf_free_uri(p->bundle_uri);
+       slv2_value_free(p->bundle_uri);
        p->bundle_uri = NULL;
        
-       librdf_free_uri(p->binary_uri);
+       slv2_value_free(p->binary_uri);
        p->binary_uri = NULL;
        
        raptor_free_sequence(p->ports);
@@ -84,40 +87,6 @@
 }
 
 
-// FIXME: ew
-librdf_query_results*
-slv2_plugin_query(SLV2Plugin plugin,
-                  const char* sparql_str);
-
-
-/*
-SLV2Plugin
-slv2_plugin_duplicate(SLV2Plugin p)
-{
-       assert(p);
-       struct _Plugin* result = malloc(sizeof(struct _Plugin));
-       result->world = p->world;
-       result->plugin_uri = librdf_new_uri_from_uri(p->plugin_uri);
-
-       //result->bundle_url = strdup(p->bundle_url);
-       result->binary_uri = strdup(p->binary_uri);
-       
-       result->data_uris = slv2_values_new();
-       for (unsigned i=0; i < slv2_values_size(p->data_uris); ++i)
-               raptor_sequence_push(result->data_uris, 
strdup(slv2_values_get_at(p->data_uris, i)));
-       
-       result->ports = raptor_new_sequence((void (*)(void*))&slv2_port_free, 
NULL);
-       for (int i=0; i < raptor_sequence_size(p->ports); ++i)
-               raptor_sequence_push(result->ports, 
slv2_port_duplicate(raptor_sequence_get_at(p->ports, i)));
-
-       result->storage = NULL;
-       result->rdf = NULL;
-
-       return result;
-}
-*/
-
-
 /** comparator for sorting */
 int
 slv2_port_compare_by_index(const void* a, const void* b)
@@ -141,8 +110,11 @@
 
        if (!p->storage) {
                assert(!p->rdf);
-               p->storage = librdf_new_storage(p->world->world, "hashes", NULL,
-                               "hash-type='memory'");
+               //p->storage = librdf_new_storage(p->world->world, "hashes", 
NULL,
+               //              "hash-type='memory'");
+               p->storage = librdf_new_storage(p->world->world, "trees", NULL, 
NULL);
+               if (!p->storage)
+                       p->storage = librdf_new_storage(p->world->world, 
"memory", NULL, NULL);
                p->rdf = librdf_new_model(p->world->world, p->storage, NULL);
        }
 
@@ -160,29 +132,32 @@
                "SELECT DISTINCT ?class WHERE { <> a ?class }";
        
        librdf_query* q = librdf_new_query(p->world->world, "sparql",
-               NULL, query, p->plugin_uri);
+               NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
        
        librdf_query_results* results = librdf_query_execute(q, p->rdf);
                
        while (!librdf_query_results_finished(results)) {
                librdf_node* class_node    = 
librdf_query_results_get_binding_value(results, 0);
                librdf_uri*  class_uri     = librdf_node_get_uri(class_node);
-               assert(class_uri);
-               const char*  class_uri_str = (const 
char*)librdf_uri_as_string(class_uri);
                
-               if ( ! librdf_uri_equals(class_uri, 
p->world->lv2_plugin_class->uri) ) {
+               SLV2Value class = slv2_value_new_librdf_uri(p->world, 
class_uri);
+               
+               if ( ! slv2_value_equals(class, 
p->world->lv2_plugin_class->uri)) {
 
                        SLV2PluginClass plugin_class = 
slv2_plugin_classes_get_by_uri(
-                                       p->world->plugin_classes, 
class_uri_str);
+                                       p->world->plugin_classes, class);
+                       
                        
                        librdf_free_node(class_node);
 
                        if (plugin_class) {
                                p->plugin_class = plugin_class;
+                               slv2_value_free(class);
                                break;
                        }
                }
 
+               slv2_value_free(class);
                librdf_query_results_next(results);
        }
        
@@ -195,76 +170,127 @@
        // Load ports
        query = (const unsigned char*)
                "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
-               "SELECT DISTINCT ?port ?symbol ?index WHERE {\n"
+               "SELECT DISTINCT ?type ?symbol ?index WHERE {\n"
                "<>    :port   ?port .\n"
-               "?port :symbol ?symbol ;\n"
+               "?port a        ?type ;\n"
+               "      :symbol  ?symbol ;\n"
                "      :index  ?index .\n"
-               "}";
+               "} ORDER BY (?index)";
        
        q = librdf_new_query(p->world->world, "sparql",
-               NULL, query, p->plugin_uri);
+               NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
        
        results = librdf_query_execute(q, p->rdf);
 
+       int num_ports = 0;
+       int last_index = -1;
+
        while (!librdf_query_results_finished(results)) {
        
-               //librdf_node* port_node = 
librdf_query_results_get_binding_value(results, 0);
+               librdf_node* type_node = 
librdf_query_results_get_binding_value(results, 0);
                librdf_node* symbol_node = 
librdf_query_results_get_binding_value(results, 1);
                librdf_node* index_node = 
librdf_query_results_get_binding_value(results, 2);
 
-               //assert(librdf_node_is_blank(port_node));
                assert(librdf_node_is_literal(symbol_node));
                assert(librdf_node_is_literal(index_node));
 
-               //const char* id = (const 
char*)librdf_node_get_blank_identifier(port_node);
                const char* symbol = (const 
char*)librdf_node_get_literal_value(symbol_node);
                const char* index = (const 
char*)librdf_node_get_literal_value(index_node);
 
-               //printf("%s: PORT: %s %s\n", p->plugin_uri, index, symbol);
+               //printf("PORT: %s %s %s\n", type, index, symbol);
+
+               const int this_index = atoi(index);
+               SLV2Port  this_port  = NULL;
                
-               // Create a new SLV2Port
-               SLV2Port port = slv2_port_new((unsigned)atoi(index), symbol);
-               raptor_sequence_push(p->ports, port);
+               // Create a new SLV2Port, and add to template
+               if (this_index == num_ports) {
+                       assert(this_index == last_index + 1);
+                       this_port = slv2_port_new(p->world, 
(unsigned)atoi(index), symbol);
+                       raptor_sequence_push(p->ports, this_port);
+                       ++num_ports;
+                       ++last_index;
+
+               // More information about a port we already created
+               } else if (this_index < num_ports) {
+                       this_port = slv2_plugin_get_port_by_index(p, 
this_index);
+               
+               // Got a port index out of whack, plugin or rasqal is broken
+               } else {
+                       fprintf(stderr, "ERROR: Found port %d immediately after 
port %d\n",
+                                       this_index, num_ports-1);
+                       fprintf(stderr, "Either the plugin %s or your version 
of rasqal is broken.\n",
+                                       slv2_value_as_uri(p->plugin_uri));
+                       fprintf(stderr, "Please report (with rasqal version): 
http://dev.drobilla.net/newticket?component=SLV2\n";);
+               }
                
+               if (this_port) {
+                       raptor_sequence_push(this_port->classes,
+                                       slv2_value_new_librdf_uri(p->world, 
librdf_node_get_uri(type_node)));
+               }
+
+               librdf_free_node(type_node);
                librdf_free_node(symbol_node);
                librdf_free_node(index_node);
                
                librdf_query_results_next(results);
        }
        
-       raptor_sequence_sort(p->ports, slv2_port_compare_by_index);
+       // Not necessary due to ORDER BY clause
+       //raptor_sequence_sort(p->ports, slv2_port_compare_by_index);
        
        librdf_free_query_results(results);
        librdf_free_query(q);
 
-       //printf("%p %s: NUM PORTS: %d\n", (void*)p, p->plugin_uri, 
slv2_plugin_get_num_ports(p));
+       // Load binary URI
+       query = (const unsigned char*)
+               "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
+               "SELECT ?binary WHERE { <> :binary ?binary . }";
+       
+       q = librdf_new_query(p->world->world, "sparql",
+               NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
+       
+       results = librdf_query_execute(q, p->rdf);
+
+       if (!librdf_query_results_finished(results)) {
+               librdf_node* binary_node = 
librdf_query_results_get_binding_value(results, 0);
+               librdf_uri* binary_uri = librdf_node_get_uri(binary_node);
+
+               SLV2Value binary = slv2_value_new_librdf_uri(p->world, 
binary_uri);
+               p->binary_uri = binary;
+
+               librdf_free_node(binary_node);
+       }
+       
+       librdf_free_query_results(results);
+       librdf_free_query(q);
 }
 
 
-const char*
+SLV2Value
 slv2_plugin_get_uri(SLV2Plugin p)
 {
        assert(p);
        assert(p->plugin_uri);
-       return (const char*)librdf_uri_as_string(p->plugin_uri);
+       return p->plugin_uri;
 }
 
 
-const char*
+SLV2Value
 slv2_plugin_get_bundle_uri(SLV2Plugin p)
 {
        assert(p);
        assert(p->bundle_uri);
-       return (const char*)librdf_uri_as_string(p->bundle_uri);
+       return p->bundle_uri;
 }
 
 
-const char*
+SLV2Value
 slv2_plugin_get_library_uri(SLV2Plugin p)
 {
        assert(p);
-       assert(p->binary_uri);
-       return (const char*)librdf_uri_as_string(p->binary_uri);
+       if (!p->binary_uri && !p->rdf)
+               slv2_plugin_load(p);
+       return p->binary_uri;
 }
 
 
@@ -309,7 +335,6 @@
                librdf_node* type_node = 
librdf_query_results_get_binding_value(results, 0);
                const char* const type_str = (const 
char*)librdf_node_get_literal_value(type_node);
                librdf_node* name_node = 
librdf_query_results_get_binding_value(results, 1);
-               //const char* const name = (const 
char*)librdf_node_get_literal_value(name_node);
                librdf_node* license_node = 
librdf_query_results_get_binding_value(results, 2);
                librdf_node* port_node = 
librdf_query_results_get_binding_value(results, 3);
 
@@ -336,7 +361,8 @@
        librdf_free_query_results(results);
 
        if ( ! (has_type && has_name && has_license && has_port) ) {
-               fprintf(stderr, "Invalid LV2 Plugin %s\n", 
slv2_plugin_get_uri(plugin));
+               fprintf(stderr, "Invalid LV2 Plugin %s\n",
+                               slv2_value_as_uri(slv2_plugin_get_uri(plugin)));
                return false;
        } else {
                return true;
@@ -344,49 +370,92 @@
 }
 
 
-char*
+SLV2Value
 slv2_plugin_get_name(SLV2Plugin plugin)
 {
-       char* result     = NULL;
-       SLV2Values prop = slv2_plugin_get_value(plugin, SLV2_QNAME, 
"doap:name");
+       SLV2Values results = slv2_plugin_get_value_by_qname_i18n(plugin, 
"doap:name");
+       SLV2Value  ret     = NULL;
        
-       // FIXME: lang? guaranteed to be the untagged one?
-       if (prop && slv2_values_size(prop) > 0) {
-               SLV2Value val = slv2_values_get_at(prop, 0);
+       if (results) {
+               SLV2Value val = slv2_values_get_at(results, 0);
                if (slv2_value_is_string(val))
-                       result = strdup(slv2_value_as_string(val));
+                       ret = slv2_value_duplicate(val);
+               slv2_values_free(results);
+       } else {
+               results = slv2_plugin_get_value_by_qname(plugin, "doap:name");
+               SLV2Value val = slv2_values_get_at(results, 0);
+               if (slv2_value_is_string(val))
+                       ret = slv2_value_duplicate(val);
+               slv2_values_free(results);
        }
 
-       if (prop)
-               slv2_values_free(prop);
-
-       return result;
+       return ret;
 }
 
 
 SLV2Values
 slv2_plugin_get_value(SLV2Plugin  p,
-                      SLV2URIType predicate_type,
-                      const char* predicate)
+                      SLV2Value  predicate)
 {
        char* query = NULL;
        
        /* Hack around broken RASQAL, full URI predicates don't work :/ */
 
-       if (predicate_type == SLV2_URI) {
+       if (predicate->type == SLV2_VALUE_URI) {
                query = slv2_strjoin(
-                       "PREFIX slv2predicate: <", predicate, ">",
+                       "PREFIX slv2predicate: <", 
slv2_value_as_string(predicate), ">",
                        "SELECT DISTINCT ?value WHERE { \n"
                        "<> slv2predicate: ?value \n"
                        "}\n", NULL);
-       } else {
+       } else if (predicate->type == SLV2_VALUE_QNAME) {
        query = slv2_strjoin(
                        "SELECT DISTINCT ?value WHERE { \n"
-                       "<> ", predicate, " ?value \n"
+                       "<> ", slv2_value_as_string(predicate), " ?value \n"
                        "}\n", NULL);
+       } else {
+               fprintf(stderr, "slv2_plugin_get_value error: "
+                               "predicate is not a URI or QNAME\n");
+               return NULL;
        }
 
-       SLV2Values result = slv2_plugin_simple_query(p, query, 0);
+       SLV2Values result = slv2_plugin_query_variable(p, query, 0);
+       
+       free(query);
+
+       return result;
+}
+
+
+/* internal */
+SLV2Values
+slv2_plugin_get_value_by_qname(SLV2Plugin  p,
+                               const char* predicate)
+{
+       char* query = slv2_strjoin(
+                       "SELECT DISTINCT ?value WHERE { \n"
+                       "<> ", predicate, " ?value . \n"
+                       "}\n", NULL);
+
+       SLV2Values result = slv2_plugin_query_variable(p, query, 0);
+       
+       free(query);
+
+       return result;
+}
+
+       
+/* internal: get i18n value if possible */
+SLV2Values
+slv2_plugin_get_value_by_qname_i18n(SLV2Plugin  p,
+                                    const char* predicate)
+{
+       char* query = slv2_strjoin(
+                       "SELECT DISTINCT ?value WHERE { \n"
+                       "<> ", predicate, " ?value . \n"
+                       "FILTER(lang(?value) = \"", slv2_get_lang(), "\") \n"
+                       "}\n", NULL);
+
+       SLV2Values result = slv2_plugin_query_variable(p, query, 0);
        
        free(query);
 
@@ -397,12 +466,11 @@
 SLV2Values
 slv2_plugin_get_value_for_subject(SLV2Plugin  p,
                                   SLV2Value   subject,
-                                  SLV2URIType predicate_type,
-                                  const char* predicate)
+                                  SLV2Value   predicate)
 {
        if ( ! slv2_value_is_uri(subject)) {
                fprintf(stderr, "slv2_plugin_get_value_for_subject error: "
-                               "passed non-URI subject\n");
+                               "subject is not a URI\n");
                return NULL;
        }
 
@@ -412,20 +480,25 @@
 
        char* subject_token = slv2_value_get_turtle_token(subject);
 
-       if (predicate_type == SLV2_URI) {
+       if (predicate->type == SLV2_VALUE_URI) {
                query = slv2_strjoin(
                        "PREFIX slv2predicate: <", predicate, ">",
                        "SELECT DISTINCT ?value WHERE { \n",
                        subject_token, " slv2predicate: ?value \n"
                        "}\n", NULL);
-       } else {
+       } else if (predicate->type == SLV2_VALUE_URI) {
        query = slv2_strjoin(
                        "SELECT DISTINCT ?value WHERE { \n",
                        subject_token, " ", predicate, " ?value \n"
                        "}\n", NULL);
+       } else {
+               fprintf(stderr, "slv2_plugin_get_value error: "
+                               "predicate is not a URI or QNAME\n");
+               free(subject_token);
+               return NULL;
        }
 
-       SLV2Values result = slv2_plugin_simple_query(p, query, 0);
+       SLV2Values result = slv2_plugin_query_variable(p, query, 0);
        
        free(query);
        free(subject_token);
@@ -437,14 +510,14 @@
 SLV2Values
 slv2_plugin_get_properties(SLV2Plugin p)
 {
-       return slv2_plugin_get_value(p, SLV2_QNAME, "lv2:pluginProperty");
+       return slv2_plugin_get_value_by_qname(p, "lv2:pluginProperty");
 }
 
 
 SLV2Values
 slv2_plugin_get_hints(SLV2Plugin p)
 {
-       return slv2_plugin_get_value(p, SLV2_QNAME, "lv2:pluginHint");
+       return slv2_plugin_get_value_by_qname(p, "lv2:pluginHint");
 }
 
 
@@ -458,17 +531,114 @@
 }
 
 
+void
+slv2_plugin_get_port_float_values(SLV2Plugin  p,
+                                  const char* qname,
+                                  float*      values)
+{
+       if (!p->rdf)
+               slv2_plugin_load(p);
+
+       const unsigned char* query;
+       librdf_query* q;
+       librdf_query_results* results;
+
+       for (int i = 0; i < raptor_sequence_size(p->ports); ++i)
+               values[i] = NAN;
+
+       query = (const unsigned char*)slv2_strjoin(
+                       "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
+                       "SELECT DISTINCT ?index ?value WHERE {\n"
+                       "<>    :port    ?port .\n"
+                       "?port :index   ?index .\n"
+                       "?port ", qname, " ?value .\n"
+                       "} ", NULL);
+
+       q = librdf_new_query(p->world->world, "sparql",
+                       NULL, query, slv2_value_as_librdf_uri(p->plugin_uri));
+
+       results = librdf_query_execute(q, p->rdf);
+
+       while (!librdf_query_results_finished(results)) {
+               librdf_node* idx_node = 
librdf_query_results_get_binding_value(results, 0);
+               librdf_node* val_node = 
librdf_query_results_get_binding_value(results, 1);
+               if (idx_node && val_node && librdf_node_is_literal(idx_node)
+                               && librdf_node_is_literal(val_node)) {
+                       const int idx = atoi((const 
char*)librdf_node_get_literal_value(idx_node));
+                       const float val = atof((const 
char*)librdf_node_get_literal_value(val_node));
+                       values[idx] = val;
+                       librdf_free_node(idx_node);
+                       librdf_free_node(val_node);
+               }
+               librdf_query_results_next(results);
+       }
+
+       librdf_free_query_results(results);
+       librdf_free_query(q);
+}
+
+
+void
+slv2_plugin_get_port_ranges_float(SLV2Plugin p, 
+                                  float*     min_values, 
+                                  float*     max_values,
+                                  float*     def_values)
+{
+       if (min_values)
+               slv2_plugin_get_port_float_values(p, ":minimum", min_values);
+
+       if (max_values)
+               slv2_plugin_get_port_float_values(p, ":maximum", max_values);
+
+       if (def_values)
+               slv2_plugin_get_port_float_values(p, ":default", def_values);
+}
+
+
+uint32_t
+slv2_plugin_get_num_ports_of_class(SLV2Plugin p,
+                                   SLV2Value  class_1, ...)
+{
+       uint32_t ret = 0;
+       va_list  args;
+
+       for (unsigned i=0; i < slv2_plugin_get_num_ports(p); ++i) {
+               SLV2Port port = raptor_sequence_get_at(p->ports, i);
+               if (!slv2_port_is_a(p, port, class_1))
+                       continue;
+
+               va_start(args, class_1);
+               
+               bool matches = true;
+               for (SLV2Value class_i = NULL; (class_i = va_arg(args, 
SLV2Value)) != NULL ; ) {
+                       if (!slv2_port_is_a(p, port, class_i)) {
+                               va_end(args);
+                               matches = false;
+                               break;
+                       }
+               }
+
+               if (matches)
+                       ++ret;
+
+               va_end(args);
+       }
+
+       return ret;
+}
+
+
 bool
 slv2_plugin_has_latency(SLV2Plugin p)
 {
     const char* const query = 
-               "SELECT DISTINCT ?index WHERE {\n"
+               "SELECT ?index WHERE {\n"
                "       <>      lv2:port         ?port .\n"
                "       ?port   lv2:portProperty lv2:reportsLatency ;\n"
                "           lv2:index        ?index .\n"
                "}\n";
 
-       SLV2Values results = slv2_plugin_simple_query(p, query, 0);
+       SLV2Values results = slv2_plugin_query_variable(p, query, 0);
        const bool latent = (slv2_values_size(results) > 0);
        slv2_values_free(results);
        
@@ -477,16 +647,16 @@
 
 
 uint32_t
-slv2_plugin_get_latency_port(SLV2Plugin p)
+slv2_plugin_get_latency_port_index(SLV2Plugin p)
 {
     const char* const query = 
-               "SELECT DISTINCT ?index WHERE {\n"
+               "SELECT ?index WHERE {\n"
                "       <>      lv2:port         ?port .\n"
                "       ?port   lv2:portProperty lv2:reportsLatency ;\n"
                "           lv2:index        ?index .\n"
                "}\n";
 
-       SLV2Values result = slv2_plugin_simple_query(p, query, 0);
+       SLV2Values result = slv2_plugin_query_variable(p, query, 0);
        
        // FIXME: need a sane error handling strategy
        assert(slv2_values_size(result) > 0);
@@ -497,17 +667,42 @@
 }
 
 
+bool
+slv2_plugin_has_feature(SLV2Plugin p,
+                        SLV2Value  feature)
+{
+       SLV2Values features = slv2_plugin_get_supported_features(p);
+       
+       const bool ret = features && feature && slv2_values_contains(features, 
feature);
+
+       slv2_values_free(features);
+       return ret;
+}
+
+
 SLV2Values
 slv2_plugin_get_supported_features(SLV2Plugin p)
 {
-    const char* const query = 
+       /* Work around broken UNION in Redland :( */
+    /*const char* const query = 
                "SELECT DISTINCT ?feature WHERE {\n"
                "       { <>  lv2:optionalFeature ?feature }\n"
                "       UNION\n"
                "       { <>  lv2:requiredFeature ?feature }\n"
                "}\n";
 
-       SLV2Values result = slv2_plugin_simple_query(p, query, 0);
+       SLV2Values result = slv2_plugin_query_variable(p, query, 0);*/
+
+       SLV2Values optional = slv2_plugin_get_optional_features(p);
+       SLV2Values required = slv2_plugin_get_required_features(p);
+       
+       SLV2Values result = slv2_values_new();
+       unsigned n_optional = slv2_values_size(optional);
+       unsigned i = 0;
+       for ( ; i < n_optional; ++i)
+               slv2_values_set_at(result, i, slv2_values_get_at(optional, i));
+       for ( ; i < n_optional + slv2_values_size(required); ++i)
+               slv2_values_set_at(result, i, slv2_values_get_at(required, i - 
n_optional));
        
        return result;
 }
@@ -516,14 +711,14 @@
 SLV2Values
 slv2_plugin_get_optional_features(SLV2Plugin p)
 {
-       return slv2_plugin_get_value(p, SLV2_QNAME, "lv2:optionalFeature");
+       return slv2_plugin_get_value_by_qname(p, "lv2:optionalFeature");
 }
 
 
 SLV2Values
 slv2_plugin_get_required_features(SLV2Plugin p)
 {
-       return slv2_plugin_get_value(p, SLV2_QNAME, "lv2:requiredFeature");
+       return slv2_plugin_get_value_by_qname(p, "lv2:requiredFeature");
 }
 
 
@@ -540,15 +735,14 @@
 
 SLV2Port
 slv2_plugin_get_port_by_symbol(SLV2Plugin  p,
-                               const char* symbol)
+                               SLV2Value  symbol)
 {
        if (!p->rdf)
                slv2_plugin_load(p);
        
-       // FIXME: sort plugins and do a binary search
        for (int i=0; i < raptor_sequence_size(p->ports); ++i) {
                SLV2Port port = raptor_sequence_get_at(p->ports, i);
-               if (!strcmp(port->symbol, symbol))
+               if (slv2_value_equals(port->symbol, symbol))
                        return port;
        }
 
@@ -556,15 +750,93 @@
 }
 
 
+SLV2Value
+slv2_plugin_get_author_name(SLV2Plugin plugin)
+{
+       SLV2Value ret = NULL;
+
+    const char* const query = 
+               "SELECT ?name WHERE {\n"
+               "       <>      doap:maintainer ?maint . \n"
+               "       ?maint  foaf:name ?name . \n"
+               "}\n";
+
+       SLV2Values results = slv2_plugin_query_variable(plugin, query, 0);
+       
+       if (results && slv2_values_size(results) > 0) {
+               SLV2Value val = slv2_values_get_at(results, 0);
+               if (slv2_value_is_string(val))
+                       ret = slv2_value_duplicate(val);
+       }
+
+       if (results)
+               slv2_values_free(results);
+
+       return ret;
+}
+
+
+SLV2Value
+slv2_plugin_get_author_email(SLV2Plugin plugin)
+{
+       SLV2Value ret = NULL;
+
+    const char* const query = 
+               "SELECT ?email WHERE {\n"
+               "       <>      doap:maintainer ?maint . \n"
+               "       ?maint  foaf:mbox ?email . \n"
+               "}\n";
+       
+       SLV2Values results = slv2_plugin_query_variable(plugin, query, 0);
+       
+       if (results && slv2_values_size(results) > 0) {
+               SLV2Value val = slv2_values_get_at(results, 0);
+               if (slv2_value_is_uri(val))
+                       ret = slv2_value_duplicate(val);
+       }
+
+       if (results)
+               slv2_values_free(results);
+
+       return ret;
+}
+
+       
+SLV2Value
+slv2_plugin_get_author_homepage(SLV2Plugin plugin)
+{
+       SLV2Value ret = NULL;
+
+    const char* const query = 
+               "SELECT ?page WHERE {\n"
+               "       <>      doap:maintainer ?maint . \n"
+               "       ?maint  foaf:homepage ?page . \n"
+               "}\n";
+       
+       SLV2Values results = slv2_plugin_query_variable(plugin, query, 0);
+       
+       if (results && slv2_values_size(results) > 0) {
+               SLV2Value val = slv2_values_get_at(results, 0);
+               if (slv2_value_is_uri(val))
+                       ret = slv2_value_duplicate(val);
+       }
+
+       if (results)
+               slv2_values_free(results);
+
+       return ret;
+}
+
+
 SLV2UIs
 slv2_plugin_get_uis(SLV2Plugin plugin)
 {
     const char* const query_str =
-               "PREFIX guiext: 
<http://ll-plugins.nongnu.org/lv2/ext/gui/dev/1#>\n"
+               "PREFIX uiext: <http://lv2plug.in/ns/extensions/ui#>\n"
                "SELECT DISTINCT ?uri ?type ?binary WHERE {\n"
-               "<>   guiext:gui    ?uri .\n"
+               "<>   uiext:ui     ?uri .\n"
                "?uri a             ?type ;\n"
-               "     guiext:binary ?binary .\n"
+               "     uiext:binary ?binary .\n"
                "}\n";
 
        librdf_query_results* results = slv2_plugin_query(plugin, query_str);
@@ -600,51 +872,3 @@
        }
 }
 
-#if 0
-SLV2Value
-slv2_plugin_get_ui_library_uri(SLV2Plugin plugin, 
-                               SLV2Value  ui)
-{
-       assert(ui->type == SLV2_VALUE_UI);
-       
-       if (!plugin->rdf)
-               slv2_plugin_load(plugin);
-
-       SLV2Values values =  slv2_plugin_get_value_for_subject(plugin, ui, 
SLV2_URI,
-                       
"http://ll-plugins.nongnu.org/lv2/ext/gui/dev/1#binary";);
-
-       if (!values || slv2_values_size(values) == 0) {
-               slv2_values_free(values);
-               return NULL;
-       }
-
-       SLV2Value value = slv2_values_get_at(values, 0);
-       if (!slv2_value_is_uri(value)) {
-               slv2_values_free(values);
-               return NULL;
-       }
-
-       value = slv2_value_duplicate(value);
-       slv2_values_free(values);
-
-       return value;
-}
-#endif
-
-
-void*
-slv2_plugin_load_ui(SLV2Plugin plugin,
-                    SLV2Value  ui)
-{
-#if 0
-       SLV2Value lib_uri = slv2_plugin_get_ui_library_uri(plugin, ui);
-
-       if (!lib_uri)
-               return NULL;
-
-       //LV2UI_Handle handle =
-       //
-#endif
-       return NULL;
-}
-

Index: src/pluginclass.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/pluginclass.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- src/pluginclass.c   7 Nov 2007 11:41:51 -0000       1.2
+++ src/pluginclass.c   21 Feb 2009 21:06:59 -0000      1.3
@@ -21,54 +21,58 @@
 #include <assert.h>
 #include <stdlib.h>
 #include <string.h>
-#include <slv2/pluginclass.h>
+#include "slv2/pluginclass.h"
+#include "slv2/value.h"
 #include "slv2_internal.h"
 
 
+/* private */
 SLV2PluginClass
-slv2_plugin_class_new(SLV2World world, const char* parent_uri, const char* 
uri, const char* label)
+slv2_plugin_class_new(SLV2World world, librdf_uri* parent_uri, librdf_uri* 
uri, const char* label)
 {
        SLV2PluginClass plugin_class = (SLV2PluginClass)malloc(sizeof(struct 
_SLV2PluginClass));
        plugin_class->world = world;
        if (parent_uri)
-               plugin_class->parent_uri = librdf_new_uri(world->world, (const 
unsigned char*)parent_uri);
+               plugin_class->parent_uri = slv2_value_new_librdf_uri(world, 
parent_uri);
        else
                plugin_class->parent_uri = NULL;
-       plugin_class->uri = librdf_new_uri(world->world, (const unsigned 
char*)uri);
-       plugin_class->label = strdup(label);
+       plugin_class->uri = slv2_value_new_librdf_uri(world, uri);
+       plugin_class->label = slv2_value_new(world, SLV2_VALUE_STRING, label);
        return plugin_class;
 }
 
 
+/* private */
 void
 slv2_plugin_class_free(SLV2PluginClass plugin_class)
 {
-       librdf_free_uri(plugin_class->uri);
-       librdf_free_uri(plugin_class->parent_uri);
-       free(plugin_class->label);
+       assert(plugin_class->uri);
+       slv2_value_free(plugin_class->uri);
+       slv2_value_free(plugin_class->parent_uri);
+       slv2_value_free(plugin_class->label);
        free(plugin_class);
 }
 
 
-const char*
+SLV2Value
 slv2_plugin_class_get_parent_uri(SLV2PluginClass plugin_class)
 {
        if (plugin_class->parent_uri)
-               return (const 
char*)librdf_uri_as_string(plugin_class->parent_uri);
+               return plugin_class->parent_uri;
        else
                return NULL;
 }
 
 
-const char*
+SLV2Value
 slv2_plugin_class_get_uri(SLV2PluginClass plugin_class)
 {
        assert(plugin_class->uri);
-       return (const char*)librdf_uri_as_string(plugin_class->uri);
+       return plugin_class->uri;
 }
 
 
-const char*
+SLV2Value
 slv2_plugin_class_get_label(SLV2PluginClass plugin_class)
 {
        return plugin_class->label;
@@ -83,8 +87,8 @@
 
        for (int i=0; i < 
raptor_sequence_size(plugin_class->world->plugin_classes); ++i) {
                SLV2PluginClass c = 
raptor_sequence_get_at(plugin_class->world->plugin_classes, i);
-               const char* parent = slv2_plugin_class_get_parent_uri(c);
-               if (parent && !strcmp(slv2_plugin_class_get_uri(plugin_class), 
parent))
+               SLV2Value parent = slv2_plugin_class_get_parent_uri(c);
+               if (parent && 
slv2_value_equals(slv2_plugin_class_get_uri(plugin_class), parent))
                        raptor_sequence_push(result, c);
        }
 

Index: src/pluginclasses.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/pluginclasses.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- src/pluginclasses.c 7 Nov 2007 11:41:51 -0000       1.3
+++ src/pluginclasses.c 21 Feb 2009 21:06:59 -0000      1.4
@@ -22,9 +22,9 @@
 #include <limits.h>
 #include <librdf.h>
 #include "slv2_internal.h"
-#include <slv2/pluginclass.h>
-#include <slv2/pluginclasses.h>
-
+#include "slv2/value.h"
+#include "slv2/pluginclass.h"
+#include "slv2/pluginclasses.h"
 
        
 SLV2PluginClasses
@@ -51,7 +51,7 @@
 
 
 SLV2PluginClass
-slv2_plugin_classes_get_by_uri(SLV2PluginClasses list, const char* uri)
+slv2_plugin_classes_get_by_uri(SLV2PluginClasses list, SLV2Value uri)
 {
        // good old fashioned binary search
        
@@ -64,7 +64,8 @@
 
                SLV2PluginClass p = raptor_sequence_get_at(list, i);
        
-               const int cmp = strcmp(slv2_plugin_class_get_uri(p), uri);
+               const int cmp = 
strcmp(slv2_value_as_uri(slv2_plugin_class_get_uri(p)),
+                                      slv2_value_as_uri(uri));
                
                if (cmp == 0)
                        return p;

Index: src/plugininstance.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/plugininstance.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- src/plugininstance.c        7 Nov 2007 11:41:51 -0000       1.4
+++ src/plugininstance.c        21 Feb 2009 21:06:59 -0000      1.5
@@ -23,27 +23,27 @@
 #include <string.h>
 #include <assert.h>
 #include <dlfcn.h>
-#include <slv2/types.h>
-#include <slv2/plugin.h>
-#include <slv2/plugininstance.h>
-#include <slv2/util.h>
+#include "slv2/types.h"
+#include "slv2/plugin.h"
+#include "slv2/plugininstance.h"
+#include "slv2/util.h"
 #include "slv2_internal.h"
 
 
 SLV2Instance
 slv2_plugin_instantiate(SLV2Plugin          plugin,
                         double              sample_rate,
-                        const LV2_Feature** features)
+                        const LV2_Feature*const* features)
 {
        struct _Instance* result = NULL;
        
-       bool local_features = (features == NULL);
-       if (local_features) {
-               features = malloc(sizeof(LV2_Feature));
-               features[0] = NULL;
+       const LV2_Feature** local_features = NULL;
+       if (features == NULL) {
+               local_features = malloc(sizeof(LV2_Feature));
+               local_features[0] = NULL;
        }
        
-       const char* const lib_uri = slv2_plugin_get_library_uri(plugin);
+       const char* const lib_uri = 
slv2_value_as_uri(slv2_plugin_get_library_uri(plugin));
        const char* const lib_path = slv2_uri_to_path(lib_uri);
        
        if (!lib_path)
@@ -67,8 +67,10 @@
                // Search for plugin by URI
                
                // FIXME: Kluge to get bundle path (containing directory of 
binary)
-               const char* bundle_path = 
slv2_uri_to_path(slv2_plugin_get_bundle_uri(plugin));
-               printf("Bundle path: %s\n", bundle_path);
+               const char* bundle_path = slv2_uri_to_path(slv2_value_as_uri(
+                                       slv2_plugin_get_bundle_uri(plugin)));
+
+               //printf("Bundle path: %s\n", bundle_path);
                
                for (uint32_t i=0; 1; ++i) {
                        
@@ -76,22 +78,23 @@
                                
                        if (!ld) {
                                fprintf(stderr, "Did not find plugin %s in 
%s\n",
-                                               slv2_plugin_get_uri(plugin), 
lib_path);
+                                               
slv2_value_as_uri(slv2_plugin_get_uri(plugin)), lib_path);
                                dlclose(lib);
                                break; // return NULL
-                       } else if (!strcmp(ld->URI, 
slv2_plugin_get_uri(plugin))) {
+                       } else if (!strcmp(ld->URI, 
slv2_value_as_uri(slv2_plugin_get_uri(plugin)))) {
                                        
                                assert(plugin->plugin_uri);
 
-                               printf("Found %s at index %u in:\n\t%s\n\n",
-                                               
librdf_uri_as_string(plugin->plugin_uri), i, lib_path);
+                               //printf("Found %s at index %u in:\n\t%s\n\n",
+                               //              
librdf_uri_as_string(plugin->plugin_uri), i, lib_path);
 
                                assert(ld->instantiate);
 
                                // Create SLV2Instance to return
                                result = malloc(sizeof(struct _Instance));
                                result->lv2_descriptor = ld;
-                               result->lv2_handle = ld->instantiate(ld, 
sample_rate, (char*)bundle_path, features);
+                result->lv2_handle = ld->instantiate(ld, sample_rate, 
(char*)bundle_path,
+                                               (features) ? features : 
local_features);
                                struct _InstanceImpl* impl = 
malloc(sizeof(struct _InstanceImpl));
                                impl->lib_handle = lib;
                                result->pimpl = impl;
@@ -116,8 +119,7 @@
                        
result->lv2_descriptor->connect_port(result->lv2_handle, i, NULL);
        }
 
-       if (local_features)
-               free(features);
+       free(local_features);
 
        return result;
 }

Index: src/plugins.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/plugins.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- src/plugins.c       7 Nov 2007 11:41:51 -0000       1.3
+++ src/plugins.c       21 Feb 2009 21:06:59 -0000      1.4
@@ -23,11 +23,11 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <librdf.h>
-#include <slv2/types.h>
-#include <slv2/plugin.h>
-#include <slv2/plugins.h>
-#include <slv2/values.h>
-#include <slv2/util.h>
+#include "slv2/types.h"
+#include "slv2/plugin.h"
+#include "slv2/plugins.h"
+#include "slv2/values.h"
+#include "slv2/util.h"
 #include "slv2_internal.h"
 
        
@@ -69,7 +69,7 @@
 
 
 SLV2Plugin
-slv2_plugins_get_by_uri(SLV2Plugins list, const char* uri)
+slv2_plugins_get_by_uri(SLV2Plugins list, SLV2Value uri)
 {
        // good old fashioned binary search
        
@@ -82,7 +82,8 @@
 
                SLV2Plugin p = raptor_sequence_get_at(list, i);
 
-               const int cmp = strcmp(slv2_plugin_get_uri(p), uri);
+               const int cmp = 
strcmp(slv2_value_as_uri(slv2_plugin_get_uri(p)),
+                                      slv2_value_as_uri(uri));
 
                if (cmp == 0)
                        return p;

Index: src/pluginui.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/pluginui.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- src/pluginui.c      7 Nov 2007 11:41:52 -0000       1.1
+++ src/pluginui.c      21 Feb 2009 21:06:59 -0000      1.2
@@ -21,7 +21,7 @@
 #include <assert.h>
 #include <string.h>
 #include <stdlib.h>
-#include <slv2/values.h>
+#include "slv2/values.h"
 #include "slv2_internal.h"
 
 
@@ -37,21 +37,21 @@
        assert(binary_uri);
 
        struct _SLV2UI* ui = malloc(sizeof(struct _SLV2UI));
-       ui->uri = librdf_new_uri_from_uri(uri);
-       ui->binary_uri = librdf_new_uri_from_uri(binary_uri);
+       ui->world = world;
+       ui->uri = slv2_value_new_librdf_uri(world, uri);
+       ui->binary_uri = slv2_value_new_librdf_uri(world, binary_uri);
        
        assert(ui->binary_uri);
        
        // FIXME: kludge
-       char* bundle = strdup((const 
char*)librdf_uri_as_string(ui->binary_uri));
+       char* bundle = strdup(slv2_value_as_string(ui->binary_uri));
        char* last_slash = strrchr(bundle, '/') + 1;
        *last_slash = '\0';
-       ui->bundle_uri = librdf_new_uri(world->world, (const unsigned 
char*)bundle);
+       ui->bundle_uri = slv2_value_new_uri(world, bundle);
        free(bundle);
 
-       ui->types = slv2_values_new();
-       raptor_sequence_push(ui->types, slv2_value_new(SLV2_VALUE_URI,
-                               (const char*)librdf_uri_as_string(type_uri)));
+       ui->classes = slv2_values_new();
+       raptor_sequence_push(ui->classes, slv2_value_new_librdf_uri(world, 
type_uri));
 
        return ui;
 }
@@ -61,61 +61,58 @@
 void
 slv2_ui_free(SLV2UI ui)
 {
-       librdf_free_uri(ui->uri);
+       slv2_value_free(ui->uri);
        ui->uri = NULL;
        
-       librdf_free_uri(ui->bundle_uri);
+       slv2_value_free(ui->bundle_uri);
        ui->bundle_uri = NULL;
        
-       librdf_free_uri(ui->binary_uri);
+       slv2_value_free(ui->binary_uri);
        ui->binary_uri = NULL;
 
-       slv2_values_free(ui->types);
+       slv2_values_free(ui->classes);
        
        free(ui);
 }
 
 
-const char*
+SLV2Value
 slv2_ui_get_uri(SLV2UI ui)
 {
        assert(ui);
        assert(ui->uri);
-       return (const char*)librdf_uri_as_string(ui->uri);
+       return ui->uri;
 }
 
 
 SLV2Values
-slv2_ui_get_types(SLV2UI ui)
+slv2_ui_get_classes(SLV2UI ui)
 {
-       return ui->types;
+       return ui->classes;
 }
 
 
 bool
-slv2_ui_is_type(SLV2UI ui, const char* type_uri)
+slv2_ui_is_a(SLV2UI ui, SLV2Value ui_class_uri)
 {
-       SLV2Value type = slv2_value_new(SLV2_VALUE_URI, type_uri);
-       bool ret = slv2_values_contains(ui->types, type);
-       slv2_value_free(type);
-       return ret;
+       return slv2_values_contains(ui->classes, ui_class_uri);
 }
 
 
-const char*
+SLV2Value
 slv2_ui_get_bundle_uri(SLV2UI ui)
 {
        assert(ui);
        assert(ui->bundle_uri);
-       return (const char*)librdf_uri_as_string(ui->bundle_uri);
+       return ui->bundle_uri;
 }
 
 
-const char*
+SLV2Value
 slv2_ui_get_binary_uri(SLV2UI ui)
 {
        assert(ui);
        assert(ui->binary_uri);
-       return (const char*)librdf_uri_as_string(ui->binary_uri);
+       return ui->binary_uri;
 }
 

Index: src/pluginuiinstance.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/pluginuiinstance.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- src/pluginuiinstance.c      7 Nov 2007 11:41:52 -0000       1.1
+++ src/pluginuiinstance.c      21 Feb 2009 21:06:59 -0000      1.2
@@ -24,11 +24,11 @@
 #include <string.h>
 #include <assert.h>
 #include <dlfcn.h>
-#include <slv2/types.h>
-#include <slv2/plugin.h>
-#include <slv2/pluginui.h>
-#include <slv2/pluginuiinstance.h>
-#include <slv2/util.h>
+#include "slv2/types.h"
+#include "slv2/plugin.h"
+#include "slv2/pluginui.h"
+#include "slv2/pluginuiinstance.h"
+#include "slv2/util.h"
 #include "slv2_internal.h"
 
 
@@ -36,9 +36,6 @@
 slv2_ui_instantiate(SLV2Plugin                     plugin,
                     SLV2UI                         ui,
                     LV2UI_Write_Function           write_function,
-                    LV2UI_Command_Function         command_function,
-                    LV2UI_Program_Change_Function  program_function,
-                    LV2UI_Program_Save_Function    save_function,
                     LV2UI_Controller               controller,
                     const LV2_Feature* const*      features)
 {
@@ -50,7 +47,7 @@
                ((LV2_Feature**)features)[0] = NULL;
        }
        
-       const char* const lib_uri = slv2_ui_get_binary_uri(ui);
+       const char* const lib_uri = 
slv2_value_as_string(slv2_ui_get_binary_uri(ui));
        const char* const lib_path = slv2_uri_to_path(lib_uri);
        
        if (!lib_path)
@@ -72,7 +69,7 @@
                return NULL;
        } else {
                
-               const char* bundle_path = 
slv2_uri_to_path(slv2_ui_get_bundle_uri(ui));
+               const char* bundle_path = 
slv2_uri_to_path(slv2_value_as_uri(slv2_ui_get_bundle_uri(ui)));
                
                for (uint32_t i=0; 1; ++i) {
                        
@@ -80,16 +77,15 @@
                                
                        if (!ld) {
                                fprintf(stderr, "Did not find UI %s in %s\n",
-                                               slv2_ui_get_uri(ui), lib_path);
+                                               
slv2_value_as_uri(slv2_ui_get_uri(ui)), lib_path);
                                dlclose(lib);
                                break; // return NULL
-                       } else if (!strcmp(ld->URI, slv2_ui_get_uri(ui))) {
-
+                       } else if (!strcmp(ld->URI, 
slv2_value_as_uri(slv2_ui_get_uri(ui)))) {
        
                                assert(plugin->plugin_uri);
 
                                printf("Found UI %s at index %u in:\n\t%s\n\n",
-                                      
librdf_uri_as_string(plugin->plugin_uri), i, lib_path);
+                                      slv2_value_as_uri(plugin->plugin_uri), 
i, lib_path);
 
                                assert(ld->instantiate);
 
@@ -98,12 +94,9 @@
                                struct _SLV2UIInstanceImpl* impl = 
malloc(sizeof(struct _SLV2UIInstanceImpl));
                                impl->lv2ui_descriptor = ld;
                                impl->lv2ui_handle = ld->instantiate(ld, 
-                                               slv2_plugin_get_uri(plugin),
+                                               
slv2_value_as_uri(slv2_plugin_get_uri(plugin)),
                                                (char*)bundle_path, 
                                                write_function,
-                                               command_function,
-                                               program_function,
-                                               save_function,
                                                controller,
                                                &impl->widget,
                                                features);
@@ -114,11 +107,9 @@
                }
        }
 
-       assert(result);
-       assert(slv2_plugin_get_num_ports(plugin) > 0);
 
        // Failed to instantiate
-       if (result->pimpl->lv2ui_handle == NULL) {
+       if (result == NULL || result->pimpl->lv2ui_handle == NULL) {
                //printf("Failed to instantiate %s\n", plugin->plugin_uri);
                free(result);
                return NULL;
@@ -141,6 +132,9 @@
 void
 slv2_ui_instance_free(SLV2UIInstance instance)
 {
+       if (instance == NULL)
+               return;
+
        struct _SLV2UIInstance* i = (struct _SLV2UIInstance*)instance;
        i->pimpl->lv2ui_descriptor->cleanup(i->pimpl->lv2ui_handle);
        i->pimpl->lv2ui_descriptor = NULL;

Index: src/pluginuis.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/pluginuis.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- src/pluginuis.c     7 Nov 2007 11:41:52 -0000       1.1
+++ src/pluginuis.c     21 Feb 2009 21:06:59 -0000      1.2
@@ -23,10 +23,10 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <librdf.h>
-#include <slv2/types.h>
-#include <slv2/pluginuis.h>
-#include <slv2/pluginui.h>
-#include <slv2/util.h>
+#include "slv2/types.h"
+#include "slv2/pluginuis.h"
+#include "slv2/pluginui.h"
+#include "slv2/util.h"
 #include "slv2_internal.h"
 
        
@@ -54,7 +54,7 @@
 
 
 SLV2UI
-slv2_uis_get_by_uri(SLV2UIs list, const char* uri)
+slv2_uis_get_by_uri(SLV2UIs list, SLV2Value uri)
 {
        // good old fashioned binary search
        
@@ -67,7 +67,8 @@
 
                SLV2UI ui = raptor_sequence_get_at(list, i);
 
-               const int cmp = strcmp(slv2_ui_get_uri(ui), uri);
+               const int cmp = strcmp(slv2_value_as_uri(slv2_ui_get_uri(ui)),
+                                      slv2_value_as_uri(uri));
 
                if (cmp == 0)
                        return ui;

Index: src/port.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/port.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- src/port.c  7 Nov 2007 11:41:52 -0000       1.4
+++ src/port.c  21 Feb 2009 21:06:59 -0000      1.5
@@ -22,20 +22,22 @@
 #include <stdio.h>
 #include <string.h>
 #include <limits.h>
-#include <slv2/port.h>
-#include <slv2/types.h>
-#include <slv2/util.h>
-#include <slv2/values.h>
+#include "slv2/port.h"
+#include "slv2/types.h"
+#include "slv2/util.h"
+#include "slv2/values.h"
+#include "slv2/scalepoints.h"
 #include "slv2_internal.h"
 
 
 /* private */
 SLV2Port
-slv2_port_new(uint32_t index, const char* symbol/*, const char* node_id*/)
+slv2_port_new(SLV2World world, uint32_t index, const char* symbol)
 {
        struct _SLV2Port* port = malloc(sizeof(struct _SLV2Port));
        port->index = index;
-       port->symbol = strdup(symbol);
+       port->symbol = slv2_value_new(world, SLV2_VALUE_STRING, symbol);
+       port->classes = slv2_values_new();
        //port->node_id = strdup(node_id);
        return port;
 }
@@ -45,8 +47,8 @@
 void
 slv2_port_free(SLV2Port port)
 {
-       free(port->symbol);
-       //free(port->node_id);
+       slv2_values_free(port->classes);
+       slv2_value_free(port->symbol);
        free(port);
 }
 
@@ -55,123 +57,131 @@
 SLV2Port
 slv2_port_duplicate(SLV2Port port)
 {
-       SLV2Port result = malloc(sizeof(struct _SLV2Port));
-       result->index = port->index;
-       result->symbol = strdup(port->symbol);
-       //result->node_id = strdup(port->node_id);
-       return result;
+       SLV2Port ret = malloc(sizeof(struct _SLV2Port));
+       ret->index = port->index;
+       ret->symbol = slv2_value_duplicate(port->symbol);
+       return ret;
 }
 
 
-SLV2PortDirection
-slv2_port_get_direction(SLV2Plugin p,
-                        SLV2Port   port)
+bool
+slv2_port_is_a(SLV2Plugin plugin,
+               SLV2Port   port,
+               SLV2Value  port_class)
 {
-       SLV2Values direction = slv2_port_get_value(p, port, "rdf:type");
-
-       SLV2PortDirection ret = SLV2_PORT_DIRECTION_UNKNOWN;
-
-       if (!direction)
-               return ret;
-
-       for (unsigned i=0; i < slv2_values_size(direction); ++i) {
-               SLV2Value val = slv2_values_get_at(direction, i);
-               if (slv2_value_is_uri(val)) {
-                       const char* uri = slv2_value_as_uri(val);
-                       if (!strcmp(uri, 
"http://lv2plug.in/ns/lv2core#InputPort";))
-                               ret = SLV2_PORT_DIRECTION_INPUT;
-                       else if (!strcmp(uri, 
"http://lv2plug.in/ns/lv2core#OutputPort";))
-                               ret = SLV2_PORT_DIRECTION_OUTPUT;
-               }
-       }
-       
-       slv2_values_free(direction);
+       for (unsigned i=0; i < slv2_values_size(port->classes); ++i)
+               if (slv2_value_equals(slv2_values_get_at(port->classes, i), 
port_class))
+                       return true;
 
-       return ret;
+       return false;
 }
 
 
-SLV2PortDataType
-slv2_port_get_data_type(SLV2Plugin p,
-                        SLV2Port   port)
+bool
+slv2_port_has_property(SLV2Plugin p,
+                       SLV2Port   port,
+                       SLV2Value  property)
 {
-       SLV2Values type = slv2_port_get_value(p, port, "rdf:type");
+       assert(property);
 
-       SLV2PortDataType ret = SLV2_PORT_DATA_TYPE_UNKNOWN;
+       SLV2Values results = NULL;
 
-       if (!type)
-               return ret;
+       char* query = slv2_strjoin(
+                       "SELECT DISTINCT ?port WHERE {\n"
+                       "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port 
?port ."
+                       "?port lv2:symbol \"", 
slv2_value_as_string(port->symbol), "\";\n",
+                       "      lv2:portProperty <", 
slv2_value_as_uri(property), "> .\n}", NULL);
        
-       for (unsigned i=0; i < slv2_values_size(type); ++i) {
-               SLV2Value val = slv2_values_get_at(type, i);
-               if (slv2_value_is_uri(val)) {
-                       const char* uri = slv2_value_as_uri(val);
-                       if (!strcmp(uri, 
"http://lv2plug.in/ns/lv2core#ControlPort";))
-                               ret = SLV2_PORT_DATA_TYPE_CONTROL;
-                       else if (!strcmp(uri, 
"http://lv2plug.in/ns/lv2core#AudioPort";))
-                               ret = SLV2_PORT_DATA_TYPE_AUDIO;
-                       else if (!strcmp(uri, 
"http://ll-plugins.nongnu.org/lv2/ext/MidiPort";))
-                               ret = SLV2_PORT_DATA_TYPE_MIDI;
-                       else if (!strcmp(uri, 
"http://drobilla.net/ns/lv2ext/osc/0#OSCPort";))
-                               ret = SLV2_PORT_DATA_TYPE_OSC;
-               }
-       }
+       results = slv2_plugin_query_variable(p, query, 0);
+
+       const bool ret = (slv2_values_size(results) > 0);
 
-       slv2_values_free(type);
+       free(query);
+       free(results);
 
        return ret;
 }
 
-#if 0
+
 bool
-slv2_port_has_property(SLV2Plugin p,
+slv2_port_supports_event(SLV2Plugin p,
                        SLV2Port   port,
-                       SLV2Value  hint)
+                         SLV2Value  event)
 {
-       /* FIXME: Add SLV2Value QName stuff to make this not suck to use */
+       assert(event);
 
-       SLV2Values hints = slv2_port_get_value(p, port, "lv2:portHint");
+       char* query = slv2_strjoin(
+                       "ASK WHERE {\n"
+                       "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port 
?port ."
+                       "?port lv2:symbol \"", 
slv2_value_as_string(port->symbol), "\";\n",
+                       "      lv2ev:supportsEvent <", 
slv2_value_as_uri(event), "> .\n"
+                       "}", NULL);
 
-       if (!hints)
-               return false;
+       librdf_query_results* results = slv2_plugin_query(p, query);
+       assert(librdf_query_results_is_boolean(results));
        
-       for (unsigned i=0; i < slv2_values_size(type); ++i) {
-               const SLV2Value val = slv2_values_get_at(type, i);
-               if (slv2_value_is_uri(val)) {
-                       const char* uri = slv2_value_as_uri(val);
-                       if (!strcmp(uri, 
"http://lv2plug.in/ns/lv2core#connectionOptional";))
-                               return true;
-                               ret = SLV2_PORT_DATA_TYPE_CONTROL;
-                       else if (!strcmp(uri, 
"http://lv2plug.in/ns/lv2core#AudioPort";))
-                               ret = SLV2_PORT_DATA_TYPE_AUDIO;
-                       else if (!strcmp(uri, 
"http://ll-plugins.nongnu.org/lv2/ext/MidiPort";))
-                               ret = SLV2_PORT_DATA_TYPE_MIDI;
-                       else if (!strcmp(uri, 
"http://drobilla.net/ns/lv2ext/osc/0#OSCPort";))
-                               ret = SLV2_PORT_DATA_TYPE_OSC;
-               }
-       }
+       const bool ret = librdf_query_results_get_boolean(results);
 
-       slv2_values_free(type);
+       free(query);
+       librdf_free_query_results(results);
 
        return ret;
 }
-#endif
+
 
 SLV2Values
-slv2_port_get_value(SLV2Plugin  p,
+slv2_port_get_value_by_qname(SLV2Plugin  p,
                     SLV2Port    port,
                     const char* property)
 {
        assert(property);
-
-       SLV2Values result = NULL;
+       SLV2Values results = NULL;
 
        char* query = slv2_strjoin(
                        "SELECT DISTINCT ?value WHERE {\n"
-                       "?port lv2:symbol \"", port->symbol, "\";\n\t",
-                              property, " ?value .\n}", 0);
+                       "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port 
?port .\n"
+                       "?port lv2:symbol \"", 
slv2_value_as_string(port->symbol), "\";\n\t",
+                       property, " ?value .\n"
+                       "FILTER(lang(?value) = \"\") }", NULL);
                        
-       result = slv2_plugin_simple_query(p, query, 0);
+       results = slv2_plugin_query_variable(p, query, 0);
+
+       free(query);
+       return results;
+}
+
+
+SLV2Values
+slv2_port_get_value(SLV2Plugin p,
+                    SLV2Port   port,
+                    SLV2Value  predicate)
+{
+       char* query = NULL;
+       
+       /* Hack around broken RASQAL, full URI predicates don't work :/ */
+
+       if (predicate->type == SLV2_VALUE_URI) {
+               query = slv2_strjoin(
+                       "PREFIX slv2predicate: <", 
slv2_value_as_string(predicate), ">",
+                       "SELECT DISTINCT ?value WHERE { \n"
+                       "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port 
?port .\n"
+                       "?port lv2:symbol \"", 
slv2_value_as_string(port->symbol), "\";\n\t",
+                               " slv2predicate: ?value .\n"
+                       "}\n", NULL);
+       } else if (predicate->type == SLV2_VALUE_QNAME) {
+       query = slv2_strjoin(
+                       "SELECT DISTINCT ?value WHERE { \n"
+                       "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port 
?port .\n"
+                       "?port lv2:symbol \"", 
slv2_value_as_string(port->symbol), "\";\n\t",
+                               slv2_value_as_string(predicate), " ?value .\n"
+                       "}\n", NULL);
+       } else {
+               fprintf(stderr, "slv2_port_get_value error: "
+                               "predicate is not a URI or QNAME\n");
+               return NULL;
+       }
+
+       SLV2Values result = slv2_plugin_query_variable(p, query, 0);
 
        free(query);
        
@@ -179,95 +189,163 @@
 }
 
 
-char*
-slv2_port_get_symbol(SLV2Plugin p,
-                     SLV2Port   port)
+SLV2Values
+slv2_port_get_value_by_qname_i18n(SLV2Plugin  p,
+                                  SLV2Port    port,
+                                  const char* property)
 {
-       char* symbol = NULL;
+       assert(property);
+       SLV2Values results = NULL;
+
+       char* query = slv2_strjoin(
+                       "SELECT DISTINCT ?value WHERE {\n"
+                       "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port 
?port .\n"
+                       "?port lv2:symbol \"", 
slv2_value_as_string(port->symbol), "\";\n\t",
+                       property, " ?value .\n"
+                       "FILTER(lang(?value) = \"", slv2_get_lang(), 
+                       "\") }", NULL);
        
-       SLV2Values result = slv2_port_get_value(p, port, "lv2:symbol");
+       results = slv2_plugin_query_variable(p, query, 0);
 
-       if (result && slv2_values_size(result) == 1)
-               symbol = strdup(slv2_value_as_string(slv2_values_get_at(result, 
0)));
+       free(query);
+       return results;
+}
        
-       slv2_values_free(result);
 
-       return symbol;
+SLV2Value
+slv2_port_get_symbol(SLV2Plugin p,
+                     SLV2Port   port)
+{
+       return port->symbol;
 }
 
        
-char*
+SLV2Value
 slv2_port_get_name(SLV2Plugin p,
                    SLV2Port   port)
 {
-       char* name = NULL;
+       SLV2Value  ret     = NULL;
+       SLV2Values results = slv2_port_get_value_by_qname_i18n(p, port, 
"lv2:name");
        
-       SLV2Values result = slv2_port_get_value(p, port, "lv2:name");
-
-       if (result && slv2_values_size(result) == 1)
-               name = strdup(slv2_value_as_string(slv2_values_get_at(result, 
0)));
+       if (results && slv2_values_size(results) > 0) {
+               ret = slv2_value_duplicate(slv2_values_get_at(results, 0));
+       } else {
+               results = slv2_port_get_value_by_qname(p, port, "lv2:name");
+               if (results && slv2_values_size(results) > 0)
+                       ret = slv2_value_duplicate(slv2_values_get_at(results, 
0));
+       }
        
-       slv2_values_free(result);
+       slv2_values_free(results);
 
-       return name;
+       return ret;
 }
 
 
-float
-slv2_port_get_default_value(SLV2Plugin p, 
+SLV2Values
+slv2_port_get_classes(SLV2Plugin p,
                             SLV2Port   port)
 {
-       float value = 0.0f;
+       return port->classes;
+}
        
-       SLV2Values result = slv2_port_get_value(p, port, "lv2:default");
 
-       if (result && slv2_values_size(result) == 1)
-               value = slv2_value_as_float(slv2_values_get_at(result, 0));
+void
+slv2_port_get_range(SLV2Plugin p, 
+                    SLV2Port   port,
+                    SLV2Value* def,
+                    SLV2Value* min,
+                    SLV2Value* max)
+{
+       if (def)
+               *def = NULL;
+       if (min)
+               *min = NULL;
+       if (max)
+               *max = NULL;
        
-       slv2_values_free(result);
+       char* query = slv2_strjoin(
+                       "SELECT DISTINCT ?def ?min ?max WHERE {\n"
+                       "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port 
?port .\n"
+                       "?port lv2:symbol \"", 
slv2_value_as_string(port->symbol), "\".\n",
+                       "OPTIONAL { ?port lv2:default ?def }\n",
+                       "OPTIONAL { ?port lv2:minimum ?min }\n",
+                       "OPTIONAL { ?port lv2:maximum ?max }\n",
+                       "\n}", NULL);
+       
+       librdf_query_results* results = slv2_plugin_query(p, query);
+
+    while (!librdf_query_results_finished(results)) {
+               librdf_node* def_node = 
librdf_query_results_get_binding_value(results, 0);
+               librdf_node* min_node = 
librdf_query_results_get_binding_value(results, 1);
+               librdf_node* max_node = 
librdf_query_results_get_binding_value(results, 2);
+
+               if (def && def_node && !*def)
+                       *def = slv2_value_new_librdf_node(p->world, def_node);
+               if (min && min_node && !*min)
+                       *min = slv2_value_new_librdf_node(p->world, min_node);
+               if (max && max_node && !*max)
+                       *max = slv2_value_new_librdf_node(p->world, max_node);
 
-       return value;
+               if ((!def || *def) && (!min || *min) && (!max || *max))
+                       break;
+
+               librdf_query_results_next(results);
+       }
+                       
+       librdf_free_query_results(results);
+
+       free(query);
 }
 
 
-float
-slv2_port_get_minimum_value(SLV2Plugin p, 
+SLV2ScalePoints
+slv2_port_get_scale_points(SLV2Plugin p,
                             SLV2Port   port)
 {
-       float value = 0.0f;
+       char* query = slv2_strjoin(
+                       "SELECT DISTINCT ?value ?label WHERE {\n"
+                       "<", slv2_value_as_uri(p->plugin_uri), "> lv2:port 
?port .\n"
+                       "?port  lv2:symbol \"", 
slv2_value_as_string(port->symbol), "\" ;\n",
+                       "       lv2:scalePoint ?point .\n"
+                       "?point rdf:value ?value ;\n"
+                       "       rdfs:label ?label .\n"
+                       "\n} ORDER BY ?value", NULL);
        
-       SLV2Values result = slv2_port_get_value(p, port, "lv2:minimum");
+       librdf_query_results* results = slv2_plugin_query(p, query);
 
-       if (result && slv2_values_size(result) == 1)
-               value = slv2_value_as_float(slv2_values_get_at(result, 0));
+       SLV2ScalePoints ret = NULL;
        
-       slv2_values_free(result);
+    if (!librdf_query_results_finished(results))
+               ret = slv2_scale_points_new();
 
-       return value;
-}
+    while (!librdf_query_results_finished(results)) {
 
+               librdf_node* value_node = 
librdf_query_results_get_binding_value(results, 0);
+               librdf_node* label_node = 
librdf_query_results_get_binding_value(results, 1);
 
-float
-slv2_port_get_maximum_value(SLV2Plugin p, 
-                            SLV2Port   port)
-{
-       float value = 0.0f;
+               SLV2Value value = slv2_value_new_librdf_node(p->world, 
value_node);
+               SLV2Value label = slv2_value_new_librdf_node(p->world, 
label_node);
+
+               raptor_sequence_push(ret, slv2_scale_point_new(value, label));
        
-       SLV2Values result = slv2_port_get_value(p, port, "lv2:maximum");
+               librdf_query_results_next(results);
+       }
+                       
+       librdf_free_query_results(results);
 
-       if (result && slv2_values_size(result) == 1)
-               value = slv2_value_as_float(slv2_values_get_at(result, 0));
+       free(query);
        
-       slv2_values_free(result);
+       assert(!ret || slv2_values_size(ret) > 0);
 
-       return value;
+       return ret;
 }
 
 
+
 SLV2Values
 slv2_port_get_properties(SLV2Plugin p,
                          SLV2Port   port)
 {
-       return slv2_port_get_value(p, port, "lv2:portProperty");
+       return slv2_port_get_value_by_qname(p, port, "lv2:portProperty");
 }
 

Index: src/query.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/query.c,v
retrieving revision 1.4
retrieving revision 1.5
diff -u -b -r1.4 -r1.5
--- src/query.c 7 Nov 2007 11:41:52 -0000       1.4
+++ src/query.c 21 Feb 2009 21:06:59 -0000      1.5
@@ -21,10 +21,11 @@
 #include <stdlib.h>
 #include <assert.h>
 #include <librdf.h>
+#include <locale.h>
 #include <limits.h>
-#include <slv2/plugin.h>
-#include <slv2/util.h>
-#include <slv2/values.h>
+#include "slv2/plugin.h"
+#include "slv2/util.h"
+#include "slv2/values.h"
 #include "slv2_internal.h"
 
 
@@ -32,33 +33,19 @@
        "PREFIX rdf:    <http://www.w3.org/1999/02/22-rdf-syntax-ns#>\n"
        "PREFIX rdfs:   <http://www.w3.org/2000/01/rdf-schema#>\n"
        "PREFIX doap:   <http://usefulinc.com/ns/doap#>\n"
-       "PREFIX lv2:    <http://lv2plug.in/ns/lv2core#>\n";
+       "PREFIX foaf:   <http://xmlns.com/foaf/0.1/>\n"
+       "PREFIX lv2:    <http://lv2plug.in/ns/lv2core#>\n"
+       "PREFIX lv2ev:  <http://lv2plug.in/ns/ext/event#>\n";
 
-#if 0
-char*
-slv2_query_lang_filter(const char* variable)
-{
-       char* result = NULL;
-       char* const lang = (char*)getenv("LANG");
-       if (lang) {
-               // FILTER( LANG(?value) = "en" || LANG(?value) = "" )
-               result = slv2_strjoin(
-                       //"FILTER (lang(?value) = \"", lang, "\"\n"), 0);
-                       "FILTER( lang(?", variable, ") = \"", lang, 
-                       "\" || lang(?", variable, ") = \"\" )\n", NULL);
-       }
-
-       return result;
-}
-#endif
 
 SLV2Values
-slv2_query_get_variable_bindings(librdf_query_results* results,
+slv2_query_get_variable_bindings(SLV2World             world,
+                                 librdf_query_results* results,
                                  int                   variable)
 {
        SLV2Values result = NULL;
 
-    if (librdf_query_results_get_bindings_count(results) > 0)
+    if (!librdf_query_results_finished(results))
                result = slv2_values_new();
 
     while (!librdf_query_results_finished(results)) {
@@ -66,16 +53,23 @@
         librdf_node* node =
             librdf_query_results_get_binding_value(results, variable);
                
+               if (!node) {
+                       fprintf(stderr, "SLV2 ERROR: Variable %d bound to 
NULL.\n", variable);
+               librdf_query_results_next(results);
+                       continue;
+               }
+               
                librdf_uri* datatype_uri = NULL;
                SLV2ValueType type = SLV2_VALUE_STRING;
                
+               librdf_uri* uri_val = NULL;
                const char* str_val = NULL;
 
                switch (librdf_node_get_type(node)) {
                case LIBRDF_NODE_TYPE_RESOURCE:
                        type = SLV2_VALUE_URI;
-                       assert(librdf_node_get_uri(node));
-                       str_val = (const 
char*)librdf_uri_as_string(librdf_node_get_uri(node));
+                       uri_val = librdf_node_get_uri(node);
+                       assert(uri_val);
                        break;
                case LIBRDF_NODE_TYPE_LITERAL:
                        datatype_uri = 
librdf_node_get_literal_value_datatype_uri(node);
@@ -100,8 +94,10 @@
                        break;
                }
                        
-               if (str_val)
-                       raptor_sequence_push(result, slv2_value_new(type, 
str_val));
+               if (uri_val)
+                       raptor_sequence_push(result, 
slv2_value_new_librdf_uri(world, uri_val));
+               else if (str_val)
+                       raptor_sequence_push(result, slv2_value_new(world, 
type, str_val));
 
                librdf_free_node(node);
 
@@ -133,7 +129,7 @@
        if (!plugin->rdf)
                slv2_plugin_load(plugin);
 
-       librdf_uri* base_uri = plugin->plugin_uri;
+       librdf_uri* base_uri = slv2_value_as_librdf_uri(plugin->plugin_uri);
 
        char* query_str = slv2_strjoin(slv2_query_prefixes, sparql_str, NULL);
 
@@ -147,7 +143,14 @@
                return NULL;
        }
        
+       // FIXME: locale kludges to work around librdf bug
+       char* locale = strdup(setlocale(LC_NUMERIC, NULL));
+
+       setlocale(LC_NUMERIC, "POSIX");
        librdf_query_results* results = librdf_query_execute(query, 
plugin->rdf);
+       setlocale(LC_NUMERIC, locale);
+       
+       free(locale);
        
        librdf_free_query(query);
        free(query_str);
@@ -158,7 +161,7 @@
 
 /** Query a single variable */
 SLV2Values
-slv2_plugin_simple_query(SLV2Plugin  plugin,
+slv2_plugin_query_variable(SLV2Plugin  plugin,
                          const char* sparql_str,
                          unsigned    variable)
 {
@@ -166,7 +169,7 @@
 
        librdf_query_results* results = slv2_plugin_query(plugin, sparql_str);
 
-       SLV2Values ret = slv2_query_get_variable_bindings(results, 
(int)variable);
+       SLV2Values ret = slv2_query_get_variable_bindings(plugin->world, 
results, (int)variable);
        
        librdf_free_query_results(results);
 
@@ -178,6 +181,9 @@
  *
  * More efficient than slv2_plugin_simple_query if you're only interested
  * in the number of results (ie slv2_plugin_num_ports).
+ * 
+ * Note the result of this function is probably meaningless unless the query
+ * is a SELECT DISTINCT.
  */
 unsigned
 slv2_plugin_query_count(SLV2Plugin  plugin,
@@ -195,31 +201,3 @@
        return ret;
 }
 
-/*
-size_t
-slv2_query_count_results(SLV2Plugin  p,
-                         const char* query)
-{
-       char* query_str = slv2_strjoin(slv2_query_prefixes, query, NULL);
-
-       assert(p);
-       assert(query_str);
-
-       librdf_query *rq = librdf_new_query(p->world->world, "sparql", NULL,
-                       (unsigned char*)query_str, NULL);
-
-       //printf("Query: \n%s\n\n", query_str);
-
-       librdf_query_results* results = librdf_query_execute(rq, 
p->world->model);
-       assert(results);
-       
-       size_t count = slv2_query_count_bindings(results);
-       
-       librdf_free_query_results(results);
-       librdf_free_query(rq);
-       
-       free(query_str);
-
-       return count;
-}
-*/

Index: src/slv2_internal.h
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/slv2_internal.h,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- src/slv2_internal.h 7 Nov 2007 11:41:52 -0000       1.3
+++ src/slv2_internal.h 21 Feb 2009 21:06:59 -0000      1.4
@@ -25,10 +25,11 @@
 
 #include <stdbool.h>
 #include <stddef.h>
+#include <stdlib.h>
 #include <inttypes.h>
 #include <librdf.h>
-#include <slv2/types.h>
-#include <slv2/lv2_gui.h>
+#include "slv2/types.h"
+#include "slv2/lv2_ui.h"
 
 
 
@@ -37,12 +38,13 @@
 
 /** Reference to a port on some plugin. */
 struct _SLV2Port {
-       uint32_t index;  ///< LV2 index
-       char*    symbol; ///< LV2 symbol
+       uint32_t   index;   ///< lv2:index
+       SLV2Value  symbol;  ///< lv2:symbol
+       SLV2Values classes; ///< rdf:type
 };
 
 
-SLV2Port slv2_port_new(uint32_t index, const char* symbol);
+SLV2Port slv2_port_new(SLV2World world, uint32_t index, const char* symbol);
 SLV2Port slv2_port_duplicate(SLV2Port port);
 void     slv2_port_free(SLV2Port port);
 
@@ -58,9 +60,9 @@
  */
 struct _SLV2Plugin {
        struct _SLV2World*   world;
-       librdf_uri*      plugin_uri;
-       librdf_uri*      bundle_uri; ///< Bundle directory plugin was loaded 
from
-       librdf_uri*      binary_uri; ///< lv2:binary
+       SLV2Value            plugin_uri;
+       SLV2Value            bundle_uri; ///< Bundle directory plugin was 
loaded from
+       SLV2Value            binary_uri; ///< lv2:binary
        SLV2PluginClass  plugin_class;
        raptor_sequence* data_uris;  ///< rdfs::seeAlso
        raptor_sequence* ports;
@@ -68,9 +70,12 @@
        librdf_model*    rdf;
 };
 
-SLV2Plugin slv2_plugin_new(SLV2World world, librdf_uri* uri, librdf_uri* 
bundle_uri, librdf_uri* binary_uri);
+SLV2Plugin slv2_plugin_new(SLV2World world, SLV2Value uri, librdf_uri* 
bundle_uri);
 void       slv2_plugin_load(SLV2Plugin p);
 void       slv2_plugin_free(SLV2Plugin plugin);
+void       slv2_plugin_get_port_float_values(SLV2Plugin  p,
+                                            const char* qname,
+                                            float*      values);
 
 librdf_query_results* slv2_plugin_query(SLV2Plugin  plugin,
                                         const char* sparql_str);
@@ -112,13 +117,13 @@
 
 struct _SLV2PluginClass {
        struct _SLV2World* world;
-       librdf_uri*        parent_uri;
-       librdf_uri*        uri;
-       char*              label;
+       SLV2Value          parent_uri;
+       SLV2Value          uri;
+       SLV2Value          label;
 };
 
-SLV2PluginClass slv2_plugin_class_new(SLV2World world, const char* parent_uri,
-                                      const char* uri, const char* label);
+SLV2PluginClass slv2_plugin_class_new(SLV2World world, librdf_uri* parent_uri,
+                                      librdf_uri* uri, const char* label);
 void slv2_plugin_class_free(SLV2PluginClass plugin_class);
 
 
@@ -147,6 +152,8 @@
        librdf_node*      lv2_specification_node;
        librdf_node*      lv2_plugin_node;
        librdf_node*      rdf_a_node;
+       librdf_node*      xsd_integer_node;
+       librdf_node*      xsd_decimal_node;
 };
 
 /** Load all bundles found in \a search_path.
@@ -173,10 +180,11 @@
 /* ********* Plugin UI ********* */
 
 struct _SLV2UI {
-       librdf_uri* uri;
-       librdf_uri* bundle_uri;
-       librdf_uri* binary_uri;
-       SLV2Values  types;
+       struct _SLV2World* world;
+       SLV2Value          uri;
+       SLV2Value          bundle_uri;
+       SLV2Value          binary_uri;
+       SLV2Values         classes;
 };
 
 SLV2UIs slv2_uis_new();
@@ -191,9 +199,9 @@
 
 /* ********* Value ********* */
 
-
 typedef enum _SLV2ValueType {
        SLV2_VALUE_URI,
+       SLV2_VALUE_QNAME,
        SLV2_VALUE_STRING,
        SLV2_VALUE_INT,
        SLV2_VALUE_FLOAT,
@@ -205,11 +213,39 @@
        union {
                int   int_val;
                float float_val;
+               librdf_uri* uri_val;
        } val;
 };
 
-SLV2Value slv2_value_new(SLV2ValueType type, const char* val);
+SLV2Value   slv2_value_new(SLV2World world, SLV2ValueType type, const char* 
val);
+SLV2Value   slv2_value_new_librdf_node(SLV2World world, librdf_node* node);
+SLV2Value   slv2_value_new_librdf_uri(SLV2World world, librdf_uri* uri);
+void        slv2_value_set_numerics_from_string(SLV2Value val);
+librdf_uri* slv2_value_as_librdf_uri(SLV2Value value);
+
+       
+/* ********* Values ********* */
+
+void slv2_values_set_at(SLV2Values list, unsigned index, void* value);
+
+
+/* ********* Scale Points ********* */
+
+struct _SLV2ScalePoint {
+       SLV2Value value;
+       SLV2Value label;
+};
+
+SLV2ScalePoint slv2_scale_point_new(SLV2Value value, SLV2Value label);
+void           slv2_scale_point_free(SLV2ScalePoint point);
+
+
+/* String utility functions */
+
+char* slv2_strjoin(const char* first, ...);
 
+/* I18N utility functions */
+char* slv2_get_lang();
 
 
 #ifdef __cplusplus

Index: src/util.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/util.c,v
retrieving revision 1.1
retrieving revision 1.2
diff -u -b -r1.1 -r1.2
--- src/util.c  23 Apr 2007 11:59:22 -0000      1.1
+++ src/util.c  21 Feb 2009 21:06:59 -0000      1.2
@@ -22,26 +22,14 @@
 #include <string.h>
 #include <assert.h>
 #include <stdarg.h>
-#include <slv2/util.h>
-
-
-void
-slv2_strappend(char** dst, const char* suffix)
-{
-       assert(dst);
-       assert(*dst);
-       assert(suffix);
-
-       const size_t new_length = strlen((char*)*dst) + strlen((char*)suffix) + 
1;
-       *dst = realloc(*dst, (new_length * sizeof(char)));
-       assert(dst);
-       strcat((char*)*dst, (char*)suffix);
-}
+#include "slv2/util.h"
 
 
 char*
 slv2_strjoin(const char* first, ...)
 {
+       /* FIXME: This is, in fact, as stupid as it looks */
+
        size_t  len    = strlen(first);
        char*   result = NULL;
        va_list args;
@@ -83,4 +71,27 @@
 }
 
 
+char* 
+slv2_get_lang()
+{
+       static char lang[32];
+       lang[31] = '\0';
+       char* tmp = getenv("LANG");
+       if (!tmp) {
+               lang[0] = '\0';
+       } else {
+               strncpy(lang, tmp, 31);
+               for (int i = 0; i < 31 && lang[i]; ++i) {
+                       if (lang[i] == '_') {
+                               lang[i] = '-';
+                       } else if (   !(lang[i] >= 'a' && lang[i] <= 'z')
+                                  && !(lang[i] >= 'A' && lang[i] <= 'Z')) {
+                               lang[i] = '\0';
+                               break;
+                       }
+               }
+       }
+
+       return lang;
+}
 

Index: src/value.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/value.c,v
retrieving revision 1.3
retrieving revision 1.4
diff -u -b -r1.3 -r1.4
--- src/value.c 7 Nov 2007 11:41:52 -0000       1.3
+++ src/value.c 21 Feb 2009 21:06:59 -0000      1.4
@@ -21,50 +21,139 @@
 #include <stdlib.h>
 #include <string.h>
 #include <assert.h>
+#include <locale.h>
 #include <raptor.h>
-#include <slv2/value.h>
+#include "slv2/value.h"
 #include "slv2_internal.h"
 
 
 /* private */
 SLV2Value
-slv2_value_new(SLV2ValueType type, const char* str)
+slv2_value_new(SLV2World world, SLV2ValueType type, const char* str)
 {
        SLV2Value val = (SLV2Value)malloc(sizeof(struct _SLV2Value));
-       val->str_val = strdup(str);
        val->type = type;
 
-       //printf("New value, t=%d, %s\n", type, str);
+       if (type == SLV2_VALUE_URI) {
+               val->val.uri_val = librdf_new_uri(world->world, (const unsigned 
char*)str);
+               if (val->val.uri_val)
+                       val->str_val = 
(char*)librdf_uri_as_string(val->val.uri_val);
+               else
+                       return NULL;
+       } else {
+               val->str_val = strdup(str);
+       }
+
+       slv2_value_set_numerics_from_string(val);
+
+       return val;
+}
+
+
+/* private */
+void
+slv2_value_set_numerics_from_string(SLV2Value val)
+{
+       if (!val)
+               return;
 
-       if (type == SLV2_VALUE_INT) {
+       // FIXME: locale kludges to work around librdf bug
+       char* locale = strdup(setlocale(LC_NUMERIC, NULL));
+
+       if (val->type == SLV2_VALUE_INT) {
                char* endptr = 0;
-               val->val.int_val = strtol(str, &endptr, 10);
-       } else if (type == SLV2_VALUE_FLOAT) {
+               setlocale(LC_NUMERIC, "POSIX");
+               val->val.int_val = strtol(val->str_val, &endptr, 10);
+               setlocale(LC_NUMERIC, locale);
+       } else if (val->type == SLV2_VALUE_FLOAT) {
                char* endptr = 0;
-               val->val.float_val = strtod(str, &endptr);
-       } else {
-               val->val.int_val = 0;
+               setlocale(LC_NUMERIC, "POSIX");
+               val->val.float_val = strtod(val->str_val, &endptr);
+               setlocale(LC_NUMERIC, locale);
+       }
+       
+       free(locale);
+}
+
+
+/* private */
+SLV2Value
+slv2_value_new_librdf_node(SLV2World world, librdf_node* node)
+{
+       SLV2Value val = (SLV2Value)malloc(sizeof(struct _SLV2Value));
+       val->type = SLV2_VALUE_STRING;
+       val->str_val = NULL;
+       
+       librdf_uri* datatype_uri = NULL;
+
+       switch (librdf_node_get_type(node)) {
+       case LIBRDF_NODE_TYPE_RESOURCE:
+               val->type = SLV2_VALUE_URI;
+               val->val.uri_val = librdf_node_get_uri(node);
+               val->str_val = (char*)librdf_uri_as_string(val->val.uri_val);
+               break;
+       case LIBRDF_NODE_TYPE_LITERAL:
+               datatype_uri = librdf_node_get_literal_value_datatype_uri(node);
+               if (datatype_uri) {
+                       if (librdf_uri_equals(datatype_uri, 
librdf_node_get_uri(world->xsd_integer_node)))
+                               val->type = SLV2_VALUE_INT;
+                       else if (librdf_uri_equals(datatype_uri, 
librdf_node_get_uri(world->xsd_decimal_node)))
+                               val->type = SLV2_VALUE_FLOAT;
+                       else
+                               fprintf(stderr, "Unknown datatype %s\n", 
librdf_uri_as_string(datatype_uri));
+               }
+               val->str_val = 
strdup((char*)librdf_node_get_literal_value(node));
+               break;
+       case LIBRDF_NODE_TYPE_BLANK:
+       case LIBRDF_NODE_TYPE_UNKNOWN:
+       default:
+               fprintf(stderr, "slv2_value_new_librdf_node error: Unknown node 
type.");
+               free(val);
+               val = NULL;
+               break;
        }
 
+       slv2_value_set_numerics_from_string(val);
        return val;
 }
 
 
-/*
+/* private */
 SLV2Value
-slv2_value_new_uri(const char* uri)
+slv2_value_new_librdf_uri(SLV2World world, librdf_uri* uri)
 {
-       return slv2_value_new(SLV2_VALUE_URI, uri);
+       if (!uri)
+               return NULL;
+
+       SLV2Value val = (SLV2Value)malloc(sizeof(struct _SLV2Value));
+       val->type = SLV2_VALUE_URI;
+       val->val.uri_val = librdf_new_uri_from_uri(uri);
+       val->str_val = (char*)librdf_uri_as_string(val->val.uri_val);
+       return val;
 }
-*/
+
+
+SLV2Value
+slv2_value_new_uri(SLV2World world, const char* uri)
+{
+       return slv2_value_new(world, SLV2_VALUE_URI, uri);
+}
+
 
 SLV2Value
 slv2_value_duplicate(SLV2Value val)
 {
        SLV2Value result = (SLV2Value)malloc(sizeof(struct _SLV2Value));
-       result->str_val = strdup(val->str_val);
        result->type = val->type;
+
+       if (val->type == SLV2_VALUE_URI) {
+               result->val.uri_val = librdf_new_uri_from_uri(val->val.uri_val);
+               result->str_val = (char*)librdf_uri_as_string(val->val.uri_val);
+       } else {
+               result->str_val = strdup(val->str_val);
        result->val = val->val;
+       }
+
        return result;
 }
 
@@ -73,7 +162,11 @@
 slv2_value_free(SLV2Value val)
 {
        if (val) {
+               if (val->type == SLV2_VALUE_URI)
+                       librdf_free_uri(val->val.uri_val);
+               else
                free(val->str_val);
+
                free(val);
        }
 }
@@ -82,12 +175,26 @@
 bool
 slv2_value_equals(SLV2Value value, SLV2Value other)
 {
-       if (value->type != other->type)
+       if (value == NULL && other == NULL)
+               return true;
+       else if (value == NULL || other == NULL)
                return false;
-       else if (value && other)
+       else if (value->type != other->type)
+               return false;
+
+       switch (value->type) {
+       case SLV2_VALUE_URI:
+               return (librdf_uri_equals(value->val.uri_val, 
other->val.uri_val) != 0);
+       case SLV2_VALUE_QNAME:
+       case SLV2_VALUE_STRING:
                return ! strcmp(value->str_val, other->str_val);
-       else
-               return true;
+       case SLV2_VALUE_INT:
+               return (value->val.int_val == other->val.int_val);
+       case SLV2_VALUE_FLOAT:
+               return (value->val.float_val == other->val.float_val);
+       }
+
+       return false; /* shouldn't get here */
 }
 
 
@@ -96,6 +203,9 @@
 {
        size_t len    = 0;
        char*  result = NULL;
+       char*  locale = strdup(setlocale(LC_NUMERIC, NULL));
+               
+       // FIXME: locale kludges to work around librdf bug
 
        switch (value->type) {
        case SLV2_VALUE_URI:
@@ -103,6 +213,7 @@
                result = calloc(len, sizeof(char));
                snprintf(result, len, "<%s>", value->str_val);
                break;
+       case SLV2_VALUE_QNAME:
        case SLV2_VALUE_STRING:
                result = strdup(value->str_val);
                break;
@@ -110,15 +221,21 @@
            // INT64_MAX is 9223372036854775807 (19 digits) + 1 for sign
                len = 20;
                result = calloc(len, sizeof(char));
+               setlocale(LC_NUMERIC, "POSIX");
                snprintf(result, len, "%d", value->val.int_val);
+               setlocale(LC_NUMERIC, locale);
                break;
        case SLV2_VALUE_FLOAT:
                len = 20; // FIXME: proper maximum value?
                result = calloc(len, sizeof(char));
+               setlocale(LC_NUMERIC, "POSIX");
                snprintf(result, len, ".1%f", value->val.float_val);
+               setlocale(LC_NUMERIC, locale);
                break;
        }
        
+       free(locale);
+       
        return result;
 }
 
@@ -126,7 +243,7 @@
 bool
 slv2_value_is_uri(SLV2Value value)
 {
-       return (value->type == SLV2_VALUE_URI);
+       return (value && value->type == SLV2_VALUE_URI);
 }
 
 
@@ -138,18 +255,27 @@
 }
 
 
+/* private */
+librdf_uri*
+slv2_value_as_librdf_uri(SLV2Value value)
+{
+       assert(slv2_value_is_uri(value));
+       return value->val.uri_val;
+}
+
+
 bool
 slv2_value_is_literal(SLV2Value value)
 {
        // No blank nodes
-       return (value->type != SLV2_VALUE_URI);
+       return (value && value->type != SLV2_VALUE_URI);
 }
 
 
 bool
 slv2_value_is_string(SLV2Value value)
 {
-       return (value->type == SLV2_VALUE_STRING);
+       return (value && value->type == SLV2_VALUE_STRING);
 }
 
 
@@ -163,13 +289,14 @@
 bool
 slv2_value_is_int(SLV2Value value)
 {
-       return (value->type == SLV2_VALUE_INT);
+       return (value && value->type == SLV2_VALUE_INT);
 }
 
 
 int
 slv2_value_as_int(SLV2Value value)
 {
+       assert(value);
        assert(slv2_value_is_int(value));
        return value->val.int_val;
 }
@@ -178,7 +305,7 @@
 bool
 slv2_value_is_float(SLV2Value value)
 {
-       return (value->type == SLV2_VALUE_FLOAT);
+       return (value && value->type == SLV2_VALUE_FLOAT);
 }
 
 

Index: src/values.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/values.c,v
retrieving revision 1.2
retrieving revision 1.3
diff -u -b -r1.2 -r1.3
--- src/values.c        7 Nov 2007 11:41:53 -0000       1.2
+++ src/values.c        21 Feb 2009 21:07:00 -0000      1.3
@@ -20,7 +20,7 @@
 #include <stdlib.h>
 #include <limits.h>
 #include <raptor.h>
-#include <slv2/values.h>
+#include "slv2/values.h"
 #include "slv2_internal.h"
 
 
@@ -56,6 +56,15 @@
 }
 
 
+/* private */
+void
+slv2_values_set_at(SLV2Values list, unsigned index, void* value)
+{
+       if (index <= INT_MAX)
+               raptor_sequence_set_at(list, index, value);
+}
+
+
 bool
 slv2_values_contains(SLV2Values list, SLV2Value value)
 {

Index: src/world.c
===================================================================
RCS file: /sources/traverso/traverso/src/3rdparty/slv2/src/world.c,v
retrieving revision 1.5
retrieving revision 1.6
diff -u -b -r1.5 -r1.6
--- src/world.c 7 Nov 2007 11:41:53 -0000       1.5
+++ src/world.c 21 Feb 2009 21:07:00 -0000      1.6
@@ -16,7 +16,7 @@
  * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  */
 
-#include "../config.h"
+#include "config.h"
 
 #define _XOPEN_SOURCE 500
 #include <string.h>
@@ -24,9 +24,9 @@
 #include <dirent.h>
 #include <string.h>
 #include <librdf.h>
-#include <slv2/world.h>
-#include <slv2/slv2.h>
-#include <slv2/util.h>
+#include "slv2/world.h"
+#include "slv2/slv2.h"
+#include "slv2/util.h"
 #include "slv2_internal.h"
 
 
@@ -43,8 +43,15 @@
 
        librdf_world_open(world->world);
        
+       world->storage = librdf_new_storage(world->world, "trees", NULL, NULL);
+       if (!world->storage) {
+               fprintf(stderr, "Warning: Unable to create \"trees\" RDF 
storage.\n");
+               fprintf(stderr, "Performance can be improved by upgrading 
librdf.\n");
+               // Testing shows "hashes" to be faster than "memory" (list) here
        world->storage = librdf_new_storage(world->world, "hashes", NULL,
                        "hash-type='memory'");
+       }
+
        if (!world->storage)
                goto fail;
 
@@ -56,26 +63,32 @@
        if (!world->parser)
                goto fail;
 
-       static const char* lv2_plugin_uri = 
"http://lv2plug.in/ns/lv2core#Plugin";;
-       world->lv2_plugin_class = slv2_plugin_class_new(world, NULL, 
lv2_plugin_uri, "Plugin");
-
        world->plugin_classes = slv2_plugin_classes_new();
        
        world->plugins = slv2_plugins_new();
        
        world->lv2_specification_node = 
librdf_new_node_from_uri_string(world->world,
-                       (unsigned 
char*)"http://lv2plug.in/ns/lv2core#Specification";);
+                       (const unsigned 
char*)"http://lv2plug.in/ns/lv2core#Specification";);
        
        world->lv2_plugin_node = librdf_new_node_from_uri_string(world->world,
-                       (unsigned char*)"http://lv2plug.in/ns/lv2core#Plugin";);
+                       (const unsigned 
char*)"http://lv2plug.in/ns/lv2core#Plugin";);
        
        world->rdf_a_node = librdf_new_node_from_uri_string(world->world,
-                       (unsigned 
char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type";);
+                       (const unsigned 
char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type";);
+       
+       world->xsd_integer_node = librdf_new_node_from_uri_string(world->world,
+                       (const unsigned 
char*)"http://www.w3.org/2001/XMLSchema#integer";);
+       
+       world->xsd_decimal_node = librdf_new_node_from_uri_string(world->world,
+                       (const unsigned 
char*)"http://www.w3.org/2001/XMLSchema#decimal";);
+
+       world->lv2_plugin_class = slv2_plugin_class_new(world, NULL,
+                       librdf_node_get_uri(world->lv2_plugin_node), "Plugin");
        
        return world;
 
 fail:
-       free(world);
+       /* keep on rockin' in the */ free(world);
        return NULL;
 }
 
@@ -91,8 +104,15 @@
        
        world->local_world = false;
 
+       world->storage = librdf_new_storage(world->world, "trees", NULL, NULL);
+       if (!world->storage) {
+               fprintf(stderr, "Warning: Unable to create \"trees\" RDF 
storage.\n");
+               fprintf(stderr, "Performance can be improved by upgrading 
librdf.\n");
+               // Testing shows "hashes" to be faster than "memory" (list) here
        world->storage = librdf_new_storage(world->world, "hashes", NULL,
                        "hash-type='memory'");
+       }
+       
        if (!world->storage)
                goto fail;
 
@@ -104,26 +124,32 @@
        if (!world->parser)
                goto fail;
 
-       static const char* lv2_plugin_uri = 
"http://lv2plug.in/ns/lv2core#Plugin";;
-       world->lv2_plugin_class = slv2_plugin_class_new(world, NULL, 
lv2_plugin_uri, "Plugin");
-       
        world->plugin_classes = slv2_plugin_classes_new();
        
        world->plugins = slv2_plugins_new();
        
        world->lv2_specification_node = 
librdf_new_node_from_uri_string(world->world,
-                       (unsigned 
char*)"http://lv2plug.in/ns/lv2core#Specification";);
+                       (const unsigned 
char*)"http://lv2plug.in/ns/lv2core#Specification";);
        
-       world->lv2_plugin_node = librdf_new_node_from_uri_string(rdf_world,
-                       (unsigned char*)"http://lv2plug.in/ns/lv2core#Plugin";);
+       world->lv2_plugin_node = librdf_new_node_from_uri_string(world->world,
+                       (const unsigned 
char*)"http://lv2plug.in/ns/lv2core#Plugin";);
        
        world->rdf_a_node = librdf_new_node_from_uri_string(rdf_world,
-                       (unsigned 
char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type";);
+                       (const unsigned 
char*)"http://www.w3.org/1999/02/22-rdf-syntax-ns#type";);
+       
+       world->xsd_integer_node = librdf_new_node_from_uri_string(world->world,
+                       (const unsigned 
char*)"http://www.w3.org/2001/XMLSchema#integer";);
+       
+       world->xsd_decimal_node = librdf_new_node_from_uri_string(world->world,
+                       (const unsigned 
char*)"http://www.w3.org/2001/XMLSchema#decimal";);
+       
+       world->lv2_plugin_class = slv2_plugin_class_new(world, NULL,
+                       librdf_node_get_uri(world->lv2_plugin_node), "Plugin");
        
        return world;
 
 fail:
-       free(world);
+       /* keep on rockin' in the */ free(world);
        return NULL;
 }
 
@@ -131,9 +157,14 @@
 void
 slv2_world_free(SLV2World world)
 {
+       slv2_plugin_class_free(world->lv2_plugin_class);
+       world->lv2_plugin_class = NULL;
+
        librdf_free_node(world->lv2_specification_node);
        librdf_free_node(world->lv2_plugin_node);
        librdf_free_node(world->rdf_a_node);
+       librdf_free_node(world->xsd_integer_node);
+       librdf_free_node(world->xsd_decimal_node);
 
        for (int i=0; i < raptor_sequence_size(world->plugins); ++i)
                slv2_plugin_free(raptor_sequence_get_at(world->plugins, i));
@@ -166,35 +197,22 @@
 void
 slv2_world_load_file(SLV2World world, librdf_uri* file_uri)
 {
-       librdf_storage* storage = librdf_new_storage(world->world, 
-                       "memory", NULL, NULL);
-       librdf_model* model = librdf_new_model(world->world,
-                       storage, NULL);
-       librdf_parser_parse_into_model(world->parser, file_uri, NULL, 
-                       model);
-
-       librdf_stream* stream = librdf_model_as_stream(model);
-       librdf_model_add_statements(world->model, stream);
-       librdf_free_stream(stream);
-       
-       librdf_free_model(model);
-       librdf_free_storage(storage);
+       librdf_parser_parse_into_model(world->parser, file_uri, NULL, 
world->model);
 }
 
 
 
 void
-slv2_world_load_bundle(SLV2World world, const char* bundle_uri_str)
+slv2_world_load_bundle(SLV2World world, SLV2Value bundle_uri)
 {
-       librdf_uri* bundle_uri = librdf_new_uri(world->world,
-                       (const unsigned char*)bundle_uri_str);
-
        librdf_uri* manifest_uri = librdf_new_uri_relative_to_base(
-                       bundle_uri, (const unsigned char*)"manifest.ttl");
+                       bundle_uri->val.uri_val, (const unsigned 
char*)"manifest.ttl");
 
        /* Parse the manifest into a temporary model */
-       librdf_storage* manifest_storage = librdf_new_storage(world->world, 
-                       "memory", NULL, NULL);
+       librdf_storage* manifest_storage = librdf_new_storage(world->world, 
"trees", NULL, NULL);
+       if (manifest_storage == NULL)
+               manifest_storage = librdf_new_storage(world->world, "memory", 
NULL, NULL);
+
        librdf_model* manifest_model = librdf_new_model(world->world,
                        manifest_storage, NULL);
        librdf_parser_parse_into_model(world->parser, manifest_uri, NULL, 
@@ -202,7 +220,8 @@
 
        /* Query statement: ?plugin a lv2:Plugin */
        librdf_statement* q = librdf_new_statement_from_nodes(world->world,
-                       NULL, world->rdf_a_node, world->lv2_plugin_node);
+                       NULL, librdf_new_node_from_node(world->rdf_a_node),
+                             
librdf_new_node_from_node(world->lv2_plugin_node));
 
        librdf_stream* results = librdf_model_find_statements(manifest_model, 
q);
 
@@ -224,7 +243,7 @@
                subject = librdf_new_node_from_node(plugin_node);
                predicate = librdf_new_node_from_uri_string(world->world, 
                                (unsigned 
char*)"http://drobilla.net/ns/slv2#bundleURI";);
-               object = librdf_new_node_from_uri(world->world, bundle_uri);
+               object = librdf_new_node_from_uri(world->world, 
bundle_uri->val.uri_val);
 
                librdf_model_add(world->model, subject, predicate, object);
 
@@ -232,11 +251,12 @@
        }
        
        librdf_free_stream(results);
-       free(q);
+       librdf_free_statement(q);
        
        /* Query statement: ?specification a lv2:Specification */
        q = librdf_new_statement_from_nodes(world->world,
-                       NULL, world->rdf_a_node, world->lv2_specification_node);
+                       NULL, librdf_new_node_from_node(world->rdf_a_node),
+                             
librdf_new_node_from_node(world->lv2_specification_node));
 
        results = librdf_model_find_statements(manifest_model, q);
 
@@ -258,7 +278,7 @@
                subject = librdf_new_node_from_node(spec_node);
                predicate = librdf_new_node_from_uri_string(world->world, 
                                (unsigned 
char*)"http://drobilla.net/ns/slv2#bundleURI";);
-               object = librdf_new_node_from_uri(world->world, bundle_uri);
+               object = librdf_new_node_from_uri(world->world, 
bundle_uri->val.uri_val);
 
                librdf_model_add(world->model, subject, predicate, object);
 
@@ -266,7 +286,7 @@
        }
        
        librdf_free_stream(results);
-       free(q);
+       librdf_free_statement(q);
        
        /* Join the temporary model to the main model */
        librdf_stream* manifest_stream = librdf_model_as_stream(manifest_model);
@@ -276,7 +296,6 @@
        librdf_free_model(manifest_model);
        librdf_free_storage(manifest_storage);
        librdf_free_uri(manifest_uri);
-       librdf_free_uri(bundle_uri);
 }
 
 
@@ -302,7 +321,9 @@
 
                if (bundle_dir != NULL) {
                        closedir(bundle_dir);
-                       slv2_world_load_bundle(world, uri);
+                       SLV2Value uri_val = slv2_value_new_uri(world, uri);
+                       slv2_world_load_bundle(world, uri_val);
+                       slv2_value_free(uri_val);
                }
                
                free(uri);
@@ -335,6 +356,30 @@
 }
 
 
+/** Comparator for sorting SLV2Plugins */
+int
+slv2_plugin_compare_by_uri(const void* a, const void* b)
+{
+    SLV2Plugin plugin_a = *(SLV2Plugin*)a;
+    SLV2Plugin plugin_b = *(SLV2Plugin*)b;
+
+    return strcmp(slv2_value_as_uri(plugin_a->plugin_uri),
+                  slv2_value_as_uri(plugin_b->plugin_uri));
+}
+
+
+/** Comparator for sorting SLV2PluginClasses */
+int
+slv2_plugin_class_compare_by_uri(const void* a, const void* b)
+{
+    SLV2PluginClass class_a = *(SLV2PluginClass*)a;
+    SLV2PluginClass class_b = *(SLV2PluginClass*)b;
+
+    return strcmp(slv2_value_as_uri(class_a->uri),
+                  slv2_value_as_uri(class_b->uri));
+}
+
+
 void
 slv2_world_load_specifications(SLV2World world)
 {
@@ -383,7 +428,7 @@
                "SELECT DISTINCT ?class ?parent ?label WHERE {\n"
                //"     ?plugin a ?class .\n"
                "       ?class a rdfs:Class; rdfs:subClassOf ?parent; 
rdfs:label ?label\n"
-               "} ORDER BY ?class\n";
+               "}\n"; // ORDER BY ?class\n";
        
        librdf_query* q = librdf_new_query(world->world, "sparql",
                NULL, query_string, NULL);
@@ -401,10 +446,10 @@
                assert(class_uri);
 
                SLV2PluginClass plugin_class = slv2_plugin_class_new(world,
-                               parent_uri ? (const 
char*)librdf_uri_as_string(parent_uri) : NULL,
-                               (const char*)librdf_uri_as_string(class_uri),
-                               label);
+                               parent_uri, class_uri, label);
                raptor_sequence_push(world->plugin_classes, plugin_class);
+               // FIXME: Slow!  ORDER BY broken in certain versions of redland?
+               raptor_sequence_sort(world->plugin_classes, 
slv2_plugin_class_compare_by_uri);
 
                librdf_free_node(class_node);
                librdf_free_node(parent_node);
@@ -425,33 +470,26 @@
 {
        char* lv2_path = getenv("LV2_PATH");
 
-       /* 1. Read LV2 ontology into model */
-       const char* ontology_path = "/usr/local/share/slv2/lv2.ttl";
-       FILE* ontology = fopen(ontology_path, "r");
-       if (ontology == NULL) {
-               ontology_path = "/usr/share/slv2/lv2.ttl";
-               ontology = fopen(ontology_path, "r");
-       }
-
-       if (ontology) {
-               fclose(ontology);
-               librdf_uri* ontology_uri = 
librdf_new_uri_from_filename(world->world,
-                               ontology_path);
-               librdf_parser_parse_into_model(world->parser, ontology_uri, 
NULL, world->model);
-               librdf_free_uri(ontology_uri);
-       }
-
-       /* 2. Read all manifest files into model */
+       /* 1. Read all manifest files into model */
 
        if (lv2_path) {
                slv2_world_load_path(world, lv2_path);
        } else {
                const char* const home = getenv("HOME");
                if (home) {
+#ifdef __APPLE__
+                       const char* const suffix = 
"/Library/Audio/Plug-Ins/LV2:/Library/Audio/Plug-Ins/LV2"
+                               ":/usr/local/lib/lv2:/usr/lib/lv2";
+#else
                        const char* const suffix = 
"/.lv2:/usr/local/lib/lv2:/usr/lib/lv2";
+#endif
                        lv2_path = slv2_strjoin(home, suffix, NULL);
                } else {
+#ifdef __APPLE__
+                       lv2_path = 
strdup("/Library/Audio/Plug-Ins/LV2:/usr/local/lib/lv2:/usr/lib/lv2");
+#else
                        lv2_path = strdup("/usr/local/lib/lv2:/usr/lib/lv2");
+#endif
                }
 
                slv2_world_load_path(world, lv2_path);
@@ -460,7 +498,7 @@
        }
 
        
-       /* 3. Query out things to cache */
+       /* 2. Query out things to cache */
 
        slv2_world_load_specifications(world);
 
@@ -471,10 +509,9 @@
        "PREFIX : <http://lv2plug.in/ns/lv2core#>\n"
                "PREFIX rdfs: <http://www.w3.org/2000/01/rdf-schema#>\n"
                "PREFIX slv2: <http://drobilla.net/ns/slv2#>\n"
-               "SELECT DISTINCT ?plugin ?data ?bundle ?binary\n"
-               "WHERE { ?plugin a :Plugin; slv2:bundleURI ?bundle; 
rdfs:seeAlso ?data\n"
-               "OPTIONAL { ?plugin :binary ?binary } }\n"
-               "ORDER BY ?plugin\n";
+               "SELECT DISTINCT ?plugin ?data ?bundle\n"
+               "WHERE { ?plugin a :Plugin; slv2:bundleURI ?bundle; 
rdfs:seeAlso ?data }\n";
+               //"ORDER BY ?plugin\n";
        
        librdf_query* q = librdf_new_query(world->world, "sparql",
                NULL, query_string, NULL);
@@ -489,31 +526,32 @@
                librdf_uri*  data_uri    = librdf_node_get_uri(data_node);
                librdf_node* bundle_node = 
librdf_query_results_get_binding_value(results, 2);
                librdf_uri*  bundle_uri  = librdf_node_get_uri(bundle_node);
-               librdf_node* binary_node = 
librdf_query_results_get_binding_value(results, 3);
-               librdf_uri*  binary_uri  = librdf_node_get_uri(binary_node);
                
                assert(plugin_uri);
                assert(data_uri);
 
-               SLV2Plugin plugin = slv2_plugins_get_by_uri(world->plugins,
-                               (const char*)librdf_uri_as_string(plugin_uri));
+               SLV2Value   uri        = slv2_value_new_librdf_uri(world, 
plugin_uri);
+               SLV2Plugin  plugin     = 
slv2_plugins_get_by_uri(world->plugins, uri);
                
                // Create a new SLV2Plugin
                if (!plugin) {
-                       plugin = slv2_plugin_new(world, plugin_uri, bundle_uri, 
binary_uri);
+                       plugin = slv2_plugin_new(world, uri, bundle_uri);
                        raptor_sequence_push(world->plugins, plugin);
+                       // FIXME: Slow!  ORDER BY broken in certain versions of 
redland?
+                       raptor_sequence_sort(world->plugins, 
slv2_plugin_compare_by_uri);
+               } else {
+                       slv2_value_free(uri);
                }
                
                plugin->world = world;
 
                // FIXME: check for duplicates
                raptor_sequence_push(plugin->data_uris,
-                               slv2_value_new(SLV2_VALUE_URI, (const 
char*)librdf_uri_as_string(data_uri)));
+                               slv2_value_new_librdf_uri(plugin->world, 
data_uri));
                
                librdf_free_node(plugin_node);
                librdf_free_node(data_node);
                librdf_free_node(bundle_node);
-               librdf_free_node(binary_node);
 
                librdf_query_results_next(results);
        }

Index: slv2/lv2_ui.h
===================================================================
RCS file: slv2/lv2_ui.h
diff -N slv2/lv2_ui.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ slv2/lv2_ui.h       21 Feb 2009 21:06:57 -0000      1.1
@@ -0,0 +1,372 @@
+/************************************************************************
+ *
+ * In-process UI extension for LV2
+ *
+ * Copyright (C) 2006-2008 Lars Luthman <address@hidden>
+ * 
+ * Based on lv2.h, which was
+ *
+ * Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, 
+ *                         Stefan Westerfeld
+ * Copyright (C) 2006 Steve Harris, Dave Robillard.
+ *
+ * This header is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU Lesser General Public License as published
+ * by the Free Software Foundation; either version 2.1 of the License,
+ * or (at your option) any later version.
+ *
+ * This header 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
+ * Lesser General Public License for more details.
+ *
+ * You should have received a copy of the GNU Lesser General Public
+ * License along with this library; if not, write to the Free Software
+ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
+ * USA.
+ *
+ ***********************************************************************/
+
+/** @file
+    This extension defines an interface that can be used in LV2 plugins and
+    hosts to create UIs for plugins. The UIs are plugins that reside in
+    shared object files in an LV2 bundle and are referenced in the RDF data
+    using the triples (Turtle shown)
+<pre>    
+    @@prefix uiext: <http://lv2plug.in/ns/extensions/ui#> .
+    <http://my.plugin>    uiext:ui     <http://my.pluginui> .
+    <http://my.plugin>    a            uiext:GtkUI .
+    <http://my.pluginui>  uiext:binary <myui.so> .
+</pre>
+    where <http://my.plugin> is the URI of the plugin, <http://my.pluginui> is
+    the URI of the plugin UI and <myui.so> is the relative URI to the shared 
+    object file. While it is possible to have the plugin UI and the plugin in 
+    the same shared object file it is probably a good idea to keep them 
+    separate so that hosts that don't want UIs don't have to load the UI code.
+    A UI MUST specify its class in the RDF data, in this case uiext:GtkUI. The
+    class defines what type the UI is, e.g. what graphics toolkit it uses.
+    There are no UI classes defined in this extension, those are specified
+    separately (and anyone can define their own).
+    
+    (Note: the prefix above is used throughout this file for the same URI)
+    
+    It's entirely possible to have multiple UIs for the same plugin, or to have
+    the UI for a plugin in a different bundle from the actual plugin - this
+    way people other than the plugin author can write plugin UIs independently
+    without editing the original plugin bundle.
+    
+    Note that the process that loads the shared object file containing the UI
+    code and the process that loads the shared object file containing the 
+    actual plugin implementation does not have to be the same. There are many
+    valid reasons for having the plugin and the UI in different processes, or
+    even on different machines. This means that you can _not_ use singletons
+    and global variables and expect them to refer to the same objects in the
+    UI and the actual plugin. The function callback interface defined in this
+    header is all you can expect to work.
+    
+    Since the LV2 specification itself allows for extensions that may add 
+    new types of data and configuration parameters that plugin authors may 
+    want to control with a UI, this extension allows for meta-extensions that
+    can extend the interface between the UI and the host. These extensions
+    mirror the extensions used for plugins - there are required and optional
+    "features" that you declare in the RDF data for the UI as
+<pre>    
+    <http://my.pluginui> uiext:requiredFeature <http://my.feature> .
+    <http://my.pluginui> uiext:optionalFeature <http://my.feature> .
+</pre>
+    These predicates have the same semantics as lv2:requiredFeature and 
+    lv2:optionalFeature - if a UI is declaring a feature as required, the
+    host is NOT allowed to load it unless it supports that feature, and if it
+    does support a feature (required or optional) it MUST pass that feature's
+    URI and any additional data (specified by the meta-extension that defines
+    the feature) in a LV2_Feature struct (as defined in lv2.h) to the UI's 
+    instantiate() function.
+    
+    These features may be used to specify how to pass data between the UI
+    and the plugin port buffers - see LV2UI_Write_Function for details.
+    
+    There are four features defined in this extension that hosts may want to
+    implement:
+
+<pre>
+    uiext:makeResident
+</pre>
+    If this feature is required by a UI the host MUST NEVER unload the shared
+    library containing the UI implementation during the lifetime of the host
+    process (e.g. never calling dlclose() on Linux). This feature may be 
+    needed by e.g. a Gtk UI that registers its own Glib types using 
+    g_type_register_static() - if it gets unloaded and then loaded again the 
+    type registration will break, since there is no way to unregister the 
+    types when the library is unloaded. The data pointer in the LV2_Feature
+    for this feature should always be set to NULL.
+
+<pre>
+    uiext:makeSONameResident
+</pre>
+    This feature is ELF specific - it should only be used by UIs that
+    use the ELF file format for the UI shared object files (e.g. on Linux).
+    If it is required by an UI the UI should also list a number of SO names
+    (shared object names) for libraries that the UI shared object
+    depends on and that may not be unloaded during the lifetime of the host
+    process, using the predicate @c uiext:residentSONames, like this:
+<pre>
+    <http://my.pluginui> uiext:residentSONames "libgtkmm-2.4.so.1", 
"libfoo.so.0"
+</pre>
+    The host MUST then make sure that the shared libraries with the given ELF
+    SO names are not unloaded when the plugin UI is, but stay loaded during
+    the entire lifetime of the host process. On Linux this can be accomplished
+    by calling dlopen() on the shared library file with that SO name and never
+    calling a matching dlclose(). However, if a plugin UI requires the 
+    @c uiext:makeSONameResident feature, it MUST ALWAYS be safe for the host to
+    just never unload the shared object containing the UI implementation, i.e.
+    act as if the UI required the @c uiext:makeResident feature instead. Thus
+    the host only needs to find the shared library files corresponding to the
+    given SO names if it wants to save RAM by unloading the UI shared object 
+    file when it is no longer needed. The data pointer for the LV2_Feature for
+    this feature should always be set to NULL.
+
+<pre>
+    uiext:noUserResize
+</pre>
+    If an UI requires this feature it indicates that it does not make sense
+    to let the user resize the main widget, and the host should prevent that.
+    This feature may not make sense for all UI types. The data pointer for the
+    LV2_Feature for this feature should always be set to NULL.
+
+<pre>
+    uiext:fixedSize
+</pre>
+    If an UI requires this feature it indicates the same thing as 
+    uiext:noUserResize, and additionally it means that the UI will not resize
+    the main widget on its own - it will always remain the same size (e.g. a
+    pixmap based GUI). This feature may not make sense for all UI types.
+    The data pointer for the LV2_Feature for this feature should always be set
+    to NULL.
+    
+    
+    UIs written to this specification do not need to be threadsafe - the 
+    functions defined below may only be called in the same thread as the UI
+    main loop is running in.
+    
+    Note that this UI extension is NOT a lv2:Feature. There is no way for a 
+    plugin to know whether the host that loads it supports UIs or not, and 
+    the plugin must ALWAYS work without the UI (although it may be rather 
+    useless unless it has been configured using the UI in a previous session).
+    
+    A UI does not have to be a graphical widget, it could just as well be a
+    server listening for OSC input or an interface to some sort of hardware
+    device, depending on the RDF class of the UI.
+*/
+
+#ifndef LV2_UI_H
+#define LV2_UI_H
+
+#include "lv2.h"
+
+#define LV2_UI_URI "http://lv2plug.in/ns/extensions/ui";
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** A pointer to some widget or other type of UI handle.
+    The actual type is defined by the type URI of the UI.
+    All the functionality provided by this extension is toolkit 
+    independent, the host only needs to pass the necessary callbacks and 
+    display the widget, if possible. Plugins may have several UIs, in various
+    toolkits. */
+typedef void* LV2UI_Widget;
+
+
+/** This handle indicates a particular instance of a UI.
+    It is valid to compare this to NULL (0 for C++) but otherwise the 
+    host MUST not attempt to interpret it. The UI plugin may use it to 
+    reference internal instance data. */
+typedef void* LV2UI_Handle;
+
+
+/** This handle indicates a particular plugin instance, provided by the host.
+    It is valid to compare this to NULL (0 for C++) but otherwise the 
+    UI plugin MUST not attempt to interpret it. The host may use it to 
+    reference internal plugin instance data. */
+typedef void* LV2UI_Controller;
+
+
+/** This is the type of the host-provided function that the UI can use to
+    send data to a plugin's input ports. The @c buffer parameter must point
+    to a block of data, @c buffer_size bytes large. The contents of this buffer
+    and what the host should do with it depends on the value of the @c format
+    parameter.
+    
+    The @c format parameter should either be 0 or a numeric ID for a "Transfer
+    mechanism". Transfer mechanisms are Features and may be defined in 
+    meta-extensions. They specify how to translate the data buffers passed
+    to this function to input data for the plugin ports. If a UI wishes to 
+    write data to an input port, it must list a transfer mechanism Feature 
+    for that port's class as an optional or required feature (depending on 
+    whether the UI will work without being able to write to that port or not).
+    The only exception is when the UI wants to write single float values to 
+    input ports of the class lv2:ControlPort, in which case @c buffer_size 
+    should always be 4, the buffer should always contain a single IEEE-754
+    float, and @c format should be 0.
+    
+    The numeric IDs for the transfer mechanisms are provided by a
+    URI-to-integer mapping function provided by the host, using the URI Map 
+    feature <http://lv2plug.in/ns/ext/uri-map> with the map URI 
+    "http://lv2plug.in/ns/extensions/ui";. Thus a UI that requires transfer
+    mechanism features also requires the URI Map feature, but this is 
+    implicit - the UI does not have to list the URI map feature as a required
+    or optional feature in it's RDF data.
+    
+    An UI MUST NOT pass a @c format parameter value (except 0) that has not
+    been returned by the host-provided URI mapping function for a 
+    host-supported transfer mechanism feature URI.
+
+    The UI MUST NOT try to write to a port for which there is no specified
+    transfer mechanism, or to an output port. The UI is responsible for 
+    allocating the buffer and deallocating it after the call.
+*/
+typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller,
+                                     uint32_t         port_index,
+                                     uint32_t         buffer_size,
+                                     uint32_t         format,
+                                     const void*      buffer);
+
+
+/** This struct contains the implementation of an UI. A pointer to an 
+    object of this type is returned by the lv2ui_descriptor() function. 
+*/
+typedef struct _LV2UI_Descriptor {
+  
+  /** The URI for this UI (not for the plugin it controls). */
+  const char* URI;
+  
+  /** Create a new UI object and return a handle to it. This function works
+      similarly to the instantiate() member in LV2_Descriptor.
+      
+      @param descriptor The descriptor for the UI that you want to instantiate.
+      @param plugin_uri The URI of the plugin that this UI will control.
+      @param bundle_path The path to the bundle containing the RDF data file
+                         that references this shared object file, including the
+                         trailing '/'.
+      @param write_function A function provided by the host that the UI can
+                            use to send data to the plugin's input ports.
+      @param controller A handle for the plugin instance that should be passed
+                        as the first parameter of @c write_function.
+      @param widget     A pointer to an LV2UI_Widget. The UI will write a
+                        widget pointer to this location (what type of widget 
+                        depends on the RDF class of the UI) that will be the
+                        main UI widget.
+      @param features   An array of LV2_Feature pointers. The host must pass
+                        all feature URIs that it and the UI supports and any
+                        additional data, just like in the LV2 plugin 
+                        instantiate() function. Note that UI features and 
plugin
+                       features are NOT necessarily the same, they just share
+                       the same data structure - this will probably not be the
+                       same array as the one the plugin host passes to a 
+                       plugin.
+  */
+  LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor,
+                              const char*                     plugin_uri,
+                              const char*                     bundle_path,
+                              LV2UI_Write_Function            write_function,
+                              LV2UI_Controller                controller,
+                              LV2UI_Widget*                   widget,
+                              const LV2_Feature* const*       features);
+
+  
+  /** Destroy the UI object and the associated widget. The host must not try
+      to access the widget after calling this function.
+   */
+  void (*cleanup)(LV2UI_Handle ui);
+  
+  /** Tell the UI that something interesting has happened at a plugin port.
+      What is interesting and how it is written to the buffer passed to this
+      function is defined by the @c format parameter, which has the same 
+      meaning as in LV2UI_Write_Function. The only exception is ports of the 
+      class lv2:ControlPort, for which this function should be called
+      when the port value changes (it does not have to be called for every 
+      single change if the host's UI thread has problems keeping up with 
+      the thread the plugin is running in), @c buffer_size should be 4 and the 
+      buffer should contain a single IEEE-754 float. In this case the @c format
+      parameter should be 0.
+      
+      By default, the host should only call this function for input ports of
+      the lv2:ControlPort class. However, the default setting can be modified
+      by using the following URIs in the UI's RDF data:
+      <pre>
+      uiext:portNotification
+      uiext:noPortNotification
+      uiext:plugin
+      uiext:portIndex
+      </pre>
+      For example, if you want the UI with uri 
+      <code><http://my.pluginui></code> for the plugin with URI 
+      <code><http://my.plugin></code> to get notified when the value of the 
+      output control port with index 4 changes, you would use the following 
+      in the RDF for your UI:
+      <pre>
+      <http://my.pluginui> uiext:portNotification [ uiext:plugin 
<http://my.plugin> ;
+                                                      uiext:portIndex 4 ] .
+      </pre>
+      and similarly with <code>uiext:noPortNotification</code> if you wanted
+      to prevent notifications for a port for which it would be on by default 
+      otherwise. The UI is not allowed to request notifications for ports of 
+      types for which no transfer mechanism is specified, if it does it should 
+      be considered broken and the host should not load it.
+      
+      The @c buffer is only valid during the time of this function call, so if 
+      the UI wants to keep it for later use it has to copy the contents to an
+      internal buffer.
+      
+      This member may be set to NULL if the UI is not interested in any 
+      port events.
+  */
+  void (*port_event)(LV2UI_Handle ui,
+                     uint32_t     port_index,
+                     uint32_t     buffer_size,
+                     uint32_t     format,
+                     const void*  buffer);
+  
+  /** Returns a data structure associated with an extension URI, for example
+      a struct containing additional function pointers. Avoid returning
+      function pointers directly since standard C++ has no valid way of
+      casting a void* to a function pointer. This member may be set to NULL
+      if the UI is not interested in supporting any extensions. This is similar
+      to the extension_data() member in LV2_Descriptor.
+  */
+  const void* (*extension_data)(const char*  uri);
+
+} LV2UI_Descriptor;
+
+
+
+/** A plugin UI programmer must include a function called "lv2ui_descriptor"
+    with the following function prototype within the shared object
+    file. This function will have C-style linkage (if you are using
+    C++ this is taken care of by the 'extern "C"' clause at the top of
+    the file). This function will be accessed by the UI host using the 
+    @c dlsym() function and called to get a LV2UI_UIDescriptor for the
+    wanted plugin.
+    
+    Just like lv2_descriptor(), this function takes an index parameter. The
+    index should only be used for enumeration and not as any sort of ID number 
-
+    the host should just iterate from 0 and upwards until the function returns
+    NULL or a descriptor with an URI matching the one the host is looking for.
+*/
+const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index);
+
+
+/** This is the type of the lv2ui_descriptor() function. */
+typedef const LV2UI_Descriptor* (*LV2UI_DescriptorFunction)(uint32_t index);
+
+
+
+#ifdef __cplusplus
+}
+#endif
+
+
+#endif

Index: slv2/scalepoint.h
===================================================================
RCS file: slv2/scalepoint.h
diff -N slv2/scalepoint.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ slv2/scalepoint.h   21 Feb 2009 21:06:58 -0000      1.1
@@ -0,0 +1,55 @@
+/* SLV2
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *  
+ * This library 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 library 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __SLV2_SCALE_POINT_H__
+#define __SLV2_SCALE_POINT_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include "slv2/types.h"
+
+/** \addtogroup slv2_data
+ * @{
+ */
+
+
+/** Get the label of this scale point (enumeration value)
+ *
+ * Returned value is owned by \a point and must not be freed.
+ */
+SLV2Value
+slv2_scale_point_get_label(SLV2ScalePoint point);
+
+
+/** Get the value of this scale point (enumeration value)
+ *
+ * Returned value is owned by \a point and must not be freed.
+ */
+SLV2Value
+slv2_scale_point_get_value(SLV2ScalePoint point);
+
+
+/** @} */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* __SLV2_SCALE_POINT_H__ */

Index: slv2/scalepoints.h
===================================================================
RCS file: slv2/scalepoints.h
diff -N slv2/scalepoints.h
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ slv2/scalepoints.h  21 Feb 2009 21:06:58 -0000      1.1
@@ -0,0 +1,73 @@
+/* SLV2
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *  
+ * This library 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 library 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#ifndef __SLV2_SCALE_POINTS_H__
+#define __SLV2_SCALE_POINTS_H__
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+#include <stdbool.h>
+#include "slv2/value.h"
+
+/** \defgroup slv2_collections Collections of scale_points/objects
+ *
+ * Ordered collections of typed scale_points which are fast for random
+ * access by index (i.e. a fancy array).
+ *
+ * @{
+ */
+
+
+/** Allocate a new, empty SLV2ScalePoints
+ */
+SLV2ScalePoints
+slv2_scale_points_new();
+
+
+/** Free an SLV2ScalePoints.
+ */
+void
+slv2_scale_points_free(SLV2ScalePoints points);
+
+
+/** Get the number of scale points in a collection.
+ */
+unsigned
+slv2_scale_points_size(SLV2ScalePoints points);
+
+
+/** Get the scale point at the given index in a collection.
+ *
+ * @return the element at \a index, or NULL if index is out of range.
+ *
+ * Time = O(1)
+ */
+SLV2ScalePoint
+slv2_scale_points_get_at(SLV2ScalePoints points, unsigned index);
+
+
+/** @} */
+
+#ifdef __cplusplus
+} /* extern "C" */
+#endif
+
+#endif /* __SLV2_SCALE_POINTS_H__ */
+

Index: src/scalepoint.c
===================================================================
RCS file: src/scalepoint.c
diff -N src/scalepoint.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ src/scalepoint.c    21 Feb 2009 21:06:59 -0000      1.1
@@ -0,0 +1,63 @@
+/* SLV2
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *  
+ * This library 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 library 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#define _XOPEN_SOURCE 500
+
+#include <stdlib.h>
+#include <string.h>
+#include <assert.h>
+#include <locale.h>
+#include <raptor.h>
+#include "slv2/value.h"
+#include "slv2_internal.h"
+
+
+/* private - ownership of value and label is taken */
+SLV2ScalePoint
+slv2_scale_point_new(SLV2Value value, SLV2Value label)
+{
+       SLV2ScalePoint point = (SLV2ScalePoint)malloc(sizeof(struct 
_SLV2ScalePoint));
+       point->value = value;
+       point->label= label;
+       return point;
+}
+
+
+/* private */
+void
+slv2_scale_point_free(SLV2ScalePoint point)
+{
+       slv2_value_free(point->value);
+       slv2_value_free(point->label);
+       free(point);
+}
+
+
+SLV2Value
+slv2_scale_point_get_value(SLV2ScalePoint p)
+{
+       return p->value;
+}
+
+
+SLV2Value
+slv2_scale_point_get_label(SLV2ScalePoint p)
+{
+       return p->label;
+}
+

Index: src/scalepoints.c
===================================================================
RCS file: src/scalepoints.c
diff -N src/scalepoints.c
--- /dev/null   1 Jan 1970 00:00:00 -0000
+++ src/scalepoints.c   21 Feb 2009 21:06:59 -0000      1.1
@@ -0,0 +1,57 @@
+/* SLV2
+ * Copyright (C) 2007 Dave Robillard <http://drobilla.net>
+ *  
+ * This library 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 library 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.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
+ */
+
+#include <string.h>
+#include <stdlib.h>
+#include <limits.h>
+#include <raptor.h>
+#include "slv2/scalepoints.h"
+#include "slv2_internal.h"
+
+
+SLV2ScalePoints
+slv2_scale_points_new()
+{
+       return raptor_new_sequence((void (*)(void*))&slv2_scale_point_free, 
NULL);
+}
+
+
+void
+slv2_scale_points_free(SLV2ScalePoints points)
+{
+       if (points)
+               raptor_free_sequence(points);
+}
+
+
+unsigned
+slv2_scale_points_size(SLV2ScalePoints points)
+{
+       return (points ? raptor_sequence_size(points) : 0);
+}
+
+
+SLV2ScalePoint
+slv2_scale_points_get_at(SLV2ScalePoints points, unsigned index)
+{
+       if (index > INT_MAX)
+               return NULL;
+       else
+               return (SLV2ScalePoint)raptor_sequence_get_at(points, 
(int)index);
+}
+




reply via email to

[Prev in Thread] Current Thread [Next in Thread]