ladish/daemon/jack_proxy.c

401 lines
9.2 KiB
C
Raw Normal View History

2009-07-23 00:23:18 +03:00
/* -*- Mode: C ; c-basic-offset: 2 -*- */
/*****************************************************************************
*
* DESCRIPTION:
* Helper functionality for accessing JACK through D-Bus
*
*****************************************************************************/
2009-07-24 01:39:06 +03:00
//#define LASH_DEBUG
2009-07-23 00:23:18 +03:00
#include "jack_proxy.h"
2009-07-23 01:37:53 +03:00
#define JACKDBUS_SERVICE "org.jackaudio.service"
#define JACKDBUS_OBJECT "/org/jackaudio/Controller"
#define JACKDBUS_IFACE_CONTROL "org.jackaudio.JackControl"
#define JACKDBUS_IFACE_PATCHBAY "org.jackaudio.JackPatchbay"
2009-07-24 01:39:06 +03:00
static
void
on_jack_patchbay_signal(
DBusMessage * message_ptr,
const char * signal_name)
{
const char * client1_name;
const char * port1_name;
const char * client2_name;
const char * port2_name;
dbus_uint64_t dummy;
dbus_uint64_t client1_id;
dbus_uint64_t client2_id;
dbus_uint64_t port1_id;
dbus_uint64_t port2_id;
dbus_error_init(&g_dbus_error);
if (strcmp(signal_name, "ClientAppeared") == 0)
{
lash_debug("Received ClientAppeared signal");
if (!dbus_message_get_args(
message_ptr,
&g_dbus_error,
DBUS_TYPE_UINT64, &dummy,
DBUS_TYPE_UINT64, &client1_id,
DBUS_TYPE_STRING, &client1_name,
DBUS_TYPE_INVALID))
{
goto fail;
}
on_jack_client_appeared(client1_id, client1_name);
return;
}
if (strcmp(signal_name, "ClientDisappeared") == 0)
{
lash_debug("Received ClientDisappeared signal");
if (!dbus_message_get_args(
message_ptr,
&g_dbus_error,
DBUS_TYPE_UINT64, &dummy,
DBUS_TYPE_UINT64, &client1_id,
DBUS_TYPE_STRING, &client1_name,
DBUS_TYPE_INVALID))
{
goto fail;
}
on_jack_client_disappeared(client1_id);
return;
}
if (strcmp(signal_name, "PortAppeared") == 0)
{
lash_debug("Received PortAppeared signal");
if (!dbus_message_get_args(
message_ptr,
&g_dbus_error,
DBUS_TYPE_UINT64, &dummy,
DBUS_TYPE_UINT64, &client1_id,
DBUS_TYPE_STRING, &client1_name,
DBUS_TYPE_UINT64, &port1_id,
DBUS_TYPE_STRING, &port1_name,
DBUS_TYPE_INVALID))
{
goto fail;
}
on_jack_port_appeared(client1_id, port1_id, port1_name);
return;
}
if (strcmp(signal_name, "PortsConnected") == 0)
{
lash_debug("Received PortsConnected signal");
if (!dbus_message_get_args(
message_ptr,
&g_dbus_error,
DBUS_TYPE_UINT64, &dummy,
DBUS_TYPE_UINT64, &client1_id,
DBUS_TYPE_STRING, &client1_name,
DBUS_TYPE_UINT64, &port1_id,
DBUS_TYPE_STRING, &port1_name,
DBUS_TYPE_UINT64, &client2_id,
DBUS_TYPE_STRING, &client2_name,
DBUS_TYPE_UINT64, &port2_id,
DBUS_TYPE_STRING, &port2_name,
DBUS_TYPE_INVALID))
{
goto fail;
}
on_jack_ports_connected(
client1_id,
port1_id,
client2_id,
port2_id);
return;
}
if (strcmp(signal_name, "PortsDisconnected") == 0)
{
lash_debug("Received PortsDisconnected signal");
if (!dbus_message_get_args(
message_ptr,
&g_dbus_error,
DBUS_TYPE_UINT64, &dummy,
DBUS_TYPE_UINT64, &client1_id,
DBUS_TYPE_STRING, &client1_name,
DBUS_TYPE_UINT64, &port1_id,
DBUS_TYPE_STRING, &port1_name,
DBUS_TYPE_UINT64, &client2_id,
DBUS_TYPE_STRING, &client2_name,
DBUS_TYPE_UINT64, &port2_id,
DBUS_TYPE_STRING, &port2_name,
DBUS_TYPE_INVALID))
{
goto fail;
}
on_jack_ports_disconnected(
client1_id,
port1_id,
client2_id,
port2_id);
return;
}
return;
fail:
lash_error("Cannot get message arguments: %s", g_dbus_error.message);
dbus_error_free(&g_dbus_error);
}
static
void
on_jack_control_signal(
DBusMessage * message_ptr,
const char * signal_name)
{
if (strcmp(signal_name, "ServerStarted") == 0)
{
lash_debug("JACK server start detected.");
on_jack_server_started();
return;
}
if (strcmp(signal_name, "ServerStopped") == 0)
{
lash_debug("JACK server stop detected.");
on_jack_server_stopped();
return;
}
}
static
DBusHandlerResult
on_bus_signal(
DBusMessage * message_ptr,
const char * signal_name)
{
const char * object_name;
const char * old_owner;
const char * new_owner;
//lash_info("bus signal '%s' received", signal_name);
dbus_error_init(&g_dbus_error);
if (strcmp(signal_name, "NameOwnerChanged") == 0)
{
//lash_info("NameOwnerChanged signal received");
if (!dbus_message_get_args(
message_ptr,
&g_dbus_error,
DBUS_TYPE_STRING, &object_name,
DBUS_TYPE_STRING, &old_owner,
DBUS_TYPE_STRING, &new_owner,
DBUS_TYPE_INVALID)) {
lash_error("Cannot get message arguments: %s", g_dbus_error.message);
dbus_error_free(&g_dbus_error);
return DBUS_HANDLER_RESULT_HANDLED;
}
if (strcmp(object_name, JACKDBUS_SERVICE) != 0)
{
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
if (old_owner[0] == '\0')
{
lash_debug("JACK serivce appeared");
on_jack_server_appeared();
}
else if (new_owner[0] == '\0')
{
lash_debug("JACK serivce disappeared");
on_jack_server_disappeared();
}
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
2009-07-23 01:37:53 +03:00
static
DBusHandlerResult
dbus_signal_handler(
DBusConnection * connection_ptr,
DBusMessage * message_ptr,
void * data)
{
const char * object_path;
const char * interface;
const char * signal_name;
/* Non-signal messages are ignored */
if (dbus_message_get_type(message_ptr) != DBUS_MESSAGE_TYPE_SIGNAL)
{
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
interface = dbus_message_get_interface(message_ptr);
if (interface == NULL)
{
/* Signals with no interface are ignored */
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
object_path = dbus_message_get_path(message_ptr);
signal_name = dbus_message_get_member(message_ptr);
if (signal_name == NULL)
{
lash_error("Received signal with NULL member");
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
2009-07-24 01:39:06 +03:00
lash_debug("'%s' sent signal '%s'::'%s'", object_path, interface, signal_name);
2009-07-23 01:37:53 +03:00
/* Handle JACK patchbay and control interface signals */
if (object_path != NULL && strcmp(object_path, JACKDBUS_OBJECT) == 0)
{
if (strcmp(interface, JACKDBUS_IFACE_PATCHBAY) == 0)
{
2009-07-24 01:39:06 +03:00
on_jack_patchbay_signal(message_ptr, signal_name);
2009-07-23 01:37:53 +03:00
return DBUS_HANDLER_RESULT_HANDLED;
}
if (strcmp(interface, JACKDBUS_IFACE_CONTROL) == 0)
{
2009-07-24 01:39:06 +03:00
on_jack_control_signal(message_ptr, signal_name);
2009-07-23 01:37:53 +03:00
return DBUS_HANDLER_RESULT_HANDLED;
}
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
/* Handle session bus signals to track JACK service alive state */
if (strcmp(interface, DBUS_INTERFACE_DBUS) == 0)
{
2009-07-24 01:39:06 +03:00
return on_bus_signal(message_ptr, signal_name);
2009-07-23 01:37:53 +03:00
}
/* Let everything else pass through */
return DBUS_HANDLER_RESULT_NOT_YET_HANDLED;
}
2009-07-23 00:23:18 +03:00
bool
jack_proxy_init(
2009-07-23 00:23:18 +03:00
void)
{
2009-07-23 01:37:53 +03:00
DBusError err;
char rule[1024];
const char ** signal;
const char * patchbay_signals[] = {
"ClientAppeared",
"ClientDisappeared",
"PortAppeared",
"PortsConnected",
"PortsDisconnected",
NULL};
const char * control_signals[] = {
"ServerStarted",
"ServerStopped",
NULL};
dbus_bus_add_match(
g_dbus_connection,
"type='signal',interface='"DBUS_INTERFACE_DBUS"',member=NameOwnerChanged,arg0='"JACKDBUS_SERVICE"'",
&err);
if (dbus_error_is_set(&err))
{
lash_error("Failed to add D-Bus match rule: %s", err.message);
dbus_error_free(&err);
return false;
}
for (signal = patchbay_signals; *signal != NULL; signal++)
{
snprintf(
rule,
sizeof(rule),
"type='signal',sender='"JACKDBUS_SERVICE"',path='"JACKDBUS_OBJECT"',interface='"JACKDBUS_IFACE_PATCHBAY"',member='%s'",
*signal);
dbus_bus_add_match(g_dbus_connection, rule, &err);
if (dbus_error_is_set(&err))
{
lash_error("Failed to add D-Bus match rule: %s", err.message);
dbus_error_free(&err);
return false;
}
}
for (signal = control_signals; *signal != NULL; signal++)
{
snprintf(
rule,
sizeof(rule),
"type='signal',sender='"JACKDBUS_SERVICE"',path='"JACKDBUS_OBJECT"',interface='"JACKDBUS_IFACE_CONTROL"',member='%s'",
*signal);
dbus_bus_add_match(g_dbus_connection, rule, &err);
if (dbus_error_is_set(&err))
{
lash_error("Failed to add D-Bus match rule: %s", err.message);
dbus_error_free(&err);
return false;
}
}
if (!dbus_connection_add_filter(g_dbus_connection, dbus_signal_handler, NULL, NULL))
{
lash_error("Failed to add D-Bus filter");
return false;
}
return true;
2009-07-23 00:23:18 +03:00
}
void
jack_proxy_uninit(
2009-07-23 00:23:18 +03:00
void)
{
2009-07-23 01:37:53 +03:00
dbus_connection_remove_filter(g_dbus_connection, dbus_signal_handler, NULL);
2009-07-23 00:23:18 +03:00
}
bool
jack_proxy_is_started(
2009-07-23 00:23:18 +03:00
bool * started_ptr)
{
return false;
}
bool
jack_proxy_get_client_pid(
2009-07-23 00:23:18 +03:00
uint64_t client_id,
pid_t * pid_ptr)
{
return false;
}
bool
jack_proxy_connect_ports(
2009-07-23 00:23:18 +03:00
uint64_t port1_id,
uint64_t port2_id)
{
return false;
}