lv2_gui.h   lv2_gui.h 
/************************************************************************ /************************************************************************
* *
* In-process UI extension for LV2 * In-process UI extension for LV2
* *
* Copyright (C) 2006-2007 Lars Luthman <lars.luthman@gmail.com> * Copyright (C) 2006-2007 Lars Luthman <lars.luthman@gmail.com>
* *
* Based on lv2.h, which is: * Based on lv2.h, which was
* *
* Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis, * Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis,
* Stefan Westerfeld * Stefan Westerfeld
* Copyright (C) 2006 Steve Harris, Dave Robillard. * Copyright (C) 2006 Steve Harris, Dave Robillard.
* *
* This header is free software; you can redistribute it and/or modify it * 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 * under the terms of the GNU Lesser General Public License as published
* by the Free Software Foundation; either version 2.1 of the License, * by the Free Software Foundation; either version 2.1 of the License,
* or (at your option) any later version. * or (at your option) any later version.
* *
skipping to change at line 33 skipping to change at line 33
* You should have received a copy of the GNU Lesser General Public * You should have received a copy of the GNU Lesser General Public
* License along with this library; if not, write to the Free Software * License along with this library; if not, write to the Free Software
* Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
* USA. * USA.
* *
***********************************************************************/ ***********************************************************************/
/** @file /** @file
This extension defines an interface that can be used in LV2 plugins and 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 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 shared object files in an LV2 bundle and are referenced in the RDF data
using the triples (Turtle shown) using the triples (Turtle shown)
<pre> <pre>
@prefix guiext: <http://ll-plugins.nongnu.org/lv2/ext/ipgui/1#> . @@prefix guiext: <http://ll-plugins.nongnu.org/lv2/ext/gui#> .
<http://my.plugin> guiext:gui <http://my.plugingui> . <http://my.plugin> guiext:gui <http://my.plugingui> .
<http://my.plugin> a guiext:GtkGUI .
<http://my.plugingui> guiext:binary <mygui.so> . <http://my.plugingui> guiext:binary <mygui.so> .
</pre> </pre>
where <http://my.plugin> is the URI of the plugin, <http://my.plugingui > is 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 sha red the URI of the plugin GUI and <mygui.so> is the relative URI to the sha red
object file. While it is possible to have the plugin GUI and the plugin in 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 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. separate so that hosts that don't want GUIs don't have to load the GUI code.
A GUI MUST specify its class in the RDF data. In this case the class is
guiext:GtkGUI, which is the only class defined by this extension.
(Note: the prefix above is used throughout this file for the same URI) (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 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 - thi s the GUI for a plugin in a different bundle from the actual plugin - thi s
way people other than the plugin author can write plugin GUIs independe ntly way people other than the plugin author can write plugin GUIs independe ntly
without editing the original plugin bundle. If a GUI is in a separate b without editing the original plugin bundle.
undle
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 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 code and the process that loads the shared object file containing the
actual plugin implementation does not have to be the same. There are ma ny actual plugin implementation does not have to be the same. There are ma ny
valid reasons for having the plugin and the GUI in different processes, or valid reasons for having the plugin and the GUI in different processes, or
even on different machines. This means that you can _not_ use singleton s even on different machines. This means that you can _not_ use singleton s
and global variables and expect them to refer to the same objects in th e and global variables and expect them to refer to the same objects in th e
GUI and the actual plugin. The function callback interface defined in t his GUI and the actual plugin. The function callback interface defined in t his
header is all you can expect to work. header is all you can expect to work.
Since the LV2 specification itself allows for extensions that may add Since the LV2 specification itself allows for extensions that may add
new types of data and configuration parameters that plugin authors may new types of data and configuration parameters that plugin authors may
want to control with a GUI, this extension allows for meta-extensions t hat want to control with a GUI, this extension allows for meta-extensions t hat
can extend the interface between the GUI and the host. See the can extend the interface between the GUI and the host. These extensions
instantiate() and extension_data() callback pointers for more details. mirror the extensions used for plugins - there are required and optiona
l
"features" that you declare in the RDF data for the GUI as
<pre>
<http://my.plugingui> guiext:requiredFeature <http://my.feature> .
<http://my.plugingui> guiext:optionalFeature <http://my.feature> .
</pre>
These predicates have the same semantics as lv2:requiredFeature and
lv2:optionalFeature - if a GUI 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 defin
es
the feature) to the GUI's instantiate() function.
Note that this extension is NOT a Host Feature. There is no way for a p These features may be used to specify how to pass data between the GUI
lugin and the plugin port buffers - see LV2UI_Write_Function for details.
to know whether the host that loads it supports GUIs or not, and the pl
ugin
must ALWAYS work without the GUI (although it may be rather useless unl
ess
it has been configured using the GUI in a previous session).
GUIs written to this specification do not need to be threadsafe - the 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 functions defined below may only be called in the same thread as the UI
main loop is running in. main loop is running in.
Note that this GUI extension is NOT a lv2: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 sessi
on).
*/ */
#ifndef LV2_GUI_H #ifndef LV2_IPGUI_H
#define LV2_GUI_H #define LV2_IPGUI_H
#include "lv2.h" #include "lv2.h"
#ifdef __cplusplus #ifdef __cplusplus
extern "C" { extern "C" {
#endif #endif
/** A pointer to some widget. /** A pointer to some widget.
* The actual type of the widget is defined by the type URI of the GUI. 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 pointe e.g. if "<http://example.org/somegui> a guiext:GtkGUI", this is a point
r er
* to a GtkWidget. All the functionality provided by this extension is to a GtkWidget compatible with GTK+ 2.0 and the GUI can expect the GTK+
* toolkit independent, the host only needs to pass the necessary callbacks main loop to be running during the entire lifetime of all instances of
* and display the widget, if possible. Plugins may have several GUIs, that
* in various toolkits. GUI. 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 vari
ous
toolkits, but guiext:GtkGUI is the only type that is defined in this
extension. */
typedef void* LV2UI_Widget; typedef void* LV2UI_Widget;
/** This handle indicates a particular instance of a GUI. /** This handle indicates a particular instance of a GUI.
It is valid to compare this to NULL (0 for C++) but otherwise the 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 host MUST not attempt to interpret it. The GUI plugin may use it to
reference internal instance data. */ reference internal instance data. */
typedef void* LV2UI_Handle; typedef void* LV2UI_Handle;
/** This handle indicates a particular plugin instance, provided by the hos t. /** This handle indicates a particular plugin instance, provided by the hos t.
It is valid to compare this to NULL (0 for C++) but otherwise the 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 GUI plugin MUST not attempt to interpret it. The host may use it to
reference internal instance data. */ reference internal plugin instance data. */
typedef void* LV2UI_Controller; typedef void* LV2UI_Controller;
/** This is the type of the host-provided function that the GUI can use to /** 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 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 bu ffer to a block of data, @c buffer_size bytes large. The contents of this bu ffer
will depend on the class of the port it's being sent to. For ports of t will depend on the class of the port it's being sent to, and the transf
he er
class lv2:ControlPort, buffer_size should be sizeof(float) and the buff mechanism specified for that port class.
er
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 af Transfer mechanisms are Features and may be defined in meta-extensions.
ter They specify how to translate the data buffers passed to this function
the call. There are no timing guarantees at all for this function, alth to input data for the plugin ports. If a GUI wishes to write data to an
ough input port, it must list a transfer mechanism Feature for that port's
the faster the host can get the data to the plugin port the better. A class as an optional or required feature (depending on whether the GUI
function pointer of this type will be provided to the GUI by the host i will work without being able to write to that port or not). The only
n exception is ports of the class lv2:ControlPort, for which @c buffer_si
the instantiate() function. */ ze
should always be 4 and the buffer should always contain a single IEEE-7
54
float.
The GUI MUST NOT try to write to a port for which there is no specified
transfer mechanism, or to an output port. The GUI is responsible for
allocating the buffer and deallocating it after the call. 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, typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller,
uint32_t port_index, uint32_t port_index,
uint32_t buffer_size, uint32_t buffer_size,
const void* buffer); 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 o
ne
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 b
e
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 ju
st
a request. If the program does change, the GUI's current_program_change
d()
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 { typedef struct _LV2UI_Descriptor {
/** The URI for this GUI (not for the plugin it controls). */ /** The URI for this GUI (not for the plugin it controls). */
const char* URI; const char* URI;
/** Create a new GUI object and return a handle to it. This function work s /** Create a new GUI object and return a handle to it. This function work s
similarly to the instantiate() member in LV2_Descriptor, with the similarly to the instantiate() member in LV2_Descriptor.
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_functio
n
and controller) and a pointer to a LV2_Widget is passed, which the GU
I
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 tr
iples
<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:requiredFe
ature
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 j
ust
use the same data structure.
The same rules apply for these features as for normal host features - @param descriptor The descriptor for the GUI that you want to instant
if a feature is listed as required in the RDF file and the host does iate.
not @param plugin_uri The URI of the plugin that this GUI will control.
support it, it must not load the GUI. @param bundle_path The path to the bundle containing the RDF data fil
e
that references this shared object file, including
the
trailing '/'.
@param write_function A function provided by the host that the GUI ca
n
use to send data to the plugin's input ports.
@param controller A handle for the plugin instance that should be pas
sed
as the first parameter of @c write_function.
@param widget A pointer to an LV2UI_Widget. The GUI will write a
widget pointer to this location (what type of widge
t
depends on the RDF class of the GUI) that will be th
e
main GUI widget.
@param features An array of LV2_Feature pointers. The host must pas
s
all feature URIs that it and the plugin supports an
d any
additional data, just like in the LV2 plugin
instantiate() function.
*/ */
LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor, LV2UI_Handle (*instantiate)(const struct _LV2UI_Descriptor* descriptor,
const char* plugin_uri, const char* plugin_uri,
const char* bundle_path, const char* bundle_path,
LV2UI_Write_Function write_functio n, LV2UI_Write_Function write_functio n,
LV2UI_Command_Function command_funct
ion,
LV2UI_Program_Change_Function program_funct
ion,
LV2UI_Program_Save_Function save_function
,
LV2UI_Controller controller, LV2UI_Controller controller,
LV2UI_Widget* widget, LV2UI_Widget* widget,
const LV2_Feature* const* features); const LV2_Feature* const* features);
/** Destroy the GUI object and the associated widget. /** Destroy the GUI object and the associated widget. The host must not t
ry
to access the widget after calling this function.
*/ */
void (*cleanup)(LV2UI_Handle gui); void (*cleanup)(LV2UI_Handle gui);
/** Tell the GUI that something interesting has happened at a plugin port . /** 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 chan What is interesting and how it is written to the buffer passed to thi
ged, s
for message-based port classes like MIDI or OSC it would be when a function is defined by the specified transfer mechanism for that port
message has arrived in the buffer. For other port classes it is not class (see LV2UI_Write_Function). The only exception is ports of the
defined when this function is called, unless it is specified in the class lv2:ControlPort, for which this function should be called
definition of that port class extension. For control ports the defaul when the port value changes (it must not be called for every single
t change if the host's GUI thread has problems keeping up with the thre
setting is to call this function whenever an input control port value ad
has changed but not when any output control port value has changed, f the plugin is running in), @c buffer_size should be 4 and the buffer
or should contain a single IEEE-754 float.
all other port classes the default setting is to never call this func
tion.
However, the default setting can be modified by using the following By default, the host should only call this function for input ports o
URIs: f
the lv2:ControlPort class. However, the default setting can be modifi
ed
by using the following URIs in the GUI's RDF data:
<pre> <pre>
guiext:portNotification guiext:portNotification
guiext:noPortNotification guiext:noPortNotification
guiext:plugin guiext:plugin
guiext:portIndex guiext:portIndex
</pre> </pre>
For example, if you want the GUI with uri For example, if you want the GUI with uri
<code><http://my.plugingui></code> for the plugin 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 <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 output control port with index 4 changes, you would use the following
in the RDF for your GUI: in the RDF for your GUI:
<pre> <pre>
<http://my.plugingui> guiext:portNotification [ guiext:plugin <http:/ /my.plugin> ; <http://my.plugingui> guiext:portNotification [ guiext:plugin <http:/ /my.plugin> ;
guiext:portIndex 4 ] . guiext:portIndex 4 ] .
</pre> </pre>
and similarly with <code>guiext:noPortNotification</code> if you want and similarly with <code>guiext:noPortNotification</code> if you want
ed to ed
prevent notifications for a port for which it would be on by default to prevent notifications for a port for which it would be on by defau
otherwise. lt
otherwise. The GUI is not allowed to request notifications for ports
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 @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 the GUI wants to keep it for later use it has to copy the contents to an
internal buffer. 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:ControlPo
rt
or llext:MidiPort unless the buffer format and meaning is specified i
n
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 This member may be set to NULL if the GUI is not interested in any
port events. port events.
*/ */
void (*port_event)(LV2UI_Handle gui, void (*port_event)(LV2UI_Handle gui,
uint32_t port, uint32_t port,
uint32_t buffer_size, uint32_t buffer_size,
const void* buffer); const void* buffer);
/** This function is called when the plugin instance wants to send feedba
ck
to the GUI. It may be called in response to a command function call,
either before or after the command function has returned (depending o
n
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 progr
am
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 prog
ram
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 exampl e /** Returns a data structure associated with an extension URI, for exampl e
a struct containing additional function pointers. Avoid returning a struct containing additional function pointers. Avoid returning
function pointers directly since standard C++ has no valid way of 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 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 si milar if the GUI is not interested in supporting any extensions. This is si milar
to the extension_data() member in LV2_Descriptor. to the extension_data() member in LV2_Descriptor.
*/ */
void* (*extension_data)(LV2UI_Handle gui, const void* (*extension_data)(const char* uri);
const char* uri);
} LV2UI_Descriptor; } LV2UI_Descriptor;
/** A plugin programmer must include a function called "lv2ui_descriptor" /** A plugin GUI programmer must include a function called "lv2ui_descripto r"
with the following function prototype within the shared object with the following function prototype within the shared object
file. This function will have C-style linkage (if you are using 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 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 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 @c dlsym() function and called to get a LV2UI_UIDescriptor for the
wanted plugin. wanted plugin.
Just like lv2_descriptor(), this function takes an index parameter. The 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 num ber - index should only be used for enumeration and not as any sort of ID num ber -
the host should just iterate from 0 and upwards until the function retu rns the host should just iterate from 0 and upwards until the function retu rns
skipping to change at line 332 skipping to change at line 275
*/ */
const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index); const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index);
/** This is the type of the lv2ui_descriptor() function. */ /** This is the type of the lv2ui_descriptor() function. */
typedef const LV2UI_Descriptor* (*LV2UI_DescriptorFunction)(uint32_t index) ; typedef const LV2UI_Descriptor* (*LV2UI_DescriptorFunction)(uint32_t index) ;
#ifdef __cplusplus #ifdef __cplusplus
} }
#endif #endif
#endif /* LV2_GUI_H */ #endif
 End of changes. 28 change blocks. 
199 lines changed or deleted 124 lines changed or added


 pluginuiinstance.h   pluginuiinstance.h 
skipping to change at line 65 skipping to change at line 65
* \a host_features NULL-terminated array of features the host supports. * \a host_features NULL-terminated array of features the host supports.
* NULL may be passed if the host supports no additional features (unlike * NULL may be passed if the host supports no additional features (unlike
* the LV2 specification - SLV2 takes care of it). * the LV2 specification - SLV2 takes care of it).
* *
* \return NULL if instantiation failed. * \return NULL if instantiation failed.
*/ */
SLV2UIInstance SLV2UIInstance
slv2_ui_instantiate(SLV2Plugin plugin, slv2_ui_instantiate(SLV2Plugin plugin,
SLV2UI ui, SLV2UI ui,
LV2UI_Write_Function write_function, 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_Controller controller,
const LV2_Feature* const* features); const LV2_Feature* const* features);
/** Free a plugin UI instance. /** 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. * \a instance is invalid after this call.
*/ */
void void
slv2_ui_instance_free(SLV2UIInstance instance); slv2_ui_instance_free(SLV2UIInstance instance);
/** Get the widget for the UI instance. /** Get the widget for the UI instance.
*/ */
LV2UI_Widget LV2UI_Widget
slv2_ui_instance_get_widget(SLV2UIInstance instance); slv2_ui_instance_get_widget(SLV2UIInstance instance);
 End of changes. 2 change blocks. 
3 lines changed or deleted 4 lines changed or added

This html diff was produced by rfcdiff 1.41. The latest version is available from http://tools.ietf.org/tools/rfcdiff/