git-svn-id: svn+ssh://jackaudio.org/trunk/jack@1047 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.109.0
@@ -17,7 +17,7 @@ dnl changes are made | |||
dnl --- | |||
JACK_MAJOR_VERSION=0 | |||
JACK_MINOR_VERSION=107 | |||
JACK_MICRO_VERSION=0 | |||
JACK_MICRO_VERSION=1 | |||
dnl --- | |||
dnl HOWTO: updating the jack protocol version | |||
@@ -30,6 +30,12 @@ port_callback (jack_port_id_t port, int yn, void* arg) | |||
printf ("Port %d %s\n", port, (yn ? "registered" : "unregistered")); | |||
} | |||
void | |||
connect_callback (jack_port_id_t a, jack_port_id_t b, int yn, void* arg) | |||
{ | |||
printf ("Ports %d and %d %s\n", a, b, (yn ? "connected" : "disconnected")); | |||
} | |||
void | |||
client_callback (const char* client, int yn, void* arg) | |||
{ | |||
@@ -63,6 +69,10 @@ main (int argc, char *argv[]) | |||
fprintf (stderr, "cannot set port registration callback\n"); | |||
return 1; | |||
} | |||
if (jack_set_port_connect_callback (client, connect_callback, NULL)) { | |||
fprintf (stderr, "cannot set port connect callback\n"); | |||
return 1; | |||
} | |||
if (jack_set_client_registration_callback (client, client_callback, NULL)) { | |||
fprintf (stderr, "cannot set client registration callback\n"); | |||
return 1; | |||
@@ -71,7 +81,6 @@ main (int argc, char *argv[]) | |||
fprintf (stderr, "cannot set graph order registration callback\n"); | |||
return 1; | |||
} | |||
if (jack_activate (client)) { | |||
fprintf (stderr, "cannot activate client"); | |||
return 1; | |||
@@ -311,7 +311,7 @@ int jack_set_port_registration_callback (jack_client_t *, | |||
/** | |||
* Tell the JACK server to call @a connect_callback whenever a | |||
* port is registered or unregistered, passing @a arg as a parameter. | |||
* port is connected or disconnected, passing @a arg as a parameter. | |||
* | |||
* @return 0 on success, otherwise a non-zero error code | |||
*/ | |||
@@ -182,7 +182,7 @@ typedef void (*JackClientRegistrationCallback)(const char* name, int register, v | |||
* zero if ports were disconnected | |||
* @param arg pointer to a client supplied data | |||
*/ | |||
typedef void (*JackPortConnectCallback)(jack_port_t* a, jack_port_t* b, int connect, void* arg); | |||
typedef void (*JackPortConnectCallback)(jack_port_id_t a, jack_port_id_t b, int connect, void* arg); | |||
/** | |||
* Prototype for the client supplied function that is called | |||
@@ -108,6 +108,10 @@ static int jack_deliver_event (jack_engine_t *, jack_client_internal_t *, | |||
jack_event_t *); | |||
static void jack_deliver_event_to_all (jack_engine_t *engine, | |||
jack_event_t *event); | |||
static void jack_notify_all_port_interested_clients (jack_engine_t *engine, | |||
jack_port_id_t a, | |||
jack_port_id_t b, | |||
int connect); | |||
static void jack_engine_post_process (jack_engine_t *); | |||
static int jack_use_driver (jack_engine_t *engine, jack_driver_t *driver); | |||
static int jack_run_cycle (jack_engine_t *engine, jack_nframes_t nframes, | |||
@@ -2276,6 +2280,34 @@ jack_deliver_event_to_all (jack_engine_t *engine, jack_event_t *event) | |||
jack_unlock_graph (engine); | |||
} | |||
static void | |||
jack_notify_all_port_interested_clients (jack_engine_t *engine, jack_port_id_t a, jack_port_id_t b, int connected) | |||
{ | |||
JSList *node; | |||
jack_event_t event; | |||
event.type = (connected ? PortConnected : PortDisconnected); | |||
event.x.self_id = a; | |||
event.y.other_id = b; | |||
/* GRAPH MUST BE LOCKED : see callers of jack_send_connection_notification() | |||
*/ | |||
for (node = engine->clients; node; node = jack_slist_next (node)) { | |||
jack_client_internal_t* client; | |||
client = (jack_client_internal_t*) node->data; | |||
if (client->control->port_connect != NULL) { | |||
/* one of the ports belong to this client or it has a port connect callback */ | |||
jack_deliver_event (engine, client, &event); | |||
} | |||
} | |||
} | |||
static int | |||
jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, | |||
jack_event_t *event) | |||
@@ -3128,10 +3160,16 @@ jack_port_do_connect (jack_engine_t *engine, | |||
jack_send_connection_notification (engine, | |||
srcport->shared->client_id, | |||
src_id, dst_id, TRUE); | |||
jack_send_connection_notification (engine, | |||
dstport->shared->client_id, | |||
dst_id, src_id, TRUE); | |||
/* send a port connection notification just once to everyone who cares */ | |||
jack_notify_all_port_interested_clients (engine, src_id, dst_id, 1); | |||
jack_sort_graph (engine); | |||
} | |||
@@ -3193,6 +3231,10 @@ jack_port_disconnect_internal (jack_engine_t *engine, | |||
engine, dstport->shared->client_id, dst_id, | |||
src_id, FALSE); | |||
/* send a port connection notification just once to everyone who cares */ | |||
jack_notify_all_port_interested_clients (engine, src_id, dst_id, 0); | |||
if (connect->dir) { | |||
jack_client_internal_t *src; | |||
@@ -3812,8 +3854,8 @@ jack_send_connection_notification (jack_engine_t *engine, | |||
{ | |||
jack_client_internal_t *client; | |||
jack_event_t event; | |||
jack_event_t event; | |||
if ((client = jack_client_internal_by_id (engine, client_id)) == NULL) { | |||
jack_error ("no such client %" PRIu32 | |||
" during connection notification", client_id); | |||
@@ -426,62 +426,64 @@ jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event) | |||
JSList *node; | |||
int need_free = FALSE; | |||
switch (event->type) { | |||
case PortConnected: | |||
other = jack_port_new (client, event->y.other_id, | |||
client->engine); | |||
/* jack_port_by_id_int() always returns an internal | |||
* port that does not need to be deallocated */ | |||
control_port = jack_port_by_id_int (client, event->x.self_id, | |||
&need_free); | |||
pthread_mutex_lock (&control_port->connection_lock); | |||
control_port->connections = | |||
jack_slist_prepend (control_port->connections, | |||
(void *) other); | |||
pthread_mutex_unlock (&control_port->connection_lock); | |||
if (client->control->port_connect) { | |||
client->control->port_connect (control_port, other, 1, client->control->port_connect_arg); | |||
} | |||
break; | |||
if (client->engine->ports[event->x.self_id].client_id == client->control->id || | |||
client->engine->ports[event->y.other_id].client_id == client->control->id) { | |||
case PortDisconnected: | |||
/* jack_port_by_id_int() always returns an internal | |||
* port that does not need to be deallocated */ | |||
control_port = jack_port_by_id_int (client, event->x.self_id, | |||
&need_free); | |||
pthread_mutex_lock (&control_port->connection_lock); | |||
/* its one of ours */ | |||
for (node = control_port->connections; node; | |||
node = jack_slist_next (node)) { | |||
other = (jack_port_t *) node->data; | |||
if (other->shared->id == event->y.other_id) { | |||
control_port->connections = | |||
jack_slist_remove_link ( | |||
control_port->connections, | |||
node); | |||
break; | |||
} | |||
} | |||
pthread_mutex_unlock (&control_port->connection_lock); | |||
if (node) { | |||
if (client->control->port_connect) { | |||
client->control->port_connect (control_port, other, 0, client->control->port_connect_arg); | |||
switch (event->type) { | |||
case PortConnected: | |||
other = jack_port_new (client, event->y.other_id, | |||
client->engine); | |||
/* jack_port_by_id_int() always returns an internal | |||
* port that does not need to be deallocated | |||
*/ | |||
control_port = jack_port_by_id_int (client, event->x.self_id, | |||
&need_free); | |||
pthread_mutex_lock (&control_port->connection_lock); | |||
control_port->connections = | |||
jack_slist_prepend (control_port->connections, | |||
(void *) other); | |||
pthread_mutex_unlock (&control_port->connection_lock); | |||
break; | |||
case PortDisconnected: | |||
/* jack_port_by_id_int() always returns an internal | |||
* port that does not need to be deallocated | |||
*/ | |||
control_port = jack_port_by_id_int (client, event->x.self_id, | |||
&need_free); | |||
pthread_mutex_lock (&control_port->connection_lock); | |||
for (node = control_port->connections; node; | |||
node = jack_slist_next (node)) { | |||
other = (jack_port_t *) node->data; | |||
if (other->shared->id == event->y.other_id) { | |||
control_port->connections = | |||
jack_slist_remove_link ( | |||
control_port->connections, | |||
node); | |||
jack_slist_free_1 (node); | |||
free (other); | |||
break; | |||
} | |||
} | |||
jack_slist_free_1 (node); | |||
free (other); | |||
pthread_mutex_unlock (&control_port->connection_lock); | |||
break; | |||
default: | |||
/* impossible */ | |||
break; | |||
} | |||
} | |||
break; | |||
default: | |||
/* impossible */ | |||
break; | |||
if (client->control->port_connect) { | |||
client->control->port_connect (event->x.self_id, event->y.other_id, | |||
(event->type == PortConnected ? 1 : 0), | |||
client->control->port_connect_arg); | |||
} | |||
return 0; | |||