diff options
author | David Robillard <d@drobilla.net> | 2022-05-30 18:34:07 -0400 |
---|---|---|
committer | David Robillard <d@drobilla.net> | 2022-08-17 13:50:22 -0400 |
commit | 0133dc3e000496fb0667c7548f1404958b6eeca5 (patch) | |
tree | 379d82ee876fd8192bf96add8a84ebe67443a130 /src | |
parent | b58430c852867ab546cd3644765e33813e1aa5bb (diff) | |
download | jalv-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.c | 97 | ||||
-rw-r--r-- | src/control.h | 15 | ||||
-rw-r--r-- | src/jalv.c | 21 | ||||
-rw-r--r-- | src/jalv_gtk.c | 40 | ||||
-rw-r--r-- | src/jalv_internal.h | 45 |
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); @@ -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); |