diff --git a/configure.ac b/configure.ac index b4d99dc..714094b 100644 --- a/configure.ac +++ b/configure.ac @@ -15,7 +15,7 @@ dnl changes are made dnl --- JACK_MAJOR_VERSION=0 JACK_MINOR_VERSION=99 -JACK_MICRO_VERSION=9 +JACK_MICRO_VERSION=10 dnl --- dnl HOWTO: updating the jack protocol version diff --git a/example-clients/simple_client.c b/example-clients/simple_client.c index b0304b5..3ed5199 100644 --- a/example-clients/simple_client.c +++ b/example-clients/simple_client.c @@ -70,10 +70,16 @@ main (int argc, char *argv[]) { const char **ports; const char *client_name; + const char *server_name = NULL; + jack_options_t options = JackNullOption; jack_status_t status; - if (argc >= 2) { /* session name specified? */ + if (argc >= 2) { /* client name specified? */ client_name = argv[1]; + if (argc >= 3) { /* server name specified? */ + server_name = argv[2]; + options |= JackServerName; + } } else { /* use basename of argv[0] */ client_name = strrchr(argv[0], '/'); if (client_name == 0) { @@ -85,10 +91,13 @@ main (int argc, char *argv[]) /* open a client connection to the JACK server */ - client = jack_client_open (client_name, 0, &status, NULL, NULL); + client = jack_client_open (client_name, options, &status, server_name); if (client == NULL) { fprintf (stderr, "jack_client_open() failed, status = %d\n", status); + if (status & JackServerFailed) { + fprintf (stderr, "Unable to connect to JACK server\n"); + } exit (1); } if (status & JackServerStarted) { diff --git a/example-clients/transport.c b/example-clients/transport.c index 20c07cd..f6541f8 100644 --- a/example-clients/transport.c +++ b/example-clients/transport.c @@ -422,6 +422,8 @@ void command_loop() int main(int argc, char *argv[]) { + jack_status_t status; + /* basename $0 */ package = strrchr(argv[0], '/'); if (package == 0) @@ -429,9 +431,11 @@ int main(int argc, char *argv[]) else package++; - /* become a new client of the JACK server */ - if ((client = jack_client_new(package)) == 0) { - fprintf(stderr, "jack server not running?\n"); + /* open a connection to the JACK server */ + client = jack_client_open (package, JackNullOption, &status); + if (client == NULL) { + fprintf (stderr, "jack_client_open() failed, status = %d\n", + status); return 1; } diff --git a/jack/jack.h b/jack/jack.h index bd9f370..4721c9f 100644 --- a/jack/jack.h +++ b/jack/jack.h @@ -47,49 +47,47 @@ extern "C" { * @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 options formed by OR-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. + * OR-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. + * Optional parameters: * - * @param server_command (if non-NULL) is a command line to start the - * server if it was not running. The @ref JackNoStartServer option - * disables automatic server creation, as does defining - * $JACK_NO_START_SERVER in the environment. + * @arg @a server_name (char *) selects from among several + * possible concurrent server instances. This parameter must follow + * @a status if the @ref JackServerName option is specified. + * Otherwise, "default" is assumed. Server names are unique to each + * user. * * @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 *server_command); + jack_status_t *status, ...); /** * Attempt to become an external client of the Jack server. * * JACK is evolving a mechanism for automatically starting the server * when needed. As a transition, jack_client_new() only does this - * when $JACK_START_SERVER is defined in the environment of the + * when \$JACK_START_SERVER is defined in the environment of the * calling process. In the future this will become normal behavior. - * In either case, defining $JACK_NO_START_SERVER disables this + * For full control of this feature, use jack_client_open(), instead. + * In either case, defining \$JACK_NO_START_SERVER disables this * feature. * * @param client_name of at most jack_client_name_size() characters. + * If this name is already in use, the request fails. * * @return Opaque client handle if successful, otherwise NULL. * * @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. Use jack_client_open() and check - * the @a status parameter if you need more detailed information. + * the @a status parameter for more detailed information. */ jack_client_t *jack_client_new (const char *client_name); diff --git a/jack/types.h b/jack/types.h index c944e71..ad7020b 100644 --- a/jack/types.h +++ b/jack/types.h @@ -232,9 +232,14 @@ enum JackPortFlags { 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 + * Null value to use when no option bits are needed. + */ + JackNullOption = 0x00, + + /** + * Do not automatically start the JACK server when it is not + * already running. This option is always selected if + * \$JACK_NO_START_SERVER is defined in the calling process * environment. */ JackNoStartServer = 0x01, @@ -243,9 +248,17 @@ enum JackOpenOptions { * Use the exact client name requested. Otherwise, JACK * automatically generates a unique one, if needed. */ - JackUseExactName = 0x02 + JackUseExactName = 0x02, + + /** + * Open with optional @a char @a *server_name parameter. + * + * @warning This option has not yet been implemented. + */ + JackServerName = 0x04 }; +/* options mask does not include unimplemented features */ #define JackValidOptions (JackNoStartServer|JackUseExactName) /** @@ -260,12 +273,10 @@ typedef enum JackOpenOptions jack_options_t; 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. + * The open request failed because it contained an invalid or + * unsupported option. */ - JackServerStarted = 0x01, + JackInvalidOption = 0x01, /** * The desired client name was not unique. With the @ref @@ -279,10 +290,17 @@ enum JackOpenStatus { JackNameNotUnique = 0x02, /** - * The open request contained an invalid or unsupported option or - * parameter. + * 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 = 0x04, + + /** + * Unable to connect to the JACK server, open failed. */ - JackInvalidOpen = 0x04 + JackServerFailed = 0x08 }; /** diff --git a/libjack/client.c b/libjack/client.c index 87f2a39..53f5f83 100644 --- a/libjack/client.c +++ b/libjack/client.c @@ -343,6 +343,9 @@ server_connect (const char *server_name) return -1; } + //JOQ: temporary debug code + // fprintf (stderr, "connecting to %s server\n", server_name); + //JOQ: use server_name as part of socket path addr.sun_family = AF_UNIX; snprintf (addr.sun_path, sizeof (addr.sun_path) - 1, "%s/jack_%d_%d", @@ -409,7 +412,7 @@ server_event_connect (jack_client_t *client) /* Exec the JACK server in this process. Does not return. */ static void -_start_server (const char *server_command) +_start_server (const char *server_cmd) { FILE* fp = 0; char filename[255]; @@ -498,7 +501,7 @@ _start_server (const char *server_command) } int -start_server (jack_options_t options, const char *server_command) +start_server (jack_options_t options, const char *server_cmd) { if ((options & JackNoStartServer) || (getenv("JACK_NO_START_SERVER") != NULL)) { @@ -518,7 +521,7 @@ start_server (jack_options_t options, const char *server_command) case 0: /* child process */ switch (fork()) { case 0: /* grandchild process */ - _start_server(server_command); + _start_server(server_cmd); _exit (99); /* exec failed */ case -1: _exit (98); @@ -538,7 +541,7 @@ jack_request_client (ClientType type, const char* client_name, const char* so_name, const char* so_data, jack_client_connect_result_t *res, int *req_fd, jack_options_t options, jack_status_t *status, - const char *server_name, const char *server_command) + const char *server_name, const char *server_cmd) { jack_client_connect_request_t req; @@ -574,13 +577,15 @@ jack_request_client (ClientType type, const char* client_name, if ((*req_fd = server_connect (server_name)) < 0) { int trys; - if (start_server(options, server_command)) { + if (start_server(options, server_cmd)) { + *status |= JackServerFailed; goto fail; } trys = 5; do { sleep(1); if (--trys < 0) { + *status |= JackServerFailed; goto fail; } } while ((*req_fd = server_connect (server_name)) < 0); @@ -727,10 +732,13 @@ jack_attach_port_segment (jack_client_t *client, jack_port_type_id_t ptid) jack_client_t * jack_client_open (const char *client_name, jack_options_t options, - jack_status_t *status, - const char *server_name, - const char *server_command) + jack_status_t *status, ...) { + /* optional arguments: */ + char *server_name = "default"; /* server name */ + char *server_cmd = NULL; /* server command (not implemented) */ + va_list ap; /* variable argument pointer */ + int req_fd = -1; int ev_fd = -1; jack_client_connect_result_t res; @@ -744,12 +752,19 @@ jack_client_open (const char *client_name, *status = 0; /* validate parameters */ - if ((options & (~JackValidOptions)) - || server_name || server_command) { - *status |= JackInvalidOpen; + if ((options & ~JackValidOptions)) { + *status |= JackInvalidOption; return NULL; } + /* parse optional arguments */ + va_start (ap, status); + if ((options & JackServerName)) + server_name = va_arg(ap, char *); + //if ((options & JackServerCmd)) /* not implemented */ + // server_cmd = va_arg(ap, char *); + va_end (ap); + /* External clients need this initialized. It is already set * up in the server's address space for internal clients. */ @@ -762,7 +777,7 @@ jack_client_open (const char *client_name, if (jack_request_client (ClientExternal, client_name, "", "", &res, &req_fd, options, status, - server_name, server_command)) { + server_name, server_cmd)) { return NULL; } @@ -868,7 +883,7 @@ jack_client_new (const char *client_name) if (getenv("JACK_START_SERVER") == NULL) options |= JackNoStartServer; - return jack_client_open (client_name, options, NULL, NULL, NULL); + return jack_client_open (client_name, options, NULL); } char *