1 /************************************************************************
2  *
3  * In-process UI extension for LV2
4  *
5  * Copyright (C) 2006-2008 Lars Luthman <lars.luthman@gmail.com>
6  *
7  * Based on lv2.h, which was
8  *
9  * Copyright (C) 2000-2002 Richard W.E. Furse, Paul Barton-Davis,
10  *                         Stefan Westerfeld
11  * Copyright (C) 2006 Steve Harris, Dave Robillard.
12  *
13  * This header is free software; you can redistribute it and/or modify it
14  * under the terms of the GNU Lesser General Public License as published
15  * by the Free Software Foundation; either version 2.1 of the License,
16  * or (at your option) any later version.
17  *
18  * This header is distributed in the hope that it will be useful,
19  * but WITHOUT ANY WARRANTY; without even the implied warranty of
20  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
21  * Lesser General Public License for more details.
22  *
23  * You should have received a copy of the GNU Lesser General Public
24  * License along with this library; if not, write to the Free Software
25  * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301
26  * USA.
27  *
28  ***********************************************************************/
29 
30 /** @file
31     This extension defines an interface that can be used in LV2 plugins and
32     hosts to create UIs for plugins. The UIs are plugins that reside in
33     shared object files in an LV2 bundle and are referenced in the RDF data
34     using the triples (Turtle shown)
35 <pre>
36     @@prefix uiext: <http://lv2plug.in/ns/extensions/ui#> .
37     <http://my.plugin>    uiext:ui     <http://my.pluginui> .
38     <http://my.plugin>    a            uiext:GtkUI .
39     <http://my.pluginui>  uiext:binary <myui.so> .
40 </pre>
41     where <http://my.plugin> is the URI of the plugin, <http://my.pluginui> is
42     the URI of the plugin UI and <myui.so> is the relative URI to the shared
43     object file. While it is possible to have the plugin UI and the plugin in
44     the same shared object file it is probably a good idea to keep them
45     separate so that hosts that don't want UIs don't have to load the UI code.
46     A UI MUST specify its class in the RDF data, in this case uiext:GtkUI. The
47     class defines what type the UI is, e.g. what graphics toolkit it uses.
48     There are no UI classes defined in this extension, those are specified
49     separately (and anyone can define their own).
50 
51     (Note: the prefix above is used throughout this file for the same URI)
52 
53     It's entirely possible to have multiple UIs for the same plugin, or to have
54     the UI for a plugin in a different bundle from the actual plugin - this
55     way people other than the plugin author can write plugin UIs independently
56     without editing the original plugin bundle.
57 
58     Note that the process that loads the shared object file containing the UI
59     code and the process that loads the shared object file containing the
60     actual plugin implementation does not have to be the same. There are many
61     valid reasons for having the plugin and the UI in different processes, or
62     even on different machines. This means that you can _not_ use singletons
63     and global variables and expect them to refer to the same objects in the
64     UI and the actual plugin. The function callback interface defined in this
65     header is all you can expect to work.
66 
67     Since the LV2 specification itself allows for extensions that may add
68     new types of data and configuration parameters that plugin authors may
69     want to control with a UI, this extension allows for meta-extensions that
70     can extend the interface between the UI and the host. These extensions
71     mirror the extensions used for plugins - there are required and optional
72     "features" that you declare in the RDF data for the UI as
73 <pre>
74     <http://my.pluginui> uiext:requiredFeature <http://my.feature> .
75     <http://my.pluginui> uiext:optionalFeature <http://my.feature> .
76 </pre>
77     These predicates have the same semantics as lv2:requiredFeature and
78     lv2:optionalFeature - if a UI is declaring a feature as required, the
79     host is NOT allowed to load it unless it supports that feature, and if it
80     does support a feature (required or optional) it MUST pass that feature's
81     URI and any additional data (specified by the meta-extension that defines
82     the feature) in a LV2_Feature struct (as defined in lv2.h) to the UI's
83     instantiate() function.
84 
85     These features may be used to specify how to pass data between the UI
86     and the plugin port buffers - see LV2UI_Write_Function for details.
87 
88     There are four features defined in this extension that hosts may want to
89     implement:
90 
91 <pre>
92     uiext:makeResident
93 </pre>
94     If this feature is required by a UI the host MUST NEVER unload the shared
95     library containing the UI implementation during the lifetime of the host
96     process (e.g. never calling dlclose() on Linux). This feature may be
97     needed by e.g. a Gtk UI that registers its own Glib types using
98     g_type_register_static() - if it gets unloaded and then loaded again the
99     type registration will break, since there is no way to unregister the
100     types when the library is unloaded. The data pointer in the LV2_Feature
101     for this feature should always be set to NULL.
102 
103 <pre>
104     uiext:makeSONameResident
105 </pre>
106     This feature is ELF specific - it should only be used by UIs that
107     use the ELF file format for the UI shared object files (e.g. on Linux).
108     If it is required by an UI the UI should also list a number of SO names
109     (shared object names) for libraries that the UI shared object
110     depends on and that may not be unloaded during the lifetime of the host
111     process, using the predicate @c uiext:residentSONames, like this:
112 <pre>
113     <http://my.pluginui> uiext:residentSONames "libgtkmm-2.4.so.1", "libfoo.so.0"
114 </pre>
115     The host MUST then make sure that the shared libraries with the given ELF
116     SO names are not unloaded when the plugin UI is, but stay loaded during
117     the entire lifetime of the host process. On Linux this can be accomplished
118     by calling dlopen() on the shared library file with that SO name and never
119     calling a matching dlclose(). However, if a plugin UI requires the
120     @c uiext:makeSONameResident feature, it MUST ALWAYS be safe for the host to
121     just never unload the shared object containing the UI implementation, i.e.
122     act as if the UI required the @c uiext:makeResident feature instead. Thus
123     the host only needs to find the shared library files corresponding to the
124     given SO names if it wants to save RAM by unloading the UI shared object
125     file when it is no longer needed. The data pointer for the LV2_Feature for
126     this feature should always be set to NULL.
127 
128 <pre>
129     uiext:noUserResize
130 </pre>
131     If an UI requires this feature it indicates that it does not make sense
132     to let the user resize the main widget, and the host should prevent that.
133     This feature may not make sense for all UI types. The data pointer for the
134     LV2_Feature for this feature should always be set to NULL.
135 
136 <pre>
137     uiext:fixedSize
138 </pre>
139     If an UI requires this feature it indicates the same thing as
140     uiext:noUserResize, and additionally it means that the UI will not resize
141     the main widget on its own - it will always remain the same size (e.g. a
142     pixmap based GUI). This feature may not make sense for all UI types.
143     The data pointer for the LV2_Feature for this feature should always be set
144     to NULL.
145 
146 
147     UIs written to this specification do not need to be threadsafe - the
148     functions defined below may only be called in the same thread as the UI
149     main loop is running in.
150 
151     Note that this UI extension is NOT a lv2:Feature. There is no way for a
152     plugin to know whether the host that loads it supports UIs or not, and
153     the plugin must ALWAYS work without the UI (although it may be rather
154     useless unless it has been configured using the UI in a previous session).
155 
156     A UI does not have to be a graphical widget, it could just as well be a
157     server listening for OSC input or an interface to some sort of hardware
158     device, depending on the RDF class of the UI.
159 */
160 
161 #ifndef LV2_UI_H
162 #define LV2_UI_H
163 
164 #include "lv2.h"
165 
166 #define LV2_UI_URI "http://lv2plug.in/ns/extensions/ui"
167 
168 
169 #ifdef __cplusplus
170 extern "C" {
171 #endif
172 
173 
174 /** A pointer to some widget or other type of UI handle.
175     The actual type is defined by the type URI of the UI.
176     All the functionality provided by this extension is toolkit
177     independent, the host only needs to pass the necessary callbacks and
178     display the widget, if possible. Plugins may have several UIs, in various
179     toolkits. */
180 typedef void* LV2UI_Widget;
181 
182 
183 /** This handle indicates a particular instance of a UI.
184     It is valid to compare this to NULL (0 for C++) but otherwise the
185     host MUST not attempt to interpret it. The UI plugin may use it to
186     reference internal instance data. */
187 typedef void* LV2UI_Handle;
188 
189 
190 /** This handle indicates a particular plugin instance, provided by the host.
191     It is valid to compare this to NULL (0 for C++) but otherwise the
192     UI plugin MUST not attempt to interpret it. The host may use it to
193     reference internal plugin instance data. */
194 typedef void* LV2UI_Controller;
195 
196 
197 /** This is the type of the host-provided function that the UI can use to
198     send data to a plugin's input ports. The @c buffer parameter must point
199     to a block of data, @c buffer_size bytes large. The contents of this buffer
200     and what the host should do with it depends on the value of the @c format
201     parameter.
202 
203     The @c format parameter should either be 0 or a numeric ID for a "Transfer
204     mechanism". Transfer mechanisms are Features and may be defined in
205     meta-extensions. They specify how to translate the data buffers passed
206     to this function to input data for the plugin ports. If a UI wishes to
207     write data to an input port, it must list a transfer mechanism Feature
208     for that port's class as an optional or required feature (depending on
209     whether the UI will work without being able to write to that port or not).
210     The only exception is when the UI wants to write single float values to
211     input ports of the class lv2:ControlPort, in which case @c buffer_size
212     should always be 4, the buffer should always contain a single IEEE-754
213     float, and @c format should be 0.
214 
215     The numeric IDs for the transfer mechanisms are provided by a
216     URI-to-integer mapping function provided by the host, using the URI Map
217     feature <http://lv2plug.in/ns/ext/uri-map> with the map URI
218     "http://lv2plug.in/ns/extensions/ui". Thus a UI that requires transfer
219     mechanism features also requires the URI Map feature, but this is
220     implicit - the UI does not have to list the URI map feature as a required
221     or optional feature in it's RDF data.
222 
223     An UI MUST NOT pass a @c format parameter value (except 0) that has not
224     been returned by the host-provided URI mapping function for a
225     host-supported transfer mechanism feature URI.
226 
227     The UI MUST NOT try to write to a port for which there is no specified
228     transfer mechanism, or to an output port. The UI is responsible for
229     allocating the buffer and deallocating it after the call.
230 */
231 typedef void (*LV2UI_Write_Function)(LV2UI_Controller controller,
232                                      uint32_t         port_index,
233                                      uint32_t         buffer_size,
234                                      uint32_t         format,
235                                      const void*      buffer);
236 
237 
238 /** This struct contains the implementation of an UI. A pointer to an
239     object of this type is returned by the lv2ui_descriptor() function.
240 */
241 typedef struct LV2UI_Descriptor {
242 
243   /** The URI for this UI (not for the plugin it controls). */
244   const char* URI;
245 
246   /** Create a new UI object and return a handle to it. This function works
247       similarly to the instantiate() member in LV2_Descriptor.
248 
249       @param descriptor The descriptor for the UI that you want to instantiate.
250       @param plugin_uri The URI of the plugin that this UI will control.
251       @param bundle_path The path to the bundle containing the RDF data file
252                          that references this shared object file, including the
253                          trailing '/'.
254       @param write_function A function provided by the host that the UI can
255                             use to send data to the plugin's input ports.
256       @param controller A handle for the plugin instance that should be passed
257                         as the first parameter of @c write_function.
258       @param widget     A pointer to an LV2UI_Widget. The UI will write a
259                         widget pointer to this location (what type of widget
260                         depends on the RDF class of the UI) that will be the
261                         main UI widget.
262       @param features   An array of LV2_Feature pointers. The host must pass
263                         all feature URIs that it and the UI supports and any
264                         additional data, just like in the LV2 plugin
265                         instantiate() function. Note that UI features and plugin
266 			features are NOT necessarily the same, they just share
267 			the same data structure - this will probably not be the
268 			same array as the one the plugin host passes to a
269 			plugin.
270   */
271   LV2UI_Handle (*instantiate)(const struct LV2UI_Descriptor* descriptor,
272                               const char*                     plugin_uri,
273                               const char*                     bundle_path,
274                               LV2UI_Write_Function            write_function,
275                               LV2UI_Controller                controller,
276                               LV2UI_Widget*                   widget,
277                               const LV2_Feature* const*       features);
278 
279 
280   /** Destroy the UI object and the associated widget. The host must not try
281       to access the widget after calling this function.
282    */
283   void (*cleanup)(LV2UI_Handle ui);
284 
285   /** Tell the UI that something interesting has happened at a plugin port.
286       What is interesting and how it is written to the buffer passed to this
287       function is defined by the @c format parameter, which has the same
288       meaning as in LV2UI_Write_Function. The only exception is ports of the
289       class lv2:ControlPort, for which this function should be called
290       when the port value changes (it does not have to be called for every
291       single change if the host's UI thread has problems keeping up with
292       the thread the plugin is running in), @c buffer_size should be 4 and the
293       buffer should contain a single IEEE-754 float. In this case the @c format
294       parameter should be 0.
295 
296       By default, the host should only call this function for input ports of
297       the lv2:ControlPort class. However, the default setting can be modified
298       by using the following URIs in the UI's RDF data:
299       <pre>
300       uiext:portNotification
301       uiext:noPortNotification
302       uiext:plugin
303       uiext:portIndex
304       </pre>
305       For example, if you want the UI with uri
306       <code><http://my.pluginui></code> for the plugin with URI
307       <code><http://my.plugin></code> to get notified when the value of the
308       output control port with index 4 changes, you would use the following
309       in the RDF for your UI:
310       <pre>
311       <http://my.pluginui> uiext:portNotification [ uiext:plugin <http://my.plugin> ;
312                                                       uiext:portIndex 4 ] .
313       </pre>
314       and similarly with <code>uiext:noPortNotification</code> if you wanted
315       to prevent notifications for a port for which it would be on by default
316       otherwise. The UI is not allowed to request notifications for ports of
317       types for which no transfer mechanism is specified, if it does it should
318       be considered broken and the host should not load it.
319 
320       The @c buffer is only valid during the time of this function call, so if
321       the UI wants to keep it for later use it has to copy the contents to an
322       internal buffer.
323 
324       This member may be set to NULL if the UI is not interested in any
325       port events.
326   */
327   void (*port_event)(LV2UI_Handle ui,
328                      uint32_t     port_index,
329                      uint32_t     buffer_size,
330                      uint32_t     format,
331                      const void*  buffer);
332 
333   /** Returns a data structure associated with an extension URI, for example
334       a struct containing additional function pointers. Avoid returning
335       function pointers directly since standard C++ has no valid way of
336       casting a void* to a function pointer. This member may be set to NULL
337       if the UI is not interested in supporting any extensions. This is similar
338       to the extension_data() member in LV2_Descriptor.
339   */
340   const void* (*extension_data)(const char*  uri);
341 
342 } LV2UI_Descriptor;
343 
344 
345 
346 /** A plugin UI programmer must include a function called "lv2ui_descriptor"
347     with the following function prototype within the shared object
348     file. This function will have C-style linkage (if you are using
349     C++ this is taken care of by the 'extern "C"' clause at the top of
350     the file). This function will be accessed by the UI host using the
351     @c dlsym() function and called to get a LV2UI_UIDescriptor for the
352     wanted plugin.
353 
354     Just like lv2_descriptor(), this function takes an index parameter. The
355     index should only be used for enumeration and not as any sort of ID number -
356     the host should just iterate from 0 and upwards until the function returns
357     NULL or a descriptor with an URI matching the one the host is looking for.
358 */
359 const LV2UI_Descriptor* lv2ui_descriptor(uint32_t index);
360 
361 
362 /** This is the type of the lv2ui_descriptor() function. */
363 typedef const LV2UI_Descriptor* (*LV2UI_DescriptorFunction)(uint32_t index);
364 
365 
366 
367 #ifdef __cplusplus
368 }
369 #endif
370 
371 
372 #endif
373