summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2007-09-22 16:54:26 +0000
committerDavid Robillard <d@drobilla.net>2007-09-22 16:54:26 +0000
commit106b0784b8c8347bbbebcedc421030effdc26fd0 (patch)
tree55dbdd438de387b630a78e837ed23db12e9920cb
parentd8fb10e4246b6804e2283e4f83d2bfdccad8ad58 (diff)
downloadlilv-106b0784b8c8347bbbebcedc421030effdc26fd0.tar.gz
lilv-106b0784b8c8347bbbebcedc421030effdc26fd0.tar.bz2
lilv-106b0784b8c8347bbbebcedc421030effdc26fd0.zip
Updates LV2 and LV2 UI specs.
git-svn-id: http://svn.drobilla.net/lad/slv2@762 a436a847-0d15-0410-975c-d299462d15a1
-rw-r--r--slv2/Makefile.am2
-rw-r--r--slv2/lv2-gtk2gui.h212
-rw-r--r--slv2/lv2.h76
-rw-r--r--slv2/lv2_gui.h346
-rw-r--r--slv2/pluginguiinstance.h19
-rw-r--r--src/pluginguiinstance.c26
-rw-r--r--src/slv2_internal.h4
7 files changed, 413 insertions, 272 deletions
diff --git a/slv2/Makefile.am b/slv2/Makefile.am
index f090e22..8deb4db 100644
--- a/slv2/Makefile.am
+++ b/slv2/Makefile.am
@@ -3,7 +3,7 @@ slv2includedir = $(includedir)/slv2
slv2include_HEADERS = \
gui.h \
lv2.h \
- lv2-gtk2gui.h \
+ lv2_gui.h \
plugin.h \
pluginclass.h \
pluginclasses.h \
diff --git a/slv2/lv2-gtk2gui.h b/slv2/lv2-gtk2gui.h
deleted file mode 100644
index ae05c16..0000000
--- a/slv2/lv2-gtk2gui.h
+++ /dev/null
@@ -1,212 +0,0 @@
-/************************************************************************
- *
- * GTK2 in-process UI extension for LV2
- *
- * Copyright (C) 2006 Lars Luthman <lars.luthman@gmail.com>
- *
- * Based on lv2.h, which is
- *
- * 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 GTK2 GUIs for plugins. The GUIs will be plugins that
- will reside in shared object files in a LV2 bundle and be referenced in
- the RDF file using the triples
-<pre>
- <http://my.plugin> <http://ll-plugins.nongnu.org/lv2/ext/gtk2gui#gui> <http://my.plugingui>
- <http://my.plugingui> <http://ll-plugins.nongnu.org/lv2/ext/gtk2gui#binary> <mygui.so>
-</pre>
- where <http://my.plugin> is the URI of the plugin, <http://my.plugingui> is
- the URI of the plugin GUI and <mygui.so> is the relative URI to the shared
- object file. While it is possible to have the plugin GUI 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 GUIs don't have to load the GUI code.
-
- It's entirely possible to have multiple GUIs for the same plugin, or to have
- the GUI for a plugin in a different bundle from the actual plugin - this
- way people other than the plugin author can write plugin GUIs independently
- without editing the original plugin bundle. If a GUI is in a separate bundle
- the first triple above should be in that bundle's manifest.ttl file so that
- hosts can find the GUI when scanning the manifests.
-
- Note that the process that loads the shared object file containing the GUI
- 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 GUI 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
- GUI 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 GUI, this extension allows for meta-extensions that
- can extend the interface between the GUI and the host. See the
- instantiate() and extension_data() callback pointers for more details.
-
- Note that this extension is NOT a Host Feature. There is no way for a plugin
- to know whether the host that loads it supports GUIs or not, and the plugin
- must ALWAYS work without the GUI (although it may be rather useless unless
- it has been configured using the GUI in a previous session).
-
- GUIs written to this specification do not need to be threadsafe - the
- functions defined below may only be called in the same thread as the GTK
- main loop is running in.
-*/
-
-#ifndef LV2_GTK2GUI_H
-#define LV2_GTK2GUI_H
-
-#include "lv2.h"
-
-
-#ifdef __cplusplus
-extern "C" {
-#endif
-
-/* The original header includes <gtk/gtkwidget.h>, but we don't want
- libslv2 to depend on GTK+ so we forward declare the _GtkWidget struct
- instead. */
-struct _GtkWidget;
-
-
-
-/** This handle indicates a particular instance of a GUI.
- It is valid to compare this to NULL (0 for C++) but otherwise the
- host MUST not attempt to interpret it. The GUI 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
- GUI plugin MUST not attempt to interpret it. The host may use it to
- reference internal instance data. */
-typedef void* LV2UI_Controller;
-
-
-/** This is the type of the host-provided function that changes the value
- of a control rate float input port in a plugin instance. A function
- pointer of this type will be provided to the GUI by the host in the
- instantiate() function. */
-typedef void (*LV2UI_Set_Control_Function)(LV2UI_Controller controller,
- uint32_t port,
- float value);
-
-
-typedef struct _LV2UI_Descriptor {
-
- /** The URI for this GUI (not for the plugin it controls). */
- const char* URI;
-
- /** Create a new GUI object and return a handle to it. This function works
- similarly to the instantiate() member in LV2_Descriptor, with the
- additions that the URI for the plugin that this GUI is for is passed
- as a parameter, a function pointer and a controller handle are passed to
- allow the plugin to change control port values in the plugin
- (control_function and controller) and a pointer to a GtkWidget pointer
- is passed, which the GUI plugin should set to point to a newly created
- widget which will be the main GUI for the plugin.
-
- The features array works like the one in the instantiate() member
- in LV2_Descriptor, except that the URIs should be denoted with the triples
- <pre>
- <http://my.plugingui> <http://ll-plugins.nongnu.org/lv2/dev/gtk2gui#optionalFeature> <http://my.guifeature>
- </pre>
- or
- <pre>
- <http://my.plugingui> <http://ll-plugins.nongnu.org/lv2/dev/gtk2gui#requiredFeature> <http://my.guifeature>
- </pre>
- in the RDF file, instead of the lv2:optionalFeature or lv2:requiredFeature
- that is used by host features. These features are associated with the GUI,
- not with the plugin - they are not actually LV2 Host Features, they just
- use the same data structure.
-
- The same rules apply for these features as for normal host features -
- if a feature is listed as required in the RDF file and the host does not
- support it, it must not load the GUI.
- */
- LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor,
- const char* plugin_uri,
- const char* bundle_path,
- LV2UI_Set_Control_Function control_function,
- LV2UI_Controller controller,
- struct _GtkWidget** widget,
- const LV2_Host_Feature** features);
-
-
- /** Destroy the GUI object and the associated widget.
- */
- void (*cleanup)(LV2UI_Handle gui);
-
- /** Tell the GUI that a control port value has changed. This member may be
- set to NULL if the GUI is not interested in control port changes.
- */
- void (*set_control)(LV2UI_Handle gui,
- uint32_t port,
- float value);
-
- /** 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 GUI is not interested in supporting any extensions. This is similar
- to the extension_data() member in LV2_Descriptor.
- */
- void* (*extension_data)(LV2UI_Handle gui,
- const char* uri);
-
-} LV2UI_Descriptor;
-
-
-
-/** Accessing a plugin GUI.
-
- A plugin 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 GUI 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
- is returned.
-*/
-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
diff --git a/slv2/lv2.h b/slv2/lv2.h
index 1e73905..953c459 100644
--- a/slv2/lv2.h
+++ b/slv2/lv2.h
@@ -2,7 +2,7 @@
* *** PROVISIONAL ***
*
* Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis,
- * Stefan Westerfeld
+ * Stefan Westerfeld.
* Copyright (C) 2006-2007 Steve Harris, Dave Robillard.
*
* This header is free software; you can redistribute it and/or modify it
@@ -36,7 +36,7 @@ extern "C" {
/** @file lv2.h
*
- * Revision: 1.0beta4
+ * Revision: 1.0beta5
*
* == Overview ==
*
@@ -54,18 +54,19 @@ extern "C" {
* possible - the data file is mandatory.
*
* Plugins are expected to distinguish between control rate and audio
- * rate data. Plugins have 'ports' that are inputs or outputs for audio
- * or control data and each plugin is 'run' for a 'block' corresponding
- * to a short time interval measured in samples. Audio rate data is
- * communicated using arrays with one element per sample processed,
+ * rate data (or other types of data defined by extensions). Plugins have
+ * 'ports' that are inputs or outputs and each plugin is 'run' for a 'block'
+ * corresponding to a short time interval measured in samples. Audio rate
+ * data is communicated using arrays with one element per sample processed,
* allowing a block of audio to be processed by the plugin in a single
* pass. Control rate data is communicated using single values. Control
* rate data has a single value at the start of a call to the 'run()'
* function, and may be considered to remain this value for its duration.
- * Thus the 'control rate' is determined by the block size, controlled
- * by the host. The plugin may assume that all its input and output
- * ports have been connected to the relevant data location (see the
- * 'connect_port()' function below) before it is asked to run.
+ * Thus the 'control rate' is determined by the block size, controlled by
+ * the host. The plugin may assume that all its input and output ports have
+ * been connected to the relevant data location (see the 'connect_port()'
+ * function below) before it is asked to run, unless the port has been set
+ * 'connection optional' in the plugin's data file.
*
* Plugins will reside in shared object files suitable for dynamic linking
* by dlopen() and family. The file will provide a number of 'plugin
@@ -84,14 +85,16 @@ extern "C" {
* To facilitate this, the functions provided by a plugin are divided into
* classes:
*
- * - Audio class: run(), connect_port()
- * - Instantiation class: instantiate(), cleanup(),
- * activate(), deactivate()
+ * - Discovery class: lv2_descriptor(), extension_data()
+ * - Instantiation class: instantiate(), cleanup(), activate(), deactivate()
+ * - Audio class: run(), connect_port()
*
* Extensions to this specification which add new functions MUST declare in
* which of these classes the functions belong, or define new classes for them.
* The rules that hosts must follow are these:
*
+ * - When a function from the Discovery class is running, no other
+ * functions in the same shared object file may run.
* - When a function from the Instantiation class is running for a plugin
* instance, no other functions for that instance may run.
* - When a function is running for a plugin instance, no other
@@ -100,9 +103,6 @@ extern "C" {
* Any simultaneous calls that are not explicitly forbidden by these rules
* are allowed. For example, a host may call run() for two different plugin
* instances simultaneously.
- *
- * The extension_data() function and the lv2_descriptor() function are never
- * associated with any plugin instances and may be called at any time.
*/
@@ -127,14 +127,12 @@ typedef void * LV2_Handle;
* feature the host has which the plugin may depend on. This is to allow
* extensions to the LV2 specification without causing any breakage. The base
* LV2 specification does not define any host features; hosts are not required
- * to use this facility.
- */
+ * to use this facility. */
typedef struct _LV2_Host_Feature {
/** A globally unique, case-sensitive identifier for this feature.
*
* This MUST be defined in the specification of any LV2 extension which
- * defines a host feature.
- */
+ * defines a host feature. */
const char * URI;
/** Pointer to arbitrary data.
@@ -144,8 +142,7 @@ typedef struct _LV2_Host_Feature {
* specification makes no restrictions on the contents of this data.
* The data here MUST be cleary defined by the LV2 extension which defines
* this feature.
- * If no data is required, this may be set to NULL.
- */
+ * If no data is required, this may be set to NULL. */
void * data;
} LV2_Host_Feature;
@@ -195,10 +192,10 @@ typedef struct _LV2_Descriptor {
* Note that instance initialisation should generally occur in
* activate() rather than here. If a host calls instantiate, it MUST
* call cleanup() at some point in the future. */
- LV2_Handle (*instantiate)(const struct _LV2_Descriptor * Descriptor,
- double SampleRate,
- const char * BundlePath,
- const LV2_Host_Feature *const * HostFeatures);
+ LV2_Handle (*instantiate)(const struct _LV2_Descriptor * descriptor,
+ double sample_rate,
+ const char * bundle_path,
+ const LV2_Host_Feature *const * host_features);
/** Function pointer that connects a port on a plugin instance to a memory
* location where the block of data for the port will be read/written.
@@ -231,9 +228,9 @@ typedef struct _LV2_Descriptor {
* If the plugin has the property lv2:hardRTCapable then there are
* various things that the plugin MUST NOT do within the connect_port()
* function (see lv2.ttl). */
- void (*connect_port)(LV2_Handle Instance,
- uint32_t Port,
- void * DataLocation);
+ void (*connect_port)(LV2_Handle instance,
+ uint32_t port,
+ void * data_location);
/** Function pointer that initialises a plugin instance and activates
* it for use.
@@ -257,7 +254,7 @@ typedef struct _LV2_Descriptor {
*
* Note that connect_port() may be called before or after a call to
* activate(). */
- void (*activate)(LV2_Handle Instance);
+ void (*activate)(LV2_Handle instance);
/** Function pointer that runs a plugin instance for a block.
*
@@ -273,8 +270,8 @@ typedef struct _LV2_Descriptor {
* If the plugin has the property lv2:hardRTCapable then there are
* various things that the plugin MUST NOT do within the run()
* function (see lv2.ttl). */
- void (*run)(LV2_Handle Instance,
- uint32_t SampleCount);
+ void (*run)(LV2_Handle instance,
+ uint32_t sampleCount);
/** This is the counterpart to activate() (see above). If there is
* nothing for deactivate() to do then the plugin writer may provide
@@ -291,7 +288,7 @@ typedef struct _LV2_Descriptor {
* instance will be reinitialised when activate() is called to reuse it.
* Hosts MUST NOT call deactivate() unless activate() was previously
* called. */
- void (*deactivate)(LV2_Handle Instance);
+ void (*deactivate)(LV2_Handle instance);
/** This is the counterpart to instantiate() (see above). Once an instance
* of a plugin has been finished with it can be deleted using this
@@ -302,7 +299,7 @@ typedef struct _LV2_Descriptor {
* call to deactivate() MUST be made before cleanup() is called.
* Hosts MUST NOT call cleanup() unless instantiate() was previously
* called. */
- void (*cleanup)(LV2_Handle Instance);
+ void (*cleanup)(LV2_Handle instance);
/** Function pointer that can be used to return additional instance data for
* a plugin defined by some extenion (e.g. a struct containing additional
@@ -319,15 +316,16 @@ typedef struct _LV2_Descriptor {
* NULL if it does not support the extension, but hosts SHOULD NOT use this
* as a discovery method (e.g. hosts should only call this function for
* extensions known to be supported by the plugin from the data file).
+ *
+ * The host is never responsible for freeing the returned value.
*
* NOTE: It is highly recommended that this function returns a struct, and
* NOT a direct function pointer. Standard C++ (for real reasons) does not
* allow type casts from void* to a function pointer type. To provide
* additional functions a struct should be returned containing the extra
* function pointers (which is valid standard C++, and a much better idea
- * for extensibility anyway).
- */
- void* (*extension_data)(const char * URI);
+ * for extensibility anyway). */
+ void* (*extension_data)(const char * uri);
} LV2_Descriptor;
@@ -360,12 +358,12 @@ typedef struct _LV2_Descriptor {
* index that results in NULL being returned. Index has no meaning,
* hosts MUST NOT depend on it remaining constant (ie when serialising)
* in any way. */
-const LV2_Descriptor * lv2_descriptor(uint32_t Index);
+const LV2_Descriptor * lv2_descriptor(uint32_t index);
/** Datatype corresponding to the lv2_descriptor() function. */
typedef const LV2_Descriptor *
-(*LV2_Descriptor_Function)(uint32_t Index);
+(*LV2_Descriptor_Function)(uint32_t index);
/* ******************************************************************** */
diff --git a/slv2/lv2_gui.h b/slv2/lv2_gui.h
new file mode 100644
index 0000000..696f20b
--- /dev/null
+++ b/slv2/lv2_gui.h
@@ -0,0 +1,346 @@
+/************************************************************************
+ *
+ * In-process UI extension for LV2
+ *
+ * Copyright (C) 2006-2007 Lars Luthman <lars.luthman@gmail.com>
+ *
+ * Based on lv2.h, which is:
+ *
+ * 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 GUIs for plugins. The GUIs are plugins that reside in
+ shared object files in an LV2 bundle and be referenced in the RDF file
+ using the triples (Turtle shown)
+<pre>
+ @prefix guiext: <http://ll-plugins.nongnu.org/lv2/ext/ipgui/1#> .
+ <http://my.plugin> guiext:gui <http://my.plugingui> .
+ <http://my.plugingui> guiext:binary <mygui.so> .
+</pre>
+ where <http://my.plugin> is the URI of the plugin, <http://my.plugingui> is
+ the URI of the plugin GUI and <mygui.so> is the relative URI to the shared
+ object file. While it is possible to have the plugin GUI 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 GUIs don't have to load the GUI code.
+
+ (Note: the prefix above is used throughout this file for the same URI)
+
+ It's entirely possible to have multiple GUIs for the same plugin, or to have
+ the GUI for a plugin in a different bundle from the actual plugin - this
+ way people other than the plugin author can write plugin GUIs independently
+ without editing the original plugin bundle. If a GUI is in a separate bundle
+ the first triple above should be in that bundle's manifest.ttl file so that
+ hosts can find the GUI when scanning the manifests.
+
+ Note that the process that loads the shared object file containing the GUI
+ 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 GUI 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
+ GUI 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 GUI, this extension allows for meta-extensions that
+ can extend the interface between the GUI and the host. See the
+ instantiate() and extension_data() callback pointers for more details.
+
+ Note that this extension is NOT a Host Feature. There is no way for a plugin
+ to know whether the host that loads it supports GUIs or not, and the plugin
+ must ALWAYS work without the GUI (although it may be rather useless unless
+ it has been configured using the GUI in a previous session).
+
+ GUIs 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.
+*/
+
+#ifndef LV2_GUI_H
+#define LV2_GUI_H
+
+#include "lv2.h"
+
+
+#ifdef __cplusplus
+extern "C" {
+#endif
+
+
+/** A pointer to some widget.
+ * The actual type of the widget is defined by the type URI of the GUI.
+ * e.g. if "<http://example.org/somegui> a guiext:GtkGUI", this is a pointer
+ * to a GtkWidget. 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 GUIs,
+ * in various toolkits.
+ */
+typedef void* LV2UI_Widget;
+
+
+/** This handle indicates a particular instance of a GUI.
+ It is valid to compare this to NULL (0 for C++) but otherwise the
+ host MUST not attempt to interpret it. The GUI 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
+ GUI plugin MUST not attempt to interpret it. The host may use it to
+ reference internal instance data. */
+typedef void* LV2UI_Controller;
+
+
+/** This is the type of the host-provided function that the GUI 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
+ will depend on the class of the port it's being sent to. For ports of the
+ class lv2:ControlPort, buffer_size should be sizeof(float) and the buffer
+ contents should be a float value. For ports of the class llext:MidiPort the
+ buffer should contain the data bytes of a single MIDI event, and buffer_size
+ should be the number of bytes in the event. No other port classes are
+ allowed, unless the format and the meaning of the buffer passed to this
+ function is defined in the extension that specifies that class or in a
+ separate GUI host feature extension that is required by this GUI.
+
+ The GUI is responsible for allocating the buffer and deallocating it after
+ the call. There are no timing guarantees at all for this function, although
+ the faster the host can get the data to the plugin port the better. A
+ function pointer of this type will be provided to the GUI by the host in
+ the instantiate() function. */
+typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller,
+ uint32_t port_index,
+ uint32_t buffer_size,
+ const void* buffer);
+
+/** This is the type of the host-provided function that the GUI can use to
+ send arbitrary commands to the plugin. The parameters after the first one
+ should be const char* variables, terminated by a NULL pointer, and will be
+ interpreted as a command with arguments. A function of this type will be
+ provided to the GUI by the host in the instantiate() function. */
+typedef void (*LV2UI_Command_Function)(LV2UI_Controller controller,
+ uint32_t argc,
+ const char* const* argv);
+
+/** This is the type of the host-provided function that the GUI can use to
+ request a program change in the host. A function of this type will be
+ provided to the GUI by the host in the instantiate() function. Calling
+ this function does not guarantee that the program will change, it is just
+ a request. If the program does change, the GUI's current_program_changed()
+ callback will be called, either before or after this function returns
+ depending on whether the GUI host <-> plugin instance communication is
+ synchronous or asynchronous. */
+typedef void (*LV2UI_Program_Change_Function)(LV2UI_Controller controller,
+ unsigned char program);
+
+/** This is the type of the host-provided function that the GUI can use to
+ request that the current state of the plugin is saved to a program.
+ A function of this type will be provided to the GUI by the host in the
+ instantiate function. Calling this function does not guarantee that the
+ state will be saved, it is just a request. If the state is saved, the
+ GUI's program_added() callback will be called, either before or after
+ this function returns depending on whether the GUI host <-> plugin
+ instance communication is synchronous or asynchronous. */
+typedef void (*LV2UI_Program_Save_Function)(LV2UI_Controller controller,
+ unsigned char program,
+ const char* name);
+
+
+/** */
+typedef struct _LV2UI_Descriptor {
+
+ /** The URI for this GUI (not for the plugin it controls). */
+ const char* URI;
+
+ /** Create a new GUI object and return a handle to it. This function works
+ similarly to the instantiate() member in LV2_Descriptor, with the
+ additions that the URI for the plugin that this GUI is for is passed
+ as a parameter, a function pointer and a controller handle are passed to
+ allow the plugin to write to input ports in the plugin (write_function
+ and controller) and a pointer to a LV2_Widget is passed, which the GUI
+ plugin should set to point to a newly created widget which will be the
+ GUI for the plugin. This widget may only be destroyed by cleanup().
+
+ The features array works like the one in the instantiate() member
+ in LV2_Descriptor, except that the URIs should be denoted with the triples
+ <pre>
+ <http://my.plugingui> guiext:optionalFeature <http://my.guifeature>
+ </pre>
+ or
+ <pre>
+ <http://my.plugingui> guiext:requiredFeature <http://my.guifeature>
+ </pre>
+ in the RDF file, instead of the lv2:optionalFeature or lv2:requiredFeature
+ that is used by host features. These features are associated with the GUI,
+ not with the plugin - they are not actually LV2 Host Features, they just
+ use the same data structure.
+
+ The same rules apply for these features as for normal host features -
+ if a feature is listed as required in the RDF file and the host does not
+ support it, it must not load the GUI.
+ */
+ LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor,
+ const char* plugin_uri,
+ const char* bundle_path,
+ 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,
+ LV2UI_Widget* widget,
+ const LV2_Host_Feature* const* host_features);
+
+
+ /** Destroy the GUI object and the associated widget.
+ */
+ void (*cleanup)(LV2UI_Handle gui);
+
+ /** Tell the GUI that something interesting has happened at a plugin port.
+ For control ports this would be when the value in the buffer has changed,
+ for message-based port classes like MIDI or OSC it would be when a
+ message has arrived in the buffer. For other port classes it is not
+ defined when this function is called, unless it is specified in the
+ definition of that port class extension. For control ports the default
+ setting is to call this function whenever an input control port value
+ has changed but not when any output control port value has changed, for
+ all other port classes the default setting is to never call this function.
+
+ However, the default setting can be modified by using the following
+ URIs:
+ <pre>
+ guiext:portNotification
+ guiext:noPortNotification
+ guiext:plugin
+ guiext:portIndex
+ </pre>
+ For example, if you want the GUI with uri
+ <code><http://my.plugingui></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 GUI:
+ <pre>
+ <http://my.plugingui> guiext:portNotification [ guiext:plugin <http://my.plugin> ;
+ guiext:portIndex 4 ] .
+ </pre>
+ and similarly with <code>guiext:noPortNotification</code> if you wanted to
+ prevent notifications for a port for which it would be on by default
+ otherwise.
+
+ The @c buffer is only valid during the time of this function call, so if
+ the GUI wants to keep it for later use it has to copy the contents to an
+ internal buffer.
+
+ The buffer is subject to the same rules as the ones for the
+ LV2_Write_Function type. This means that a plugin GUI may not request a
+ portNotification for a port that has a class other than lv2:ControlPort
+ or llext:MidiPort unless the buffer format and meaning is specified in
+ the extension that defines that port class, or in a separate GUI host
+ feature extension that is required by the GUI. Any GUI that does that
+ should be considered broken and the host should not use it.
+
+ This member may be set to NULL if the GUI is not interested in any
+ port events.
+ */
+ void (*port_event)(LV2UI_Handle gui,
+ uint32_t port,
+ uint32_t buffer_size,
+ const void* buffer);
+
+ /** This function is called when the plugin instance wants to send feedback
+ to the GUI. It may be called in response to a command function call,
+ either before or after the command function has returned (depending on
+ whether the GUI host <-> plugin instance communication is synchronous or
+ asynchronous). */
+ void (*feedback)(LV2UI_Handle gui,
+ uint32_t argc,
+ const char* const* argv);
+
+ /** This function is called when the host adds a new program to its program
+ list, or changes the name of an old one. It may be set to NULL if the
+ GUI isn't interested in displaying program information. */
+ void (*program_added)(LV2UI_Handle gui,
+ unsigned char number,
+ const char* name);
+
+ /** This function is called when the host removes a program from its program
+ list. It may be set to NULL if the GUI isn't interested in displaying
+ program information. */
+ void (*program_removed)(LV2UI_Handle gui,
+ unsigned char number);
+
+ /** This function is called when the host clears its program list. It may be
+ set to NULL if the GUI isn't interested in displaying program
+ information. */
+ void (*programs_cleared)(LV2UI_Handle gui);
+
+ /** This function is called when the host changes the current program. It may
+ be set to NULL if the GUI isn't interested in displaying program
+ information. */
+ void (*current_program_changed)(LV2UI_Handle gui,
+ unsigned char number);
+
+ /** 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 GUI is not interested in supporting any extensions. This is similar
+ to the extension_data() member in LV2_Descriptor.
+ */
+ void* (*extension_data)(LV2UI_Handle gui,
+ const char* uri);
+
+} LV2UI_Descriptor;
+
+
+
+/** A plugin 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 GUI 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
+ is returned.
+*/
+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 /* LV2_GUI_H */
+
diff --git a/slv2/pluginguiinstance.h b/slv2/pluginguiinstance.h
index 7801256..2eb9c60 100644
--- a/slv2/pluginguiinstance.h
+++ b/slv2/pluginguiinstance.h
@@ -25,7 +25,7 @@ extern "C" {
#endif
#include <assert.h>
-#include <slv2/lv2-gtk2gui.h>
+#include <slv2/lv2_gui.h>
#include <slv2/plugin.h>
/** \defgroup lib Plugin GUI library access
@@ -72,11 +72,14 @@ typedef struct _SLV2GUIInstance {
* \return NULL if instantiation failed.
*/
SLV2GUIInstance
-slv2_plugin_gtk2_gui_instantiate(SLV2Plugin plugin,
- SLV2Value gui,
- LV2UI_Set_Control_Function control_function,
- LV2UI_Controller controller,
- const LV2_Host_Feature** host_features);
+slv2_plugin_gtk2_gui_instantiate(SLV2Plugin plugin,
+ SLV2Value gui,
+ 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_Host_Feature* const* host_features);
/** Free a plugin GUI instance.
@@ -87,9 +90,9 @@ void
slv2_gtk2_gui_instance_free(SLV2GUIInstance instance);
-/** Get the GTK+ 2.0 widget for the GUI instance.
+/** Get the widget for the GUI instance.
*/
-struct _GtkWidget*
+LV2UI_Widget
slv2_gtk2_gui_instance_get_widget(SLV2GUIInstance instance);
diff --git a/src/pluginguiinstance.c b/src/pluginguiinstance.c
index c115751..a29e64d 100644
--- a/src/pluginguiinstance.c
+++ b/src/pluginguiinstance.c
@@ -32,11 +32,14 @@
SLV2GUIInstance
-slv2_plugin_gtk2_gui_instantiate(SLV2Plugin plugin,
- SLV2Value gui,
- LV2UI_Set_Control_Function control_function,
- LV2UI_Controller controller,
- const LV2_Host_Feature** host_features)
+slv2_plugin_gtk2_gui_instantiate(SLV2Plugin plugin,
+ SLV2Value gui,
+ 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_Host_Feature* const* host_features)
{
assert(gui->type == SLV2_VALUE_GUI);
@@ -48,7 +51,7 @@ slv2_plugin_gtk2_gui_instantiate(SLV2Plugin plugin,
bool local_host_features = (host_features == NULL);
if (local_host_features) {
host_features = malloc(sizeof(LV2_Host_Feature));
- host_features[0] = NULL;
+ ((LV2_Host_Feature**)host_features)[0] = NULL;
}
const char* const lib_uri = slv2_value_as_uri(slv2_plugin_get_gui_library_uri(plugin, gui));
@@ -101,9 +104,12 @@ slv2_plugin_gtk2_gui_instantiate(SLV2Plugin plugin,
impl->lv2ui_handle = ld->instantiate(ld,
slv2_plugin_get_uri(plugin),
(char*)bundle_path,
- control_function,
+ write_function,
+ command_function,
+ program_function,
+ save_function,
controller,
- (struct _GtkWidget**)&impl->widget,
+ &impl->widget,
host_features);
impl->lib_handle = lib;
result->pimpl = impl;
@@ -130,7 +136,7 @@ slv2_plugin_gtk2_gui_instantiate(SLV2Plugin plugin,
}
if (local_host_features)
- free(host_features);
+ free((LV2_Host_Feature**)host_features);
return result;
}
@@ -150,7 +156,7 @@ slv2_gtk2_gui_instance_free(SLV2GUIInstance instance)
}
-struct _GtkWidget*
+LV2UI_Widget
slv2_gtk2_gui_instance_get_widget(SLV2GUIInstance instance) {
return instance->pimpl->widget;
}
diff --git a/src/slv2_internal.h b/src/slv2_internal.h
index d2296cf..1dedc50 100644
--- a/src/slv2_internal.h
+++ b/src/slv2_internal.h
@@ -28,7 +28,7 @@ extern "C" {
#include <inttypes.h>
#include <librdf.h>
#include <slv2/types.h>
-#include <slv2/lv2-gtk2gui.h>
+#include <slv2/lv2_gui.h>
@@ -103,7 +103,7 @@ struct _SLV2GUIInstanceImpl {
void* lib_handle;
const LV2UI_Descriptor* lv2ui_descriptor;
LV2UI_Handle lv2ui_handle;
- void* widget;
+ LV2UI_Widget widget;
};