diff --git a/configure.in b/configure.in index 13eb48c..b63197e 100644 --- a/configure.in +++ b/configure.in @@ -15,7 +15,7 @@ dnl changes are made dnl --- JACK_MAJOR_VERSION=0 JACK_MINOR_VERSION=99 -JACK_MICRO_VERSION=3 +JACK_MICRO_VERSION=4 dnl --- dnl HOWTO: updating the jack protocol version diff --git a/doc/mainpage.dox b/doc/mainpage.dox index 1811fe9..efc2c59 100644 --- a/doc/mainpage.dox +++ b/doc/mainpage.dox @@ -63,7 +63,7 @@ programs are not all running synchronously. Using JACK within your program is very simple, and typically consists of just: - - calling @ref jack_client_new to connect to the JACK server. + - calling @ref jack_client_open to connect to the JACK server. - registering "ports" to enable data to be moved to and from your application. - registering a "process callback" which will be called at the diff --git a/jack/jack.h b/jack/jack.h index 3704378..e74e0df 100644 --- a/jack/jack.h +++ b/jack/jack.h @@ -34,6 +34,44 @@ extern "C" { * Note: More documentation can be found in jack/types.h. */ +/** + * Open an external client session with a JACK server. This interface + * is more complex but more powerful than jack_client_new(). With it, + * clients may choose which of several servers to connect, and control + * whether and how to start the server automatically, if it was not + * already running. There is also an option for JACK to generate a + * unique client name, when necessary. + * + * @param client_name of at most jack_client_name_size() characters. + * The name scope is local to each server. Unless forbidden by the + * @ref JackUseExactName option, the server will modify this name to + * create a unique variant, if needed. + * + * @param options formed by AND-ing together @ref JackOpenOptions + * bits. + * + * @param status (if non-NULL) an address for JACK to return + * information from the open operation. This status word is formed by + * AND-ing together the relevant @ref JackOpenStatus bits. + * + * @param server_name (if non-NULL) selects from among several + * possible concurrent server instances. If unspecified, "default" is + * assumed. Server names are unique to each user. + * + * @param start_command (if non-NULL) is a command line to use if the + * server was not running and must be started. Defining + * $JACK_NO_START_SERVER in the environment disables automatic server + * creation. + * + * @return Opaque client handle if successful. If this is NULL, the + * open operation failed, and the caller is not a JACK client. + */ +jack_client_t *jack_client_open (const char *client_name, + jack_options_t options, + jack_status_t *status, + const char *server_name, + const char *start_command); + /** * Attempt to become an external client of the Jack server. * @@ -50,7 +88,8 @@ extern "C" { * * @note Failure generally means that the JACK server is not running. * If there was some other problem, it will be reported via the @ref - * jack_error_callback mechanism. + * jack_error_callback mechanism. Use jack_client_open() and check + * the @a status parameter if you need more detailed information. */ jack_client_t *jack_client_new (const char *client_name); @@ -65,7 +104,15 @@ int jack_client_close (jack_client_t *client); * @return the maximum number of characters in a JACK client name * including the final NULL character. This value is a constant. */ -int jack_client_name_size(void); +int jack_client_name_size (void); + +/** + * @return pointer to actual client name. This is useful when @ref + * JackUseExactName is not specified on open and @ref + * JackNameNotUnique status was returned. In that case, the actual + * name will differ from the @a client_name requested. + */ +char *jack_get_client_name (jack_client_t* client); /** * Attempt to load an internal client into the Jack server. @@ -119,7 +166,8 @@ int jack_is_realtime (jack_client_t *client); * to help more complex clients understand what is going * on. It should be called before jack_client_activate(). */ -void jack_on_shutdown (jack_client_t *client, void (*function)(void *arg), void *arg); +void jack_on_shutdown (jack_client_t *client, + void (*function)(void *arg), void *arg); /** * Tell the Jack server to call @a process_callback whenever there is @@ -232,8 +280,8 @@ int jack_set_sample_rate_callback (jack_client_t *client, void *arg); /** - * Tell the Jack server to call 'registration_callback' whenever a port is registered - * or unregistered, passing 'arg' as a second argument. + * Tell the JACK server to call @a registration_callback whenever a + * port is registered or unregistered, passing @a arg as a parameter. * * @return 0 on success, otherwise a non-zero error code */ @@ -242,20 +290,23 @@ int jack_set_port_registration_callback (jack_client_t *, registration_callback, void *arg); /** - * Tell the Jack server to call 'registration_callback' whenever the processing - * graph is reordered, passing 'arg' as an argument. + * Tell the JACK server to call @a graph_callback whenever the + * processing graph is reordered, passing @a arg as a parameter. * * @return 0 on success, otherwise a non-zero error code */ -int jack_set_graph_order_callback (jack_client_t *, JackGraphOrderCallback graph_callback, void *); +int jack_set_graph_order_callback (jack_client_t *, + JackGraphOrderCallback graph_callback, + void *); /** - * Tell the Jack server to call 'xrun_callback' whenever there is a xrun, passing - * 'arg' as an argument. + * Tell the JACK server to call @a xrun_callback whenever there is a + * xrun, passing @a arg as a parameter. * * @return 0 on success, otherwise a non-zero error code */ -int jack_set_xrun_callback (jack_client_t *, JackXRunCallback xrun_callback, void *arg); +int jack_set_xrun_callback (jack_client_t *, + JackXRunCallback xrun_callback, void *arg); /** * Tell the Jack server that the program is ready to start processing diff --git a/jack/types.h b/jack/types.h index 36e3fb3..255ee26 100644 --- a/jack/types.h +++ b/jack/types.h @@ -224,4 +224,61 @@ enum JackPortFlags { JackPortIsTerminal = 0x10 }; +/** + * jack_client_open() option bits + */ +enum JackOpenOptions { + + /** + * Do not automatically start the JACK server if it is not + * already running. This option is selected by default if + * $JACK_NO_START_SERVER is defined in the calling process + * environment. + */ + JackNoStartServer = 0x01, + + /** + * Use the exact client name requested. Otherwise, JACK + * automatically generates a unique one, if needed. + */ + JackUseExactName = 0x02 +}; + +/** + * jack_client_open() request options are formed by AND-ing together + * @ref JackOpenOptions bits. + */ +typedef enum JackOpenOptions jack_options_t; + +/** + * jack_client_open() status bits + */ +enum JackOpenStatus { + + /** + * The JACK server was started as a result of this open. + * Otherwise, it was running already. In either case the caller + * is now connected to jackd, so there is no race condition. + * When the server shuts down, the client will find out. + */ + JackServerStarted = 0x01, + + /** + * The desired client name was not unique. With the @ref + * JackUseExactName option this situation is fatal. Otherwise, + * the name was modified by appending a dash and a two-digit + * number in the range "-01" to "-99". The + * jack_get_client_name() function will return the exact string + * that was used. If the specified @a client_name plus these + * extra characters would be too long, the open fails instead. + */ + JackNameNotUnique = 0x02 +}; + +/** + * The status word returned from jack_client_open() is formed by + * AND-ing together the relevant @ref JackOpenStatus bits. + */ +typedef enum JackOpenStatus jack_status_t; + #endif /* __jack_types_h__ */ diff --git a/jackd/engine.c b/jackd/engine.c index 7e25533..47ae7ec 100644 --- a/jackd/engine.c +++ b/jackd/engine.c @@ -1099,12 +1099,12 @@ setup_client (jack_engine_t *engine, int client_fd, /* its good to go */ break; - default: + default: /* external client */ if (engine->pfd_max >= engine->pfd_size) { engine->pfd = (struct pollfd *) realloc (engine->pfd, sizeof (struct pollfd) - * engine->pfd_size + 16); + * (engine->pfd_size + 16)); engine->pfd_size += 16; } @@ -2812,9 +2812,11 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, our check on a client's continued well-being */ - if (client->control->dead || - (client->control->type == ClientExternal && kill (client->control->pid, 0))) { - DEBUG ("client %s is dead - no event sent", client->control->name); + if (client->control->dead + || (client->control->type == ClientExternal + && kill (client->control->pid, 0))) { + DEBUG ("client %s is dead - no event sent", + client->control->name); return 0; } @@ -3012,8 +3014,9 @@ jack_rechain_graph (jack_engine_t *engine) subgraph_client-> subgraph_start_fd, n); - /* this external client after this will have - jackd as its upstream connection. + /* this external client after + this will have jackd as its + upstream connection. */ upstream_is_jackd = 1; @@ -3029,8 +3032,10 @@ jack_rechain_graph (jack_engine_t *engine) control->name, n); subgraph_client->subgraph_wait_fd = -1; - /* this external client after this will have - another client as its upstream connection. + /* this external client after + this will have another + client as its upstream + connection. */ upstream_is_jackd = 0; @@ -3718,7 +3723,7 @@ jack_get_fifo_fd (jack_engine_t *engine, unsigned int which_fifo) engine->fifo = (int *) realloc (engine->fifo, - sizeof (int) * engine->fifo_size + 16); + sizeof (int) * (engine->fifo_size + 16)); for (i = engine->fifo_size; i < engine->fifo_size + 16; i++) { engine->fifo[i] = -1; } diff --git a/jackd/jackd.c b/jackd/jackd.c index 1d16c8e..278e021 100644 --- a/jackd/jackd.c +++ b/jackd/jackd.c @@ -381,7 +381,7 @@ main (int argc, char *argv[]) { jack_driver_desc_t * desc; - const char *options = "-ad:P:vshVRTFl:t:mp:"; + const char *options = "-ad:P:uvshVRTFl:t:mp:"; struct option long_options[] = { { "driver", 1, 0, 'd' }, @@ -389,7 +389,7 @@ main (int argc, char *argv[]) { "help", 0, 0, 'h' }, { "port-max", 1, 0, 'p' }, { "no-mlock", 0, 0, 'm' }, - { "unmlock", 0, 0, 'u' }, + { "unlock", 0, 0, 'u' }, { "realtime", 0, 0, 'R' }, { "realtime-priority", 1, 0, 'P' }, { "timeout", 1, 0, 't' },