aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorDavid Robillard <d@drobilla.net>2022-05-30 18:34:07 -0400
committerDavid Robillard <d@drobilla.net>2022-08-17 13:50:22 -0400
commit0133dc3e000496fb0667c7548f1404958b6eeca5 (patch)
tree379d82ee876fd8192bf96add8a84ebe67443a130 /src
parentb58430c852867ab546cd3644765e33813e1aa5bb (diff)
downloadjalv-0133dc3e000496fb0667c7548f1404958b6eeca5.tar.gz
jalv-0133dc3e000496fb0667c7548f1404958b6eeca5.tar.bz2
jalv-0133dc3e000496fb0667c7548f1404958b6eeca5.zip
Remove Jalv back pointer from ControlID
Bit of a kludge, but this unblocks further cleanup and modularization. The Gtk static data / signal issues can be addressed later.
Diffstat (limited to 'src')
-rw-r--r--src/control.c97
-rw-r--r--src/control.h15
-rw-r--r--src/jalv.c21
-rw-r--r--src/jalv_gtk.c40
-rw-r--r--src/jalv_internal.h45
5 files changed, 127 insertions, 91 deletions
diff --git a/src/control.c b/src/control.c
index 51afa08..a75d999 100644
--- a/src/control.c
+++ b/src/control.c
@@ -33,51 +33,52 @@ scale_point_cmp(const ScalePoint* a, const ScalePoint* b)
}
ControlID*
-new_port_control(Jalv* jalv, uint32_t index)
+new_port_control(LilvWorld* const world,
+ const LilvPlugin* const plugin,
+ const LilvPort* const port,
+ uint32_t port_index,
+ const float sample_rate,
+ const JalvNodes* const nodes,
+ LV2_Atom_Forge* const forge)
{
- struct Port* port = &jalv->ports[index];
- const LilvPort* lport = port->lilv_port;
- const LilvPlugin* plug = jalv->plugin;
- const JalvNodes* nodes = &jalv->nodes;
-
ControlID* id = (ControlID*)calloc(1, sizeof(ControlID));
- id->jalv = jalv;
id->type = PORT;
- id->node = lilv_node_duplicate(lilv_port_get_node(plug, lport));
- id->symbol = lilv_node_duplicate(lilv_port_get_symbol(plug, lport));
- id->label = lilv_port_get_name(plug, lport);
- id->index = index;
- id->group = lilv_port_get(plug, lport, jalv->nodes.pg_group);
- id->value_type = jalv->forge.Float;
- id->is_writable = lilv_port_is_a(plug, lport, nodes->lv2_InputPort);
- id->is_readable = lilv_port_is_a(plug, lport, nodes->lv2_OutputPort);
- id->is_toggle = lilv_port_has_property(plug, lport, nodes->lv2_toggled);
- id->is_integer = lilv_port_has_property(plug, lport, nodes->lv2_integer);
+ id->node = lilv_node_duplicate(lilv_port_get_node(plugin, port));
+ id->symbol = lilv_node_duplicate(lilv_port_get_symbol(plugin, port));
+ id->label = lilv_port_get_name(plugin, port);
+ id->forge = forge;
+ id->index = port_index;
+ id->group = lilv_port_get(plugin, port, nodes->pg_group);
+ id->value_type = forge->Float;
+ id->is_writable = lilv_port_is_a(plugin, port, nodes->lv2_InputPort);
+ id->is_readable = lilv_port_is_a(plugin, port, nodes->lv2_OutputPort);
+ id->is_toggle = lilv_port_has_property(plugin, port, nodes->lv2_toggled);
+ id->is_integer = lilv_port_has_property(plugin, port, nodes->lv2_integer);
id->is_enumeration =
- lilv_port_has_property(plug, lport, nodes->lv2_enumeration);
+ lilv_port_has_property(plugin, port, nodes->lv2_enumeration);
id->is_logarithmic =
- lilv_port_has_property(plug, lport, nodes->pprops_logarithmic);
+ lilv_port_has_property(plugin, port, nodes->pprops_logarithmic);
- lilv_port_get_range(plug, lport, &id->def, &id->min, &id->max);
- if (lilv_port_has_property(plug, lport, jalv->nodes.lv2_sampleRate)) {
+ lilv_port_get_range(plugin, port, &id->def, &id->min, &id->max);
+ if (lilv_port_has_property(plugin, port, nodes->lv2_sampleRate)) {
// Adjust range for lv2:sampleRate controls
if (lilv_node_is_float(id->min) || lilv_node_is_int(id->min)) {
- const float min = lilv_node_as_float(id->min) * jalv->sample_rate;
+ const float min = lilv_node_as_float(id->min) * sample_rate;
lilv_node_free(id->min);
- id->min = lilv_new_float(jalv->world, min);
+ id->min = lilv_new_float(world, min);
}
if (lilv_node_is_float(id->max) || lilv_node_is_int(id->max)) {
- const float max = lilv_node_as_float(id->max) * jalv->sample_rate;
+ const float max = lilv_node_as_float(id->max) * sample_rate;
lilv_node_free(id->max);
- id->max = lilv_new_float(jalv->world, max);
+ id->max = lilv_new_float(world, max);
}
}
// Get scale points
- LilvScalePoints* sp = lilv_port_get_scale_points(plug, lport);
+ LilvScalePoints* sp = lilv_port_get_scale_points(plugin, port);
if (sp) {
id->points =
(ScalePoint*)malloc(lilv_scale_points_size(sp) * sizeof(ScalePoint));
@@ -109,34 +110,36 @@ new_port_control(Jalv* jalv, uint32_t index)
}
static bool
-has_range(Jalv* jalv, const LilvNode* subject, const char* range_uri)
+has_range(LilvWorld* const world,
+ const JalvNodes* const nodes,
+ const LilvNode* const subject,
+ const char* const range_uri)
{
- LilvNode* range = lilv_new_uri(jalv->world, range_uri);
- const bool result =
- lilv_world_ask(jalv->world, subject, jalv->nodes.rdfs_range, range);
+ LilvNode* range = lilv_new_uri(world, range_uri);
+ const bool result = lilv_world_ask(world, subject, nodes->rdfs_range, range);
lilv_node_free(range);
return result;
}
ControlID*
-new_property_control(Jalv* jalv, const LilvNode* property)
+new_property_control(LilvWorld* const world,
+ const LilvNode* property,
+ const JalvNodes* const nodes,
+ LV2_URID_Map* const map,
+ LV2_Atom_Forge* const forge)
{
ControlID* id = (ControlID*)calloc(1, sizeof(ControlID));
- id->jalv = jalv;
id->type = PROPERTY;
id->node = lilv_node_duplicate(property);
- id->symbol = lilv_world_get_symbol(jalv->world, property);
- id->property = jalv->map.map(jalv, lilv_node_as_uri(property));
-
- id->label =
- lilv_world_get(jalv->world, property, jalv->nodes.rdfs_label, NULL);
- id->min =
- lilv_world_get(jalv->world, property, jalv->nodes.lv2_minimum, NULL);
- id->max =
- lilv_world_get(jalv->world, property, jalv->nodes.lv2_maximum, NULL);
- id->def =
- lilv_world_get(jalv->world, property, jalv->nodes.lv2_default, NULL);
+ id->symbol = lilv_world_get_symbol(world, property);
+ id->forge = forge;
+ id->property = map->map(map->handle, lilv_node_as_uri(property));
+
+ id->label = lilv_world_get(world, property, nodes->rdfs_label, NULL);
+ id->min = lilv_world_get(world, property, nodes->lv2_minimum, NULL);
+ id->max = lilv_world_get(world, property, nodes->lv2_maximum, NULL);
+ id->def = lilv_world_get(world, property, nodes->lv2_default, NULL);
const char* const types[] = {LV2_ATOM__Int,
LV2_ATOM__Long,
@@ -148,15 +151,15 @@ new_property_control(Jalv* jalv, const LilvNode* property)
NULL};
for (const char* const* t = types; *t; ++t) {
- if (has_range(jalv, property, *t)) {
- id->value_type = jalv->map.map(jalv, *t);
+ if (has_range(world, nodes, property, *t)) {
+ id->value_type = map->map(map->handle, *t);
break;
}
}
- id->is_toggle = (id->value_type == jalv->forge.Bool);
+ id->is_toggle = (id->value_type == forge->Bool);
id->is_integer =
- (id->value_type == jalv->forge.Int || id->value_type == jalv->forge.Long);
+ (id->value_type == forge->Int || id->value_type == forge->Long);
if (!id->value_type) {
fprintf(stderr,
diff --git a/src/control.h b/src/control.h
index 0442599..609d75a 100644
--- a/src/control.h
+++ b/src/control.h
@@ -7,6 +7,7 @@
#include "jalv_internal.h"
#include "lilv/lilv.h"
+#include "lv2/atom/forge.h"
#include "lv2/urid/urid.h"
#include <stdint.h>
@@ -22,10 +23,20 @@ int
scale_point_cmp(const ScalePoint* a, const ScalePoint* b);
ControlID*
-new_port_control(Jalv* jalv, uint32_t index);
+new_port_control(LilvWorld* world,
+ const LilvPlugin* plugin,
+ const LilvPort* port,
+ uint32_t port_index,
+ float sample_rate,
+ const JalvNodes* nodes,
+ LV2_Atom_Forge* forge);
ControlID*
-new_property_control(Jalv* jalv, const LilvNode* property);
+new_property_control(LilvWorld* world,
+ const LilvNode* property,
+ const JalvNodes* nodes,
+ LV2_URID_Map* map,
+ LV2_Atom_Forge* forge);
void
add_control(Controls* controls, ControlID* control);
diff --git a/src/jalv.c b/src/jalv.c
index 9e93848..be676f4 100644
--- a/src/jalv.c
+++ b/src/jalv.c
@@ -193,7 +193,14 @@ create_port(Jalv* jalv, uint32_t port_index, float default_value)
port->type = TYPE_CONTROL;
port->control = isnan(default_value) ? 0.0f : default_value;
if (!hidden) {
- add_control(&jalv->controls, new_port_control(jalv, port->index));
+ add_control(&jalv->controls,
+ new_port_control(jalv->world,
+ jalv->plugin,
+ port->lilv_port,
+ port->index,
+ jalv->sample_rate,
+ &jalv->nodes,
+ &jalv->forge));
}
} else if (lilv_port_is_a(
jalv->plugin, port->lilv_port, jalv->nodes.lv2_AudioPort)) {
@@ -344,7 +351,9 @@ jalv_create_controls(Jalv* jalv, bool writable)
}
}
- record = new_property_control(jalv, property);
+ record = new_property_control(
+ jalv->world, property, &jalv->nodes, &jalv->map, &jalv->forge);
+
if (writable) {
record->is_writable = true;
} else {
@@ -367,14 +376,14 @@ jalv_create_controls(Jalv* jalv, bool writable)
}
void
-jalv_set_control(const ControlID* control,
+jalv_set_control(Jalv* jalv,
+ const ControlID* control,
uint32_t size,
LV2_URID type,
const void* body)
{
- Jalv* jalv = control->jalv;
if (control->type == PORT && type == jalv->forge.Float) {
- struct Port* port = &control->jalv->ports[control->index];
+ struct Port* port = &jalv->ports[control->index];
port->control = *(const float*)body;
} else if (control->type == PROPERTY) {
// Copy forge since it is used by process thread
@@ -714,7 +723,7 @@ jalv_apply_control_arg(Jalv* jalv, const char* s)
return false;
}
- jalv_set_control(control, sizeof(float), jalv->urids.atom_Float, &val);
+ jalv_set_control(jalv, control, sizeof(float), jalv->urids.atom_Float, &val);
printf("%s = %f\n", sym, val);
return true;
diff --git a/src/jalv_gtk.c b/src/jalv_gtk.c
index 6c66b43..4d9248c 100644
--- a/src/jalv_gtk.c
+++ b/src/jalv_gtk.c
@@ -34,6 +34,16 @@ LV2_DISABLE_DEPRECATION_WARNINGS
#include <stdlib.h>
#include <string.h>
+/* TODO: Gtk only provides one pointer for value changed callbacks, which we
+ use for the ControlID. So, there is no easy way to pass both a ControlID
+ and Jalv which is needed to actually do anything with a control. Work
+ around this by statically storing the Jalv instance. Since this UI isn't a
+ module, this isn't the end of the world, but a global "god pointer" is a
+ pretty bad smell. Refactoring things to be more modular or changing how Gtk
+ signals are connected would be a good idea.
+*/
+static Jalv* s_jalv = NULL;
+
static GtkCheckMenuItem* active_preset_item = NULL;
static bool updating = false;
@@ -581,7 +591,7 @@ set_control(const ControlID* control,
const void* body)
{
if (!updating) {
- jalv_set_control(control, size, type, body);
+ jalv_set_control(s_jalv, control, size, type, body);
}
}
@@ -594,20 +604,20 @@ differ_enough(float a, float b)
static void
set_float_control(const ControlID* control, float value)
{
- if (control->value_type == control->jalv->forge.Int) {
+ if (control->value_type == control->forge->Int) {
const int32_t ival = lrintf(value);
- set_control(control, sizeof(ival), control->jalv->forge.Int, &ival);
- } else if (control->value_type == control->jalv->forge.Long) {
+ set_control(control, sizeof(ival), control->forge->Int, &ival);
+ } else if (control->value_type == control->forge->Long) {
const int64_t lval = lrintf(value);
- set_control(control, sizeof(lval), control->jalv->forge.Long, &lval);
- } else if (control->value_type == control->jalv->forge.Float) {
- set_control(control, sizeof(value), control->jalv->forge.Float, &value);
- } else if (control->value_type == control->jalv->forge.Double) {
+ set_control(control, sizeof(lval), control->forge->Long, &lval);
+ } else if (control->value_type == control->forge->Float) {
+ set_control(control, sizeof(value), control->forge->Float, &value);
+ } else if (control->value_type == control->forge->Double) {
const double dval = value;
- set_control(control, sizeof(dval), control->jalv->forge.Double, &dval);
- } else if (control->value_type == control->jalv->forge.Bool) {
+ set_control(control, sizeof(dval), control->forge->Double, &dval);
+ } else if (control->value_type == control->forge->Bool) {
const int32_t ival = value;
- set_control(control, sizeof(ival), control->jalv->forge.Bool, &ival);
+ set_control(control, sizeof(ival), control->forge->Bool, &ival);
}
Controller* controller = (Controller*)control->widget;
@@ -910,18 +920,17 @@ string_changed(GtkEntry* widget, gpointer data)
ControlID* control = (ControlID*)data;
const char* string = gtk_entry_get_text(widget);
- set_control(control, strlen(string) + 1, control->jalv->forge.String, string);
+ set_control(control, strlen(string) + 1, control->forge->String, string);
}
static void
file_changed(GtkFileChooserButton* widget, gpointer data)
{
ControlID* control = (ControlID*)data;
- Jalv* jalv = control->jalv;
const char* filename =
gtk_file_chooser_get_filename(GTK_FILE_CHOOSER(widget));
- set_control(control, strlen(filename) + 1, jalv->forge.Path, filename);
+ set_control(control, strlen(filename) + 1, s_jalv->forge.Path, filename);
}
static Controller*
@@ -1471,6 +1480,8 @@ jalv_frontend_open(Jalv* jalv)
GtkWidget* window = gtk_window_new(GTK_WINDOW_TOPLEVEL);
jalv->window = window;
+ s_jalv = jalv;
+
g_signal_connect(window, "destroy", G_CALLBACK(on_window_destroy), jalv);
set_window_title(jalv);
@@ -1541,6 +1552,7 @@ int
jalv_frontend_close(Jalv* ZIX_UNUSED(jalv))
{
gtk_main_quit();
+ s_jalv = NULL;
return 0;
}
diff --git a/src/jalv_internal.h b/src/jalv_internal.h
index 800f88a..d186679 100644
--- a/src/jalv_internal.h
+++ b/src/jalv_internal.h
@@ -80,27 +80,27 @@ typedef struct {
/// Plugin control
typedef struct {
- Jalv* jalv;
- ControlType type;
- LilvNode* node;
- LilvNode* symbol; ///< Symbol
- LilvNode* label; ///< Human readable label
- LV2_URID property; ///< Iff type == PROPERTY
- uint32_t index; ///< Iff type == PORT
- LilvNode* group; ///< Port/control group, or NULL
- void* widget; ///< Control Widget
- size_t n_points; ///< Number of scale points
- ScalePoint* points; ///< Scale points
- LV2_URID value_type; ///< Type of control value
- LilvNode* min; ///< Minimum value
- LilvNode* max; ///< Maximum value
- LilvNode* def; ///< Default value
- bool is_toggle; ///< Boolean (0 and 1 only)
- bool is_integer; ///< Integer values only
- bool is_enumeration; ///< Point values only
- bool is_logarithmic; ///< Logarithmic scale
- bool is_writable; ///< Writable (input)
- bool is_readable; ///< Readable (output)
+ ControlType type; ///< Type of control
+ LilvNode* node; ///< Port or property
+ LilvNode* symbol; ///< Symbol
+ LilvNode* label; ///< Human readable label
+ LV2_Atom_Forge* forge; ///< Forge (for URIDs)
+ LV2_URID property; ///< Iff type == PROPERTY
+ uint32_t index; ///< Iff type == PORT
+ LilvNode* group; ///< Port/control group, or NULL
+ void* widget; ///< Control Widget
+ size_t n_points; ///< Number of scale points
+ ScalePoint* points; ///< Scale points
+ LV2_URID value_type; ///< Type of control value
+ LilvNode* min; ///< Minimum value
+ LilvNode* max; ///< Maximum value
+ LilvNode* def; ///< Default value
+ bool is_toggle; ///< Boolean (0 and 1 only)
+ bool is_integer; ///< Integer values only
+ bool is_enumeration; ///< Point values only
+ bool is_logarithmic; ///< Logarithmic scale
+ bool is_writable; ///< Writable (input)
+ bool is_readable; ///< Readable (output)
} ControlID;
typedef struct {
@@ -325,7 +325,8 @@ ControlID*
jalv_control_by_symbol(Jalv* jalv, const char* sym);
void
-jalv_set_control(const ControlID* control,
+jalv_set_control(Jalv* jalv,
+ const ControlID* control,
uint32_t size,
LV2_URID type,
const void* body);