diff --git a/include/internal.h b/include/internal.h index bf622c8..036d703 100644 --- a/include/internal.h +++ b/include/internal.h @@ -382,7 +382,8 @@ typedef enum { ReserveName = 30, SessionReply = 31, SessionHasCallback = 32, - PropertyChangeNotify = 33 + PropertyChangeNotify = 33, + PortNameChanged = 34 } RequestType; struct _jack_request { diff --git a/jackd/engine.c b/jackd/engine.c index 0fff48c..26df2bd 100644 --- a/jackd/engine.c +++ b/jackd/engine.c @@ -136,6 +136,7 @@ static void jack_compute_all_port_total_latencies (jack_engine_t *engine); static void jack_compute_port_total_latency (jack_engine_t *engine, jack_port_shared_t*); static int jack_check_client_status (jack_engine_t* engine); static int jack_do_session_notify (jack_engine_t *engine, jack_request_t *req, int reply_fd ); +static void jack_port_rename_notify (jack_engine_t *engine, const char* old_name, const char* new_name); static void jack_do_get_client_by_uuid (jack_engine_t *engine, jack_request_t *req); static void jack_do_get_uuid_by_client_name (jack_engine_t *engine, jack_request_t *req); static void jack_do_reserve_name (jack_engine_t *engine, jack_request_t *req); @@ -1371,6 +1372,12 @@ do_request (jack_engine_t *engine, jack_request_t *req, int *reply_fd) jack_property_change_notify (engine, req->x.property.change, req->x.property.uuid, req->x.property.key); break; + case PortNameChanged: + jack_rdlock_graph (engine); + jack_port_rename_notify (engine, req->x.connect.source_port, req->x.connect.destination_port); + jack_unlock_graph (engine); + break; + default: /* some requests are handled entirely on the client * side, by adjusting the shared memory area(s) */ @@ -4644,6 +4651,47 @@ jack_port_registration_notify (jack_engine_t *engine, } } +static void +jack_port_rename_notify (jack_engine_t *engine, + const char* old_name, + const char* new_name) +{ + jack_event_t event; + jack_client_internal_t *client; + JSList *node; + jack_port_internal_t* port; + + if ((port = jack_get_port_by_name (engine, new_name)) == NULL) { + /* possible race condition: port renamed again + since this rename happened. Oh well. + */ + return; + } + + event.type = PortRename; + event.y.other_id = port->shared->id; + snprintf (event.x.name, JACK_PORT_NAME_SIZE-1, old_name); + snprintf (event.z.other_name, JACK_PORT_NAME_SIZE-1, new_name); + + for (node = engine->clients; node; node = jack_slist_next (node)) { + + client = (jack_client_internal_t *) node->data; + + if (!client->control->active) { + continue; + } + + if (client->control->port_rename_cbset) { + if (jack_deliver_event (engine, client, &event)) { + jack_error ("cannot send port registration" + " notification to %s (%s)", + client->control->name, + strerror (errno)); + } + } + } +} + void jack_client_registration_notify (jack_engine_t *engine, const char* name, int yn) diff --git a/libjack/client.c b/libjack/client.c index 11f6a9a..3fa4f73 100644 --- a/libjack/client.c +++ b/libjack/client.c @@ -2751,6 +2751,21 @@ jack_set_buffer_size_callback (jack_client_t *client, return 0; } +int +jack_set_port_rename_callback (jack_client_t *client, + JackPortRenameCallback callback, + void *arg) +{ + if (client->control->active) { + jack_error ("You cannot set callbacks on an active client."); + return -1; + } + client->port_rename_arg = arg; + client->port_rename = callback; + client->control->port_rename_cbset = (callback != NULL); + return 0; +} + int jack_set_port_registration_callback(jack_client_t *client, JackPortRegistrationCallback callback, @@ -3090,6 +3105,8 @@ jack_event_type_name (JackEventType type) return "latency callback"; case PropertyChange: return "property change callback"; + case PortRename: + return "port rename"; default: break; } diff --git a/libjack/local.h b/libjack/local.h index 46d787d..7b63ce6 100644 --- a/libjack/local.h +++ b/libjack/local.h @@ -55,6 +55,8 @@ struct _jack_client { void *bufsize_arg; JackSampleRateCallback srate; void *srate_arg; + JackPortRenameCallback port_rename; + void *port_rename_arg; JackPortRegistrationCallback port_register; void *port_register_arg; JackPortConnectCallback port_connect; diff --git a/libjack/port.c b/libjack/port.c index 481f6e0..16a11b9 100644 --- a/libjack/port.c +++ b/libjack/port.c @@ -799,17 +799,46 @@ jack_port_type (const jack_port_t *port) return port->type_info->type_name; } +int +jack_port_rename (jack_client_t* client, jack_port_t *port, const char *new_name) +{ + int ret; + char* old_name = strdup (port->shared->name); + + if ((ret = jack_port_set_name (port, new_name)) == 0) { + + /* tell server about name change */ + jack_request_t req; + + req.type = PortNameChanged; + + /* re-purpose an appropriate part of the request union to convey the names */ + snprintf ((char *) req.x.connect.source_port, JACK_PORT_NAME_SIZE-1, old_name); + snprintf ((char *) req.x.connect.destination_port, JACK_PORT_NAME_SIZE-1, new_name); + + (void) jack_client_deliver_request (client, &req); + } + + free (old_name); + + return ret; +} int jack_port_set_name (jack_port_t *port, const char *new_name) { char *colon; int len; + if (strcmp (new_name, port->shared->name) == 0) { + return 0; + } + colon = strchr (port->shared->name, ':'); len = sizeof (port->shared->name) - ((int) (colon - port->shared->name)) - 2; snprintf (colon+1, len, "%s", new_name); - + + return 0; }