Refactor jack settings retrieval code
* Move the jack settings retrieval code to studio object * Make the studio object opaque one
This commit is contained in:
parent
d1ec91c6d8
commit
c52d209bed
|
@ -111,78 +111,12 @@ struct room
|
|||
struct studio * studio_ptr; /* Studio connected to the room */
|
||||
};
|
||||
|
||||
struct studio
|
||||
{
|
||||
struct list_head all_connections; /* All connections (studio guts and all rooms). Including superconnections. */
|
||||
struct list_head all_ports; /* All ports (studio guts and all rooms) */
|
||||
struct list_head all_clients; /* All clients (studio guts and all rooms) */
|
||||
struct list_head jack_connections; /* JACK connections (studio guts and all rooms). Including superconnections, excluding virtual connections. */
|
||||
struct list_head jack_ports; /* JACK ports (studio guts and all rooms). Excluding virtual ports. */
|
||||
struct list_head jack_clients; /* JACK clients (studio guts and all rooms). Excluding virtual clients. */
|
||||
struct list_head rooms; /* Rooms connected to the studio */
|
||||
struct list_head clients; /* studio clients (studio guts and room links) */
|
||||
struct list_head ports; /* studio ports (studio guts and room links) */
|
||||
|
||||
bool persisted:1; /* Studio has on-disk representation, i.e. can be reloaded from disk */
|
||||
bool modified:1; /* Studio needs saving */
|
||||
bool jack_conf_obsolete:1; /* JACK server was stopped during configuration retrieval */
|
||||
bool jack_conf_stable:1; /* JACK server configuration obtained successfully */
|
||||
|
||||
struct list_head jack_conf;
|
||||
|
||||
object_path_t * dbus_object;
|
||||
};
|
||||
|
||||
struct jack_parameter_variant
|
||||
{
|
||||
enum
|
||||
{
|
||||
jack_byte,
|
||||
jack_boolean,
|
||||
jack_int16,
|
||||
jack_uint16,
|
||||
jack_int32,
|
||||
jack_uint32,
|
||||
jack_int64,
|
||||
jack_uint64,
|
||||
jack_doubl,
|
||||
jack_string,
|
||||
} type;
|
||||
|
||||
union
|
||||
{
|
||||
unsigned char byte;
|
||||
bool boolean;
|
||||
int16_t int16;
|
||||
uint16_t uint16;
|
||||
int32_t int32;
|
||||
uint32_t uint32;
|
||||
int64_t int64;
|
||||
uint64_t uint64;
|
||||
double doubl;
|
||||
char *string;
|
||||
} value;
|
||||
};
|
||||
|
||||
struct jack_conf_container
|
||||
{
|
||||
struct list_head siblings;
|
||||
char * name;
|
||||
bool children_leafs; /* if true, children are "jack_conf_parameter"s, if false, children are "jack_conf_container"s */
|
||||
struct list_head children;
|
||||
};
|
||||
|
||||
struct jack_conf_parameter
|
||||
{
|
||||
struct list_head siblings;
|
||||
char * name;
|
||||
struct jack_parameter_variant parameter;
|
||||
};
|
||||
#include "studio.h"
|
||||
|
||||
extern DBusConnection * g_dbus_connection;
|
||||
extern DBusError g_dbus_error;
|
||||
extern bool g_quit;
|
||||
extern struct studio * g_studio_ptr;
|
||||
extern studio_handle g_studio;
|
||||
|
||||
#define DBUS_CALL_DEFAULT_TIMEOUT 1000 // in milliseconds
|
||||
|
||||
|
|
345
daemon/jack.c
345
daemon/jack.c
|
@ -29,141 +29,6 @@
|
|||
#include "studio.h"
|
||||
#include "dbus_iface_control.h"
|
||||
|
||||
bool
|
||||
jack_conf_container_create(
|
||||
struct jack_conf_container ** container_ptr_ptr,
|
||||
const char * name)
|
||||
{
|
||||
struct jack_conf_container * container_ptr;
|
||||
|
||||
container_ptr = malloc(sizeof(struct jack_conf_container));
|
||||
if (container_ptr == NULL)
|
||||
{
|
||||
lash_error("malloc() failed to allocate struct jack_conf_container");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
container_ptr->name = strdup(name);
|
||||
if (container_ptr->name == NULL)
|
||||
{
|
||||
lash_error("strdup() failed to duplicate \"%s\"", name);
|
||||
goto fail_free;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&container_ptr->children);
|
||||
container_ptr->children_leafs = false;
|
||||
|
||||
*container_ptr_ptr = container_ptr;
|
||||
return true;
|
||||
|
||||
fail_free:
|
||||
free(container_ptr);
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
jack_conf_container_destroy(
|
||||
struct jack_conf_container * container_ptr)
|
||||
{
|
||||
struct list_head * node_ptr;
|
||||
|
||||
//lash_info("\"%s\" jack_conf_parameter destroy", container_ptr->name);
|
||||
|
||||
if (!container_ptr->children_leafs)
|
||||
{
|
||||
while (!list_empty(&container_ptr->children))
|
||||
{
|
||||
node_ptr = container_ptr->children.next;
|
||||
list_del(node_ptr);
|
||||
jack_conf_container_destroy(list_entry(node_ptr, struct jack_conf_container, siblings));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!list_empty(&container_ptr->children))
|
||||
{
|
||||
node_ptr = container_ptr->children.next;
|
||||
list_del(node_ptr);
|
||||
jack_conf_parameter_destroy(list_entry(node_ptr, struct jack_conf_parameter, siblings));
|
||||
}
|
||||
}
|
||||
|
||||
free(container_ptr->name);
|
||||
free(container_ptr);
|
||||
}
|
||||
|
||||
bool
|
||||
jack_conf_parameter_create(
|
||||
struct jack_conf_parameter ** parameter_ptr_ptr,
|
||||
const char * name)
|
||||
{
|
||||
struct jack_conf_parameter * parameter_ptr;
|
||||
|
||||
parameter_ptr = malloc(sizeof(struct jack_conf_parameter));
|
||||
if (parameter_ptr == NULL)
|
||||
{
|
||||
lash_error("malloc() failed to allocate struct jack_conf_parameter");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
parameter_ptr->name = strdup(name);
|
||||
if (parameter_ptr->name == NULL)
|
||||
{
|
||||
lash_error("strdup() failed to duplicate \"%s\"", name);
|
||||
goto fail_free;
|
||||
}
|
||||
|
||||
*parameter_ptr_ptr = parameter_ptr;
|
||||
return true;
|
||||
|
||||
fail_free:
|
||||
free(parameter_ptr);
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
jack_conf_parameter_destroy(
|
||||
struct jack_conf_parameter * parameter_ptr)
|
||||
{
|
||||
#if 0
|
||||
lash_info("jack_conf_parameter destroy");
|
||||
|
||||
switch (parameter_ptr->parameter.type)
|
||||
{
|
||||
case jack_boolean:
|
||||
lash_info("%s value is %s (boolean)", parameter_ptr->name, parameter_ptr->parameter.value.boolean ? "true" : "false");
|
||||
break;
|
||||
case jack_string:
|
||||
lash_info("%s value is %s (string)", parameter_ptr->name, parameter_ptr->parameter.value.string);
|
||||
break;
|
||||
case jack_byte:
|
||||
lash_info("%s value is %u/%c (byte/char)", parameter_ptr->name, parameter_ptr->parameter.value.byte, (char)parameter_ptr->parameter.value.byte);
|
||||
break;
|
||||
case jack_uint32:
|
||||
lash_info("%s value is %u (uint32)", parameter_ptr->name, (unsigned int)parameter_ptr->parameter.value.uint32);
|
||||
break;
|
||||
case jack_int32:
|
||||
lash_info("%s value is %u (int32)", parameter_ptr->name, (signed int)parameter_ptr->parameter.value.int32);
|
||||
break;
|
||||
default:
|
||||
lash_error("unknown jack parameter_ptr->parameter type %d (%s)", (int)parameter_ptr->parameter.type, parameter_ptr->name);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (parameter_ptr->parameter.type == jack_string)
|
||||
{
|
||||
free(parameter_ptr->parameter.value.string);
|
||||
}
|
||||
|
||||
free(parameter_ptr->name);
|
||||
free(parameter_ptr);
|
||||
}
|
||||
|
||||
bool
|
||||
jack_init(
|
||||
void)
|
||||
|
@ -236,212 +101,38 @@ on_jack_ports_disconnected(
|
|||
lash_info("JACK ports disconnected.");
|
||||
}
|
||||
|
||||
struct conf_callback_context
|
||||
{
|
||||
char address[1024];
|
||||
struct list_head * container_ptr;
|
||||
struct studio * studio_ptr;
|
||||
struct jack_conf_container * parent_ptr;
|
||||
};
|
||||
|
||||
#define context_ptr ((struct conf_callback_context *)context)
|
||||
|
||||
bool
|
||||
conf_callback(
|
||||
void * context,
|
||||
bool leaf,
|
||||
const char * address,
|
||||
char * child)
|
||||
{
|
||||
char path[1024];
|
||||
const char * component;
|
||||
char * dst;
|
||||
size_t len;
|
||||
bool is_set;
|
||||
struct jack_conf_container * parent_ptr;
|
||||
struct jack_conf_container * container_ptr;
|
||||
struct jack_conf_parameter * parameter_ptr;
|
||||
|
||||
if (context_ptr->studio_ptr->jack_conf_obsolete)
|
||||
{
|
||||
context_ptr->studio_ptr = NULL;
|
||||
return false;
|
||||
}
|
||||
|
||||
assert(context_ptr->studio_ptr);
|
||||
|
||||
parent_ptr = context_ptr->parent_ptr;
|
||||
|
||||
dst = path;
|
||||
component = address;
|
||||
while (*component != 0)
|
||||
{
|
||||
len = strlen(component);
|
||||
memcpy(dst, component, len);
|
||||
dst[len] = ':';
|
||||
component += len + 1;
|
||||
dst += len + 1;
|
||||
}
|
||||
|
||||
strcpy(dst, child);
|
||||
|
||||
/* address always is same buffer as the one supplied through context pointer */
|
||||
assert(context_ptr->address == address);
|
||||
dst = (char *)component;
|
||||
|
||||
len = strlen(child) + 1;
|
||||
memcpy(dst, child, len);
|
||||
dst[len] = 0;
|
||||
|
||||
if (leaf)
|
||||
{
|
||||
lash_debug("%s (leaf)", path);
|
||||
|
||||
if (parent_ptr == NULL)
|
||||
{
|
||||
lash_error("jack conf parameters can't appear in root container");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parent_ptr->children_leafs)
|
||||
{
|
||||
if (!list_empty(&parent_ptr->children))
|
||||
{
|
||||
lash_error("jack conf parameters cant be mixed with containers at same hierarchy level");
|
||||
return false;
|
||||
}
|
||||
|
||||
parent_ptr->children_leafs = true;
|
||||
}
|
||||
|
||||
if (!jack_conf_parameter_create(¶meter_ptr, child))
|
||||
{
|
||||
lash_error("jack_conf_parameter_create() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jack_proxy_get_parameter_value(context_ptr->address, &is_set, ¶meter_ptr->parameter))
|
||||
{
|
||||
lash_error("cannot get value of %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_set)
|
||||
{
|
||||
switch (parameter_ptr->parameter.type)
|
||||
{
|
||||
case jack_boolean:
|
||||
lash_info("%s value is %s (boolean)", path, parameter_ptr->parameter.value.boolean ? "true" : "false");
|
||||
break;
|
||||
case jack_string:
|
||||
lash_info("%s value is %s (string)", path, parameter_ptr->parameter.value.string);
|
||||
break;
|
||||
case jack_byte:
|
||||
lash_info("%s value is %u/%c (byte/char)", path, parameter_ptr->parameter.value.byte, (char)parameter_ptr->parameter.value.byte);
|
||||
break;
|
||||
case jack_uint32:
|
||||
lash_info("%s value is %u (uint32)", path, (unsigned int)parameter_ptr->parameter.value.uint32);
|
||||
break;
|
||||
case jack_int32:
|
||||
lash_info("%s value is %u (int32)", path, (signed int)parameter_ptr->parameter.value.int32);
|
||||
break;
|
||||
default:
|
||||
lash_error("unknown jack parameter_ptr->parameter type %d (%s)", (int)parameter_ptr->parameter.type, path);
|
||||
jack_conf_parameter_destroy(parameter_ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
list_add_tail(¶meter_ptr->siblings, &parent_ptr->children);
|
||||
}
|
||||
else
|
||||
{
|
||||
jack_conf_parameter_destroy(parameter_ptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lash_debug("%s (container)", path);
|
||||
|
||||
if (parent_ptr != NULL && parent_ptr->children_leafs)
|
||||
{
|
||||
lash_error("jack conf containers cant be mixed with parameters at same hierarchy level");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jack_conf_container_create(&container_ptr, child))
|
||||
{
|
||||
lash_error("jack_conf_container_create() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parent_ptr == NULL)
|
||||
{
|
||||
list_add_tail(&container_ptr->siblings, &context_ptr->studio_ptr->jack_conf);
|
||||
}
|
||||
else
|
||||
{
|
||||
list_add_tail(&container_ptr->siblings, &parent_ptr->children);
|
||||
}
|
||||
|
||||
context_ptr->parent_ptr = container_ptr;
|
||||
|
||||
if (!jack_proxy_read_conf_container(context_ptr->address, context, conf_callback))
|
||||
{
|
||||
lash_error("cannot read container %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
context_ptr->parent_ptr = parent_ptr;
|
||||
}
|
||||
|
||||
*dst = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef context_ptr
|
||||
|
||||
void
|
||||
on_jack_server_started(
|
||||
void)
|
||||
{
|
||||
struct conf_callback_context context;
|
||||
|
||||
lash_info("JACK server start detected.");
|
||||
|
||||
if (g_studio_ptr == NULL)
|
||||
if (g_studio == NULL)
|
||||
{
|
||||
if (!studio_create(&g_studio_ptr))
|
||||
if (!studio_create(&g_studio))
|
||||
{
|
||||
lash_error("failed to create studio object");
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
context.address[0] = 0;
|
||||
context.container_ptr = &g_studio_ptr->jack_conf;
|
||||
context.studio_ptr = g_studio_ptr;
|
||||
context.parent_ptr = NULL;
|
||||
|
||||
if (jack_proxy_read_conf_container(context.address, &context, conf_callback))
|
||||
if (!studio_fetch_jack_settings(g_studio))
|
||||
{
|
||||
if (g_studio_ptr == context.studio_ptr &&
|
||||
!g_studio_ptr->jack_conf_obsolete)
|
||||
lash_error("studio_fetch_jack_settings() failed.");
|
||||
|
||||
if (!studio_is_persisted(g_studio))
|
||||
{
|
||||
g_studio_ptr->jack_conf_stable = true;
|
||||
lash_info("jack conf successfully retrieved");
|
||||
studio_activate(g_studio_ptr);
|
||||
emit_studio_appeared();
|
||||
emit_studio_disappeared();
|
||||
studio_destroy(g_studio);
|
||||
g_studio = NULL;
|
||||
return;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lash_error("jack_proxy_read_conf_container() failed.");
|
||||
g_studio_ptr = NULL;
|
||||
}
|
||||
|
||||
studio_destroy(context.studio_ptr);
|
||||
lash_info("jack conf successfully retrieved");
|
||||
studio_activate(g_studio);
|
||||
emit_studio_appeared();
|
||||
return;
|
||||
}
|
||||
|
||||
void
|
||||
|
@ -450,18 +141,16 @@ on_jack_server_stopped(
|
|||
{
|
||||
lash_info("JACK server stop detected.");
|
||||
|
||||
if (g_studio_ptr == NULL)
|
||||
if (g_studio == NULL)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
g_studio_ptr->jack_conf_obsolete = true;
|
||||
|
||||
if (!g_studio_ptr->persisted)
|
||||
if (!studio_is_persisted(g_studio))
|
||||
{
|
||||
emit_studio_disappeared();
|
||||
studio_destroy(g_studio_ptr);
|
||||
g_studio_ptr = NULL;
|
||||
studio_destroy(g_studio);
|
||||
g_studio = NULL;
|
||||
return;
|
||||
}
|
||||
|
||||
|
|
|
@ -37,12 +37,4 @@ void
|
|||
jack_uninit(
|
||||
void);
|
||||
|
||||
void
|
||||
jack_conf_container_destroy(
|
||||
struct jack_conf_container * container_ptr);
|
||||
|
||||
void
|
||||
jack_conf_parameter_destroy(
|
||||
struct jack_conf_parameter * parameter_ptr);
|
||||
|
||||
#endif /* #ifndef JACK_H__1C44BAEA_280C_4235_94AB_839499BDE47F__INCLUDED */
|
||||
|
|
|
@ -30,6 +30,37 @@
|
|||
|
||||
#include "common.h"
|
||||
|
||||
struct jack_parameter_variant
|
||||
{
|
||||
enum
|
||||
{
|
||||
jack_byte,
|
||||
jack_boolean,
|
||||
jack_int16,
|
||||
jack_uint16,
|
||||
jack_int32,
|
||||
jack_uint32,
|
||||
jack_int64,
|
||||
jack_uint64,
|
||||
jack_doubl,
|
||||
jack_string,
|
||||
} type;
|
||||
|
||||
union
|
||||
{
|
||||
unsigned char byte;
|
||||
bool boolean;
|
||||
int16_t int16;
|
||||
uint16_t uint16;
|
||||
int32_t int32;
|
||||
uint32_t uint32;
|
||||
int64_t int64;
|
||||
uint64_t uint64;
|
||||
double doubl;
|
||||
char *string;
|
||||
} value;
|
||||
};
|
||||
|
||||
bool
|
||||
jack_proxy_init(
|
||||
void);
|
||||
|
|
|
@ -45,7 +45,7 @@ DBusError g_dbus_error;
|
|||
DBusConnection * g_dbus_connection;
|
||||
const char * g_dbus_unique_name;
|
||||
object_path_t * g_control_object;
|
||||
struct studio * g_studio_ptr;
|
||||
studio_handle g_studio;
|
||||
|
||||
#if 0
|
||||
static DBusHandlerResult lashd_client_disconnect_handler(DBusConnection * connection, DBusMessage * message, void * data)
|
||||
|
@ -262,9 +262,9 @@ int main(int argc, char ** argv, char ** envp)
|
|||
loader_run();
|
||||
}
|
||||
|
||||
if (g_studio_ptr != NULL)
|
||||
if (g_studio != NULL)
|
||||
{
|
||||
studio_destroy(g_studio_ptr);
|
||||
studio_destroy(g_studio);
|
||||
emit_studio_disappeared();
|
||||
}
|
||||
|
||||
|
|
373
daemon/studio.c
373
daemon/studio.c
|
@ -25,11 +25,342 @@
|
|||
*/
|
||||
|
||||
#include "common.h"
|
||||
#include "jack.h"
|
||||
#include "jack_proxy.h"
|
||||
|
||||
struct studio
|
||||
{
|
||||
struct list_head all_connections; /* All connections (studio guts and all rooms). Including superconnections. */
|
||||
struct list_head all_ports; /* All ports (studio guts and all rooms) */
|
||||
struct list_head all_clients; /* All clients (studio guts and all rooms) */
|
||||
struct list_head jack_connections; /* JACK connections (studio guts and all rooms). Including superconnections, excluding virtual connections. */
|
||||
struct list_head jack_ports; /* JACK ports (studio guts and all rooms). Excluding virtual ports. */
|
||||
struct list_head jack_clients; /* JACK clients (studio guts and all rooms). Excluding virtual clients. */
|
||||
struct list_head rooms; /* Rooms connected to the studio */
|
||||
struct list_head clients; /* studio clients (studio guts and room links) */
|
||||
struct list_head ports; /* studio ports (studio guts and room links) */
|
||||
|
||||
bool persisted:1; /* Studio has on-disk representation, i.e. can be reloaded from disk */
|
||||
bool modified:1; /* Studio needs saving */
|
||||
bool jack_conf_stable:1; /* JACK server configuration obtained successfully */
|
||||
|
||||
struct list_head jack_conf;
|
||||
|
||||
object_path_t * dbus_object;
|
||||
};
|
||||
|
||||
struct jack_conf_parameter
|
||||
{
|
||||
struct list_head siblings;
|
||||
char * name;
|
||||
struct jack_parameter_variant parameter;
|
||||
};
|
||||
|
||||
struct jack_conf_container
|
||||
{
|
||||
struct list_head siblings;
|
||||
char * name;
|
||||
bool children_leafs; /* if true, children are "jack_conf_parameter"s, if false, children are "jack_conf_container"s */
|
||||
struct list_head children;
|
||||
};
|
||||
|
||||
struct conf_callback_context
|
||||
{
|
||||
char address[1024];
|
||||
struct list_head * container_ptr;
|
||||
struct studio * studio_ptr;
|
||||
struct jack_conf_container * parent_ptr;
|
||||
};
|
||||
|
||||
bool
|
||||
jack_conf_container_create(
|
||||
struct jack_conf_container ** container_ptr_ptr,
|
||||
const char * name)
|
||||
{
|
||||
struct jack_conf_container * container_ptr;
|
||||
|
||||
container_ptr = malloc(sizeof(struct jack_conf_container));
|
||||
if (container_ptr == NULL)
|
||||
{
|
||||
lash_error("malloc() failed to allocate struct jack_conf_container");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
container_ptr->name = strdup(name);
|
||||
if (container_ptr->name == NULL)
|
||||
{
|
||||
lash_error("strdup() failed to duplicate \"%s\"", name);
|
||||
goto fail_free;
|
||||
}
|
||||
|
||||
INIT_LIST_HEAD(&container_ptr->children);
|
||||
container_ptr->children_leafs = false;
|
||||
|
||||
*container_ptr_ptr = container_ptr;
|
||||
return true;
|
||||
|
||||
fail_free:
|
||||
free(container_ptr);
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
bool
|
||||
jack_conf_parameter_create(
|
||||
struct jack_conf_parameter ** parameter_ptr_ptr,
|
||||
const char * name)
|
||||
{
|
||||
struct jack_conf_parameter * parameter_ptr;
|
||||
|
||||
parameter_ptr = malloc(sizeof(struct jack_conf_parameter));
|
||||
if (parameter_ptr == NULL)
|
||||
{
|
||||
lash_error("malloc() failed to allocate struct jack_conf_parameter");
|
||||
goto fail;
|
||||
}
|
||||
|
||||
parameter_ptr->name = strdup(name);
|
||||
if (parameter_ptr->name == NULL)
|
||||
{
|
||||
lash_error("strdup() failed to duplicate \"%s\"", name);
|
||||
goto fail_free;
|
||||
}
|
||||
|
||||
*parameter_ptr_ptr = parameter_ptr;
|
||||
return true;
|
||||
|
||||
fail_free:
|
||||
free(parameter_ptr);
|
||||
|
||||
fail:
|
||||
return false;
|
||||
}
|
||||
|
||||
void
|
||||
jack_conf_parameter_destroy(
|
||||
struct jack_conf_parameter * parameter_ptr)
|
||||
{
|
||||
#if 0
|
||||
lash_info("jack_conf_parameter destroy");
|
||||
|
||||
switch (parameter_ptr->parameter.type)
|
||||
{
|
||||
case jack_boolean:
|
||||
lash_info("%s value is %s (boolean)", parameter_ptr->name, parameter_ptr->parameter.value.boolean ? "true" : "false");
|
||||
break;
|
||||
case jack_string:
|
||||
lash_info("%s value is %s (string)", parameter_ptr->name, parameter_ptr->parameter.value.string);
|
||||
break;
|
||||
case jack_byte:
|
||||
lash_info("%s value is %u/%c (byte/char)", parameter_ptr->name, parameter_ptr->parameter.value.byte, (char)parameter_ptr->parameter.value.byte);
|
||||
break;
|
||||
case jack_uint32:
|
||||
lash_info("%s value is %u (uint32)", parameter_ptr->name, (unsigned int)parameter_ptr->parameter.value.uint32);
|
||||
break;
|
||||
case jack_int32:
|
||||
lash_info("%s value is %u (int32)", parameter_ptr->name, (signed int)parameter_ptr->parameter.value.int32);
|
||||
break;
|
||||
default:
|
||||
lash_error("unknown jack parameter_ptr->parameter type %d (%s)", (int)parameter_ptr->parameter.type, parameter_ptr->name);
|
||||
break;
|
||||
}
|
||||
#endif
|
||||
|
||||
if (parameter_ptr->parameter.type == jack_string)
|
||||
{
|
||||
free(parameter_ptr->parameter.value.string);
|
||||
}
|
||||
|
||||
free(parameter_ptr->name);
|
||||
free(parameter_ptr);
|
||||
}
|
||||
|
||||
void
|
||||
jack_conf_container_destroy(
|
||||
struct jack_conf_container * container_ptr)
|
||||
{
|
||||
struct list_head * node_ptr;
|
||||
|
||||
//lash_info("\"%s\" jack_conf_parameter destroy", container_ptr->name);
|
||||
|
||||
if (!container_ptr->children_leafs)
|
||||
{
|
||||
while (!list_empty(&container_ptr->children))
|
||||
{
|
||||
node_ptr = container_ptr->children.next;
|
||||
list_del(node_ptr);
|
||||
jack_conf_container_destroy(list_entry(node_ptr, struct jack_conf_container, siblings));
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
while (!list_empty(&container_ptr->children))
|
||||
{
|
||||
node_ptr = container_ptr->children.next;
|
||||
list_del(node_ptr);
|
||||
jack_conf_parameter_destroy(list_entry(node_ptr, struct jack_conf_parameter, siblings));
|
||||
}
|
||||
}
|
||||
|
||||
free(container_ptr->name);
|
||||
free(container_ptr);
|
||||
}
|
||||
|
||||
#define context_ptr ((struct conf_callback_context *)context)
|
||||
|
||||
static
|
||||
bool
|
||||
conf_callback(
|
||||
void * context,
|
||||
bool leaf,
|
||||
const char * address,
|
||||
char * child)
|
||||
{
|
||||
char path[1024];
|
||||
const char * component;
|
||||
char * dst;
|
||||
size_t len;
|
||||
bool is_set;
|
||||
struct jack_conf_container * parent_ptr;
|
||||
struct jack_conf_container * container_ptr;
|
||||
struct jack_conf_parameter * parameter_ptr;
|
||||
|
||||
assert(context_ptr->studio_ptr);
|
||||
|
||||
parent_ptr = context_ptr->parent_ptr;
|
||||
|
||||
dst = path;
|
||||
component = address;
|
||||
while (*component != 0)
|
||||
{
|
||||
len = strlen(component);
|
||||
memcpy(dst, component, len);
|
||||
dst[len] = ':';
|
||||
component += len + 1;
|
||||
dst += len + 1;
|
||||
}
|
||||
|
||||
strcpy(dst, child);
|
||||
|
||||
/* address always is same buffer as the one supplied through context pointer */
|
||||
assert(context_ptr->address == address);
|
||||
dst = (char *)component;
|
||||
|
||||
len = strlen(child) + 1;
|
||||
memcpy(dst, child, len);
|
||||
dst[len] = 0;
|
||||
|
||||
if (leaf)
|
||||
{
|
||||
lash_debug("%s (leaf)", path);
|
||||
|
||||
if (parent_ptr == NULL)
|
||||
{
|
||||
lash_error("jack conf parameters can't appear in root container");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!parent_ptr->children_leafs)
|
||||
{
|
||||
if (!list_empty(&parent_ptr->children))
|
||||
{
|
||||
lash_error("jack conf parameters cant be mixed with containers at same hierarchy level");
|
||||
return false;
|
||||
}
|
||||
|
||||
parent_ptr->children_leafs = true;
|
||||
}
|
||||
|
||||
if (!jack_conf_parameter_create(¶meter_ptr, child))
|
||||
{
|
||||
lash_error("jack_conf_parameter_create() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jack_proxy_get_parameter_value(context_ptr->address, &is_set, ¶meter_ptr->parameter))
|
||||
{
|
||||
lash_error("cannot get value of %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
if (is_set)
|
||||
{
|
||||
switch (parameter_ptr->parameter.type)
|
||||
{
|
||||
case jack_boolean:
|
||||
lash_info("%s value is %s (boolean)", path, parameter_ptr->parameter.value.boolean ? "true" : "false");
|
||||
break;
|
||||
case jack_string:
|
||||
lash_info("%s value is %s (string)", path, parameter_ptr->parameter.value.string);
|
||||
break;
|
||||
case jack_byte:
|
||||
lash_info("%s value is %u/%c (byte/char)", path, parameter_ptr->parameter.value.byte, (char)parameter_ptr->parameter.value.byte);
|
||||
break;
|
||||
case jack_uint32:
|
||||
lash_info("%s value is %u (uint32)", path, (unsigned int)parameter_ptr->parameter.value.uint32);
|
||||
break;
|
||||
case jack_int32:
|
||||
lash_info("%s value is %u (int32)", path, (signed int)parameter_ptr->parameter.value.int32);
|
||||
break;
|
||||
default:
|
||||
lash_error("unknown jack parameter_ptr->parameter type %d (%s)", (int)parameter_ptr->parameter.type, path);
|
||||
jack_conf_parameter_destroy(parameter_ptr);
|
||||
return false;
|
||||
}
|
||||
|
||||
list_add_tail(¶meter_ptr->siblings, &parent_ptr->children);
|
||||
}
|
||||
else
|
||||
{
|
||||
jack_conf_parameter_destroy(parameter_ptr);
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
lash_debug("%s (container)", path);
|
||||
|
||||
if (parent_ptr != NULL && parent_ptr->children_leafs)
|
||||
{
|
||||
lash_error("jack conf containers cant be mixed with parameters at same hierarchy level");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (!jack_conf_container_create(&container_ptr, child))
|
||||
{
|
||||
lash_error("jack_conf_container_create() failed");
|
||||
return false;
|
||||
}
|
||||
|
||||
if (parent_ptr == NULL)
|
||||
{
|
||||
list_add_tail(&container_ptr->siblings, &context_ptr->studio_ptr->jack_conf);
|
||||
}
|
||||
else
|
||||
{
|
||||
list_add_tail(&container_ptr->siblings, &parent_ptr->children);
|
||||
}
|
||||
|
||||
context_ptr->parent_ptr = container_ptr;
|
||||
|
||||
if (!jack_proxy_read_conf_container(context_ptr->address, context, conf_callback))
|
||||
{
|
||||
lash_error("cannot read container %s", path);
|
||||
return false;
|
||||
}
|
||||
|
||||
context_ptr->parent_ptr = parent_ptr;
|
||||
}
|
||||
|
||||
*dst = 0;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#undef context_ptr
|
||||
|
||||
bool
|
||||
studio_create(
|
||||
struct studio ** studio_ptr_ptr)
|
||||
studio_handle * studio_handle_ptr)
|
||||
{
|
||||
struct studio * studio_ptr;
|
||||
|
||||
|
@ -54,21 +385,22 @@ studio_create(
|
|||
|
||||
studio_ptr->modified = false;
|
||||
studio_ptr->persisted = false;
|
||||
studio_ptr->jack_conf_obsolete = false;
|
||||
studio_ptr->jack_conf_stable = false;
|
||||
|
||||
INIT_LIST_HEAD(&studio_ptr->jack_conf);
|
||||
|
||||
studio_ptr->dbus_object = NULL;
|
||||
|
||||
*studio_ptr_ptr = studio_ptr;
|
||||
*studio_handle_ptr = (studio_handle)studio_ptr;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
#define studio_ptr ((struct studio *)studio)
|
||||
|
||||
void
|
||||
studio_destroy(
|
||||
struct studio * studio_ptr)
|
||||
studio_handle studio)
|
||||
{
|
||||
struct list_head * node_ptr;
|
||||
|
||||
|
@ -90,7 +422,7 @@ studio_destroy(
|
|||
|
||||
bool
|
||||
studio_activate(
|
||||
struct studio * studio_ptr)
|
||||
studio_handle studio)
|
||||
{
|
||||
object_path_t * object;
|
||||
|
||||
|
@ -114,3 +446,32 @@ studio_activate(
|
|||
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
studio_is_persisted(
|
||||
studio_handle studio)
|
||||
{
|
||||
return studio_ptr->persisted;
|
||||
}
|
||||
|
||||
#undef studio_ptr
|
||||
|
||||
bool
|
||||
studio_fetch_jack_settings(
|
||||
studio_handle studio)
|
||||
{
|
||||
struct conf_callback_context context;
|
||||
|
||||
context.address[0] = 0;
|
||||
context.studio_ptr = (struct studio *)studio;
|
||||
context.container_ptr = &context.studio_ptr->jack_conf;
|
||||
context.parent_ptr = NULL;
|
||||
|
||||
if (!jack_proxy_read_conf_container(context.address, &context, conf_callback))
|
||||
{
|
||||
lash_error("jack_proxy_read_conf_container() failed.");
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
|
|
@ -27,18 +27,26 @@
|
|||
#ifndef STUDIO_H__0BEDE85E_4FB3_4D74_BC08_C373A22409C0__INCLUDED
|
||||
#define STUDIO_H__0BEDE85E_4FB3_4D74_BC08_C373A22409C0__INCLUDED
|
||||
|
||||
#include "common.h"
|
||||
typedef struct { int unused; } * studio_handle;
|
||||
|
||||
bool
|
||||
studio_create(
|
||||
struct studio ** studio_ptr_ptr);
|
||||
studio_handle * studio_ptr);
|
||||
|
||||
void
|
||||
studio_destroy(
|
||||
struct studio * studio_ptr);
|
||||
studio_handle studio);
|
||||
|
||||
bool
|
||||
studio_activate(
|
||||
struct studio * studio_ptr);
|
||||
studio_handle studio);
|
||||
|
||||
bool
|
||||
studio_fetch_jack_settings(
|
||||
studio_handle studio);
|
||||
|
||||
bool
|
||||
studio_is_persisted(
|
||||
studio_handle studio);
|
||||
|
||||
#endif /* #ifndef STUDIO_H__0BEDE85E_4FB3_4D74_BC08_C373A22409C0__INCLUDED */
|
||||
|
|
Loading…
Reference in New Issue