git-svn-id: svn+ssh://jackaudio.org/trunk/jack@3000 0c269be4-1314-0410-8aa9-9f06e86f4224tags/0.115.6
| @@ -532,12 +532,13 @@ alsa_driver_configure_stream (alsa_driver_t *driver, char *device_name, | |||
| return -1; | |||
| } | |||
| jack_info ("ALSA: use %d periods for %s", *nperiodsp, stream_name); | |||
| #if 0 | |||
| if (!jack_power_of_two(driver->frames_per_cycle)) { | |||
| jack_error("JACK: frames must be a power of two " | |||
| "(64, 512, 1024, ...)\n"); | |||
| return -1; | |||
| } | |||
| #endif | |||
| if ((err = snd_pcm_hw_params_set_buffer_size (handle, hw_params, | |||
| *nperiodsp * | |||
| @@ -34,6 +34,21 @@ | |||
| #include <sys/types.h> | |||
| #include <sys/time.h> | |||
| #ifndef POST_PACKED_STRUCTURE | |||
| #ifdef __GNUC__ | |||
| /* POST_PACKED_STRUCTURE needs to be a macro which | |||
| expands into a compiler directive. The directive must | |||
| tell the compiler to arrange the preceding structure | |||
| declaration so that it is packed on byte-boundaries rather | |||
| than use the natural alignment of the processor and/or | |||
| compiler. | |||
| */ | |||
| #define POST_PACKED_STRUCTURE __attribute__((__packed__)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif | |||
| #endif | |||
| /* Needed by <sysdeps/time.h> */ | |||
| extern void jack_error (const char *fmt, ...); | |||
| @@ -136,7 +151,7 @@ typedef struct { | |||
| int32_t reset_pending; /* xrun happened, deal with it */ | |||
| float filter_coefficient; /* set once, never altered */ | |||
| } jack_frame_timer_t; | |||
| } POST_PACKED_STRUCTURE jack_frame_timer_t; | |||
| /* JACK engine shared memory data structure. */ | |||
| typedef struct { | |||
| @@ -175,7 +190,7 @@ typedef struct { | |||
| jack_port_type_info_t port_types[JACK_MAX_PORT_TYPES]; | |||
| jack_port_shared_t ports[0]; | |||
| } jack_control_t; | |||
| } POST_PACKED_STRUCTURE jack_control_t; | |||
| typedef enum { | |||
| BufferSizeChange, | |||
| @@ -206,7 +221,7 @@ typedef struct { | |||
| jack_port_type_id_t ptid; | |||
| jack_port_id_t other_id; | |||
| } y; | |||
| } jack_event_t; | |||
| } POST_PACKED_STRUCTURE jack_event_t; | |||
| typedef enum { | |||
| ClientInternal, /* connect request just names .so */ | |||
| @@ -245,48 +260,28 @@ typedef volatile struct { | |||
| volatile uint64_t finished_at; | |||
| volatile int32_t last_status; /* w: client, r: engine and client */ | |||
| /* JOQ: all these pointers are trouble for 32/64 compatibility, | |||
| * they should move to non-shared memory. | |||
| /* indicators for whether callbacks have been set for this client. | |||
| We do not include ptrs to the callbacks here (or their arguments) | |||
| so that we can avoid 32/64 bit pointer size mismatches between | |||
| the jack server and a client. The pointers are in the client- | |||
| local structure which is part of the libjack compiled for | |||
| either 32 bit or 64 bit clients. | |||
| */ | |||
| /* callbacks | |||
| */ | |||
| JackProcessCallback process; | |||
| void *process_arg; | |||
| JackThreadInitCallback thread_init; | |||
| void *thread_init_arg; | |||
| JackBufferSizeCallback bufsize; | |||
| void *bufsize_arg; | |||
| JackSampleRateCallback srate; | |||
| void *srate_arg; | |||
| JackPortRegistrationCallback port_register; | |||
| void *port_register_arg; | |||
| JackPortConnectCallback port_connect; | |||
| void *port_connect_arg; | |||
| JackGraphOrderCallback graph_order; | |||
| void *graph_order_arg; | |||
| JackXRunCallback xrun; | |||
| void *xrun_arg; | |||
| JackSyncCallback sync_cb; | |||
| void *sync_arg; | |||
| JackTimebaseCallback timebase_cb; | |||
| void *timebase_arg; | |||
| JackFreewheelCallback freewheel_cb; | |||
| void *freewheel_arg; | |||
| JackClientRegistrationCallback client_register; | |||
| void *client_register_arg; | |||
| JackThreadCallback thread_cb; | |||
| void *thread_cb_arg; | |||
| /* external clients: set by libjack | |||
| * internal clients: set by engine */ | |||
| int (*deliver_request)(void*, jack_request_t*); /* JOQ: 64/32 bug! */ | |||
| void *deliver_arg; | |||
| /* for engine use only */ | |||
| void *private_client; | |||
| } jack_client_control_t; | |||
| volatile uint8_t process_cbset; | |||
| volatile uint8_t thread_init_cbset; | |||
| volatile uint8_t bufsize_cbset; | |||
| volatile uint8_t srate_cbset; | |||
| volatile uint8_t port_register_cbset; | |||
| volatile uint8_t port_connect_cbset; | |||
| volatile uint8_t graph_order_cbset; | |||
| volatile uint8_t xrun_cbset; | |||
| volatile uint8_t sync_cb_cbset; | |||
| volatile uint8_t timebase_cb_cbset; | |||
| volatile uint8_t freewheel_cb_cbset; | |||
| volatile uint8_t client_register_cbset; | |||
| volatile uint8_t thread_cb_cbset; | |||
| } POST_PACKED_STRUCTURE jack_client_control_t; | |||
| typedef struct { | |||
| @@ -299,14 +294,14 @@ typedef struct { | |||
| char object_path[PATH_MAX+1]; | |||
| char object_data[1024]; | |||
| } jack_client_connect_request_t; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_request_t; | |||
| typedef struct { | |||
| jack_status_t status; | |||
| jack_shm_info_t client_shm; | |||
| jack_shm_info_t engine_shm; | |||
| jack_shm_registry_index_t client_shm_index; | |||
| jack_shm_registry_index_t engine_shm_index; | |||
| char fifo_prefix[PATH_MAX+1]; | |||
| @@ -315,24 +310,29 @@ typedef struct { | |||
| char name[JACK_CLIENT_NAME_SIZE]; /* unique name, if assigned */ | |||
| /* these two are valid only for internal clients */ | |||
| jack_client_control_t *client_control; | |||
| jack_control_t *engine_control; | |||
| /* these two are valid only for internal clients, and thus | |||
| are exempt from the requirement that we not export | |||
| pointers back to clients. an internal client must | |||
| necessarily match the host, so 32/64 bit issues | |||
| do not apply to these pointers. | |||
| */ | |||
| jack_client_control_t* client_control; | |||
| jack_control_t* engine_control; | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| /* specific resources for server/client real-time thread communication */ | |||
| int32_t portnum; | |||
| #endif | |||
| } jack_client_connect_result_t; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_result_t; | |||
| typedef struct { | |||
| jack_client_id_t client_id; | |||
| } jack_client_connect_ack_request_t; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_ack_request_t; | |||
| typedef struct { | |||
| int8_t status; | |||
| } jack_client_connect_ack_result_t; | |||
| } POST_PACKED_STRUCTURE jack_client_connect_ack_result_t; | |||
| typedef enum { | |||
| RegisterPort = 1, | |||
| @@ -363,7 +363,8 @@ typedef enum { | |||
| struct _jack_request { | |||
| RequestType type; | |||
| //RequestType type; | |||
| uint32_t type; | |||
| union { | |||
| struct { | |||
| char name[JACK_PORT_NAME_SIZE]; | |||
| @@ -372,33 +373,35 @@ struct _jack_request { | |||
| jack_shmsize_t buffer_size; | |||
| jack_port_id_t port_id; | |||
| jack_client_id_t client_id; | |||
| } port_info; | |||
| } POST_PACKED_STRUCTURE port_info; | |||
| struct { | |||
| char source_port[JACK_PORT_NAME_SIZE]; | |||
| char destination_port[JACK_PORT_NAME_SIZE]; | |||
| } connect; | |||
| } POST_PACKED_STRUCTURE connect; | |||
| struct { | |||
| int32_t nports; | |||
| const char **ports; /* JOQ: 32/64 problem? */ | |||
| } port_connections; | |||
| //const char **ports; /* JOQ: 32/64 problem? */ | |||
| uint64_t ports; | |||
| } POST_PACKED_STRUCTURE port_connections; | |||
| struct { | |||
| jack_client_id_t client_id; | |||
| int32_t conditional; | |||
| } timebase; | |||
| } POST_PACKED_STRUCTURE timebase; | |||
| struct { | |||
| jack_options_t options; | |||
| //jack_options_t options; | |||
| uint32_t options; | |||
| jack_client_id_t id; | |||
| char name[JACK_CLIENT_NAME_SIZE]; | |||
| char path[PATH_MAX+1]; | |||
| char init[JACK_LOAD_INIT_LIMIT]; | |||
| } intclient; | |||
| } POST_PACKED_STRUCTURE intclient; | |||
| jack_client_id_t client_id; | |||
| jack_nframes_t nframes; | |||
| jack_time_t timeout; | |||
| pid_t cap_pid; | |||
| } x; | |||
| } POST_PACKED_STRUCTURE x; | |||
| int32_t status; | |||
| }; | |||
| } POST_PACKED_STRUCTURE; | |||
| /* Per-client structure allocated in the server's address space. | |||
| * It's here because its not part of the engine structure. | |||
| @@ -432,7 +435,42 @@ typedef struct _jack_client_internal { | |||
| int running; | |||
| int portnum; | |||
| #endif /* JACK_USE_MACH_THREADS */ | |||
| #if 0 | |||
| /* callbacks | |||
| */ | |||
| JackProcessCallback process; | |||
| void *process_arg; | |||
| JackThreadInitCallback thread_init; | |||
| void *thread_init_arg; | |||
| JackBufferSizeCallback bufsize; | |||
| void *bufsize_arg; | |||
| JackSampleRateCallback srate; | |||
| void *srate_arg; | |||
| JackPortRegistrationCallback port_register; | |||
| void *port_register_arg; | |||
| JackPortConnectCallback port_connect; | |||
| void *port_connect_arg; | |||
| JackGraphOrderCallback graph_order; | |||
| void *graph_order_arg; | |||
| JackXRunCallback xrun; | |||
| void *xrun_arg; | |||
| JackSyncCallback sync_cb; | |||
| void *sync_arg; | |||
| JackTimebaseCallback timebase_cb; | |||
| void *timebase_arg; | |||
| JackFreewheelCallback freewheel_cb; | |||
| void *freewheel_arg; | |||
| JackClientRegistrationCallback client_register; | |||
| void *client_register_arg; | |||
| JackThreadCallback thread_cb; | |||
| void *thread_cb_arg; | |||
| #endif | |||
| /* external clients: set by libjack | |||
| * internal clients: set by engine */ | |||
| //int (*deliver_request)(void*, jack_request_t*); /* JOQ: 64/32 bug! */ | |||
| //void *deliver_arg; | |||
| jack_client_t *private_client; | |||
| } jack_client_internal_t; | |||
| typedef struct _jack_thread_arg { | |||
| @@ -27,6 +27,22 @@ extern "C" { | |||
| #include <jack/types.h> | |||
| #ifndef POST_PACKED_STRUCTURE | |||
| #ifdef __GNUC__ | |||
| /* POST_PACKED_STRUCTURE needs to be a macro which | |||
| expands into a compiler directive. The directive must | |||
| tell the compiler to arrange the preceding structure | |||
| declaration so that it is packed on byte-boundaries rather | |||
| than use the natural alignment of the processor and/or | |||
| compiler. | |||
| */ | |||
| #define POST_PACKED_STRUCTURE __attribute__((__packed__)) | |||
| #else | |||
| /* Add other things here for non-gcc platforms */ | |||
| #endif | |||
| #endif | |||
| /** | |||
| * Transport states. | |||
| */ | |||
| @@ -127,7 +143,7 @@ typedef struct { | |||
| /* When (unique_1 == unique_2) the contents are consistent. */ | |||
| jack_unique_t unique_2; /**< unique ID */ | |||
| } jack_position_t; | |||
| } POST_PACKED_STRUCTURE jack_position_t; | |||
| /** | |||
| * Called by the timebase master to release itself from that | |||
| @@ -38,6 +38,8 @@ | |||
| #include "clientengine.h" | |||
| #include "transengine.h" | |||
| #include "libjack/local.h" | |||
| static void | |||
| jack_client_disconnect_ports (jack_engine_t *engine, | |||
| jack_client_internal_t *client) | |||
| @@ -318,7 +320,7 @@ jack_client_unload (jack_client_internal_t *client) | |||
| { | |||
| if (client->handle) { | |||
| if (client->finish) { | |||
| client->finish (client->control->process_arg); | |||
| client->finish (client->private_client->process_arg); | |||
| } | |||
| dlclose (client->handle); | |||
| } | |||
| @@ -516,25 +518,38 @@ jack_setup_client_control (jack_engine_t *engine, int fd, | |||
| client->subgraph_start_fd = -1; | |||
| client->subgraph_wait_fd = -1; | |||
| client->control->process = NULL; | |||
| client->control->process_arg = NULL; | |||
| client->control->bufsize = NULL; | |||
| client->control->bufsize_arg = NULL; | |||
| client->control->srate = NULL; | |||
| client->control->srate_arg = NULL; | |||
| client->control->xrun = NULL; | |||
| client->control->xrun_arg = NULL; | |||
| client->control->port_register = NULL; | |||
| client->control->port_register_arg = NULL; | |||
| client->control->port_connect = NULL; | |||
| client->control->port_connect_arg = NULL; | |||
| client->control->graph_order = NULL; | |||
| client->control->graph_order_arg = NULL; | |||
| client->control->client_register = NULL; | |||
| client->control->client_register_arg = NULL; | |||
| client->control->thread_cb = NULL; | |||
| client->control->thread_cb_arg = NULL; | |||
| client->control->process_cbset = FALSE; | |||
| client->control->bufsize_cbset = FALSE; | |||
| client->control->srate_cbset = FALSE; | |||
| client->control->xrun_cbset = FALSE; | |||
| client->control->port_register_cbset = FALSE; | |||
| client->control->port_connect_cbset = FALSE; | |||
| client->control->graph_order_cbset = FALSE; | |||
| client->control->client_register_cbset = FALSE; | |||
| client->control->thread_cb_cbset = FALSE; | |||
| #if 0 | |||
| if (type != ClientExternal) { | |||
| client->process = NULL; | |||
| client->process_arg = NULL; | |||
| client->bufsize = NULL; | |||
| client->bufsize_arg = NULL; | |||
| client->srate = NULL; | |||
| client->srate_arg = NULL; | |||
| client->xrun = NULL; | |||
| client->xrun_arg = NULL; | |||
| client->port_register = NULL; | |||
| client->port_register_arg = NULL; | |||
| client->port_connect = NULL; | |||
| client->port_connect_arg = NULL; | |||
| client->graph_order = NULL; | |||
| client->graph_order_arg = NULL; | |||
| client->client_register = NULL; | |||
| client->client_register_arg = NULL; | |||
| client->thread_cb = NULL; | |||
| client->thread_cb_arg = NULL; | |||
| } | |||
| #endif | |||
| jack_transport_client_new (client); | |||
| #ifdef JACK_USE_MACH_THREADS | |||
| @@ -586,12 +601,22 @@ setup_client (jack_engine_t *engine, ClientType type, char *name, | |||
| if (jack_client_is_internal(client)) { | |||
| // XXX: do i need to lock the graph here ? | |||
| // i moved this one up in the init process, lets see what happens. | |||
| /* Internal clients need to make regular JACK API | |||
| * calls, which need a jack_client_t structure. | |||
| * Create one here. | |||
| */ | |||
| client->private_client = | |||
| jack_client_alloc_internal (client->control, engine); | |||
| /* Set up the pointers necessary for the request | |||
| * system to work. The client is in the same address | |||
| * space */ | |||
| client->control->deliver_request = internal_client_request; | |||
| client->control->deliver_arg = engine; | |||
| client->private_client->deliver_request = internal_client_request; | |||
| client->private_client->deliver_arg = engine; | |||
| } | |||
| /* add new client to the clients list */ | |||
| @@ -601,12 +626,6 @@ setup_client (jack_engine_t *engine, ClientType type, char *name, | |||
| if (jack_client_is_internal(client)) { | |||
| /* Internal clients need to make regular JACK API | |||
| * calls, which need a jack_client_t structure. | |||
| * Create one here. | |||
| */ | |||
| client->control->private_client = | |||
| jack_client_alloc_internal (client->control, engine); | |||
| jack_unlock_graph (engine); | |||
| @@ -616,7 +635,7 @@ setup_client (jack_engine_t *engine, ClientType type, char *name, | |||
| if (client->control->type == ClientInternal) { | |||
| pthread_mutex_unlock (&engine->request_lock); | |||
| if (client->initialize (client->control->private_client, | |||
| if (client->initialize (client->private_client, | |||
| object_data)) { | |||
| /* failed: clean up client data */ | |||
| @@ -735,8 +754,8 @@ jack_client_create (jack_engine_t *engine, int client_fd) | |||
| res.status |= JackFailure; /* just making sure */ | |||
| return -1; | |||
| } | |||
| res.client_shm = client->control_shm; | |||
| res.engine_shm = engine->control_shm; | |||
| res.client_shm_index = client->control_shm.index; | |||
| res.engine_shm_index = engine->control_shm.index; | |||
| res.realtime = engine->control->real_time; | |||
| res.realtime_priority = engine->rtpriority - 1; | |||
| strncpy (res.name, req.name, sizeof(res.name)); | |||
| @@ -880,7 +899,7 @@ jack_client_delete (jack_engine_t *engine, jack_client_internal_t *client) | |||
| if (jack_client_is_internal (client)) { | |||
| jack_client_unload (client); | |||
| free (client->control->private_client); | |||
| free (client->private_client); | |||
| free ((void *) client->control); | |||
| } else { | |||
| @@ -61,6 +61,8 @@ | |||
| #include "clientengine.h" | |||
| #include "transengine.h" | |||
| #include "libjack/local.h" | |||
| typedef struct { | |||
| jack_port_internal_t *source; | |||
| @@ -581,17 +583,17 @@ jack_process_internal(jack_engine_t *engine, JSList *node, | |||
| /* XXX how to time out an internal client? */ | |||
| if (ctl->sync_cb) | |||
| jack_call_sync_client (ctl->private_client); | |||
| if (ctl->sync_cb_cbset) | |||
| jack_call_sync_client (client->private_client); | |||
| if (ctl->process) | |||
| if (ctl->process (nframes, ctl->process_arg)) { | |||
| if (ctl->process_cbset) | |||
| if (client->private_client->process (nframes, client->private_client->process_arg)) { | |||
| jack_error ("internal client %s failed", ctl->name); | |||
| engine->process_errors++; | |||
| } | |||
| if (ctl->timebase_cb) | |||
| jack_call_timebase_master (ctl->private_client); | |||
| if (ctl->timebase_cb_cbset) | |||
| jack_call_timebase_master (client->private_client); | |||
| ctl->state = Finished; | |||
| @@ -1071,7 +1073,7 @@ jack_engine_load_driver (jack_engine_t *engine, | |||
| return -1; | |||
| } | |||
| if ((driver = info->initialize (client->control->private_client, | |||
| if ((driver = info->initialize (client->private_client, | |||
| driver_params)) == NULL) { | |||
| free (info); | |||
| return -1; | |||
| @@ -1401,6 +1403,8 @@ handle_external_client_request (jack_engine_t *engine, int fd) | |||
| } else { | |||
| jack_error ("cannot read request from client (%d/%d/%s)", | |||
| r, sizeof(req), strerror (errno)); | |||
| // XXX: shouldnt we mark this client as error now ? | |||
| return -1; | |||
| } | |||
| } | |||
| @@ -2410,7 +2414,7 @@ jack_notify_all_port_interested_clients (jack_engine_t *engine, jack_client_id_t | |||
| for (node = engine->clients; node; node = jack_slist_next (node)) { | |||
| jack_client_internal_t* client = (jack_client_internal_t*) node->data; | |||
| if (src_client != client && dst_client != client && client->control->port_connect != NULL) { | |||
| if (src_client != client && dst_client != client && client->control->port_connect_cbset != FALSE) { | |||
| /* one of the ports belong to this client or it has a port connect callback */ | |||
| jack_deliver_event (engine, client, &event); | |||
| @@ -2447,39 +2451,39 @@ jack_deliver_event (jack_engine_t *engine, jack_client_internal_t *client, | |||
| case PortConnected: | |||
| case PortDisconnected: | |||
| jack_client_handle_port_connection | |||
| (client->control->private_client, event); | |||
| (client->private_client, event); | |||
| break; | |||
| case BufferSizeChange: | |||
| jack_client_invalidate_port_buffers | |||
| (client->control->private_client); | |||
| (client->private_client); | |||
| if (client->control->bufsize) { | |||
| client->control->bufsize | |||
| if (client->control->bufsize_cbset) { | |||
| client->private_client->bufsize | |||
| (event->x.n, | |||
| client->control->bufsize_arg); | |||
| client->private_client->bufsize_arg); | |||
| } | |||
| break; | |||
| case SampleRateChange: | |||
| if (client->control->srate) { | |||
| client->control->srate | |||
| if (client->control->srate_cbset) { | |||
| client->private_client->srate | |||
| (event->x.n, | |||
| client->control->srate_arg); | |||
| client->private_client->srate_arg); | |||
| } | |||
| break; | |||
| case GraphReordered: | |||
| if (client->control->graph_order) { | |||
| client->control->graph_order | |||
| (client->control->graph_order_arg); | |||
| if (client->control->graph_order_cbset) { | |||
| client->private_client->graph_order | |||
| (client->private_client->graph_order_arg); | |||
| } | |||
| break; | |||
| case XRun: | |||
| if (client->control->xrun) { | |||
| client->control->xrun | |||
| (client->control->xrun_arg); | |||
| if (client->control->xrun_cbset) { | |||
| client->private_client->xrun | |||
| (client->private_client->xrun_arg); | |||
| } | |||
| break; | |||
| @@ -3134,7 +3138,7 @@ void jack_dump_configuration(jack_engine_t *engine, int take_lock) | |||
| ++n, | |||
| ctl->name, | |||
| ctl->type, | |||
| ctl->process ? "yes" : "no", | |||
| ctl->process_cbset ? "yes" : "no", | |||
| client->subgraph_start_fd, | |||
| client->subgraph_wait_fd); | |||
| @@ -3940,7 +3944,9 @@ jack_do_get_port_connections (jack_engine_t *engine, jack_request_t *req, | |||
| * names. store in malloc'ed space, | |||
| * client frees | |||
| */ | |||
| req->x.port_connections.ports[i] = | |||
| char **ports = req->x.port_connections.ports; | |||
| ports[i] = | |||
| engine->control->ports[port_id].name; | |||
| } else { | |||
| @@ -3987,7 +3993,7 @@ jack_port_registration_notify (jack_engine_t *engine, | |||
| continue; | |||
| } | |||
| if (client->control->port_register) { | |||
| if (client->control->port_register_cbset) { | |||
| if (jack_deliver_event (engine, client, &event)) { | |||
| jack_error ("cannot send port registration" | |||
| " notification to %s (%s)", | |||
| @@ -4022,7 +4028,7 @@ jack_client_registration_notify (jack_engine_t *engine, | |||
| continue; | |||
| } | |||
| if (client->control->client_register) { | |||
| if (client->control->client_register_cbset) { | |||
| if (jack_deliver_event (engine, client, &event)) { | |||
| jack_error ("cannot send client registration" | |||
| " notification to %s (%s)", | |||
| @@ -321,10 +321,18 @@ jack_transport_client_new (jack_client_internal_t *client) | |||
| client->control->active_slowsync = 0; | |||
| client->control->sync_poll = 0; | |||
| client->control->sync_new = 0; | |||
| client->control->sync_cb = NULL; | |||
| client->control->sync_arg = NULL; | |||
| client->control->timebase_cb = NULL; | |||
| client->control->timebase_arg = NULL; | |||
| client->control->sync_cb_cbset = FALSE; | |||
| client->control->timebase_cb_cbset = FALSE; | |||
| #if 0 | |||
| if (client->control->type != ClientExternal) { | |||
| client->sync_cb = NULL; | |||
| client->sync_arg = NULL; | |||
| client->timebase_cb = NULL; | |||
| client->timebase_arg = NULL; | |||
| } | |||
| #endif | |||
| } | |||
| /* on ResetSyncClient request */ | |||
| @@ -273,7 +273,7 @@ jack_client_deliver_request (const jack_client_t *client, jack_request_t *req) | |||
| * the server. | |||
| */ | |||
| return client->control->deliver_request (client->control->deliver_arg, | |||
| return client->deliver_request (client->deliver_arg, | |||
| req); | |||
| } | |||
| @@ -454,10 +454,10 @@ jack_client_handle_port_connection (jack_client_t *client, jack_event_t *event) | |||
| } | |||
| } | |||
| if (client->control->port_connect) { | |||
| client->control->port_connect (event->x.self_id, event->y.other_id, | |||
| if (client->control->port_connect_cbset) { | |||
| client->port_connect (event->x.self_id, event->y.other_id, | |||
| (event->type == PortConnected ? 1 : 0), | |||
| client->control->port_connect_arg); | |||
| client->port_connect_arg); | |||
| } | |||
| return 0; | |||
| @@ -530,8 +530,8 @@ jack_handle_reorder (jack_client_t *client, jack_event_t *event) | |||
| execute it now. | |||
| */ | |||
| if (client->control->graph_order) { | |||
| client->control->graph_order (client->control->graph_order_arg); | |||
| if (client->control->graph_order_cbset) { | |||
| client->graph_order (client->graph_order_arg); | |||
| } | |||
| return 0; | |||
| @@ -1013,7 +1013,7 @@ jack_client_open_aux (const char *client_name, | |||
| } | |||
| /* attach the engine control/info block */ | |||
| client->engine_shm = res.engine_shm; | |||
| client->engine_shm.index = res.engine_shm_index; | |||
| if (jack_attach_shm (&client->engine_shm)) { | |||
| jack_error ("cannot attached engine control shared memory" | |||
| " segment"); | |||
| @@ -1026,7 +1026,7 @@ jack_client_open_aux (const char *client_name, | |||
| jack_set_clock_source (client->engine->clock_source); | |||
| /* now attach the client control block */ | |||
| client->control_shm = res.client_shm; | |||
| client->control_shm.index = res.client_shm_index; | |||
| if (jack_attach_shm (&client->control_shm)) { | |||
| jack_error ("cannot attached client control shared memory" | |||
| " segment"); | |||
| @@ -1056,8 +1056,8 @@ jack_client_open_aux (const char *client_name, | |||
| /* set up the client so that it does the right thing for an | |||
| * external client | |||
| */ | |||
| client->control->deliver_request = oop_client_deliver_request; | |||
| client->control->deliver_arg = client; | |||
| client->deliver_request = oop_client_deliver_request; | |||
| client->deliver_arg = client; | |||
| if ((ev_fd = server_event_connect (client, va.server_name)) < 0) { | |||
| goto fail; | |||
| @@ -1255,8 +1255,8 @@ jack_start_freewheel (jack_client_t* client) | |||
| #endif | |||
| } | |||
| if (control->freewheel_cb) { | |||
| control->freewheel_cb (1, control->freewheel_arg); | |||
| if (control->freewheel_cb_cbset) { | |||
| client->freewheel_cb (1, client->freewheel_arg); | |||
| } | |||
| } | |||
| @@ -1275,8 +1275,8 @@ jack_stop_freewheel (jack_client_t* client) | |||
| #endif | |||
| } | |||
| if (control->freewheel_cb) { | |||
| control->freewheel_cb (0, control->freewheel_arg); | |||
| if (control->freewheel_cb_cbset) { | |||
| client->freewheel_cb (0, client->freewheel_arg); | |||
| } | |||
| } | |||
| @@ -1334,34 +1334,34 @@ jack_client_process_events (jack_client_t* client) | |||
| port->type_info = &client->engine->port_types[port->shared->ptype_id]; | |||
| } | |||
| } | |||
| if (control->port_register) { | |||
| control->port_register | |||
| if (control->port_register_cbset) { | |||
| client->port_register | |||
| (event.x.port_id, TRUE, | |||
| control->port_register_arg); | |||
| client->port_register_arg); | |||
| } | |||
| break; | |||
| case PortUnregistered: | |||
| if (control->port_register) { | |||
| control->port_register | |||
| if (control->port_register_cbset) { | |||
| client->port_register | |||
| (event.x.port_id, FALSE, | |||
| control->port_register_arg); | |||
| client->port_register_arg); | |||
| } | |||
| break; | |||
| case ClientRegistered: | |||
| if (control->client_register) { | |||
| control->client_register | |||
| if (control->client_register_cbset) { | |||
| client->client_register | |||
| (event.x.name, TRUE, | |||
| control->client_register_arg); | |||
| client->client_register_arg); | |||
| } | |||
| break; | |||
| case ClientUnregistered: | |||
| if (control->client_register) { | |||
| control->client_register | |||
| if (control->client_register_cbset) { | |||
| client->client_register | |||
| (event.x.name, FALSE, | |||
| control->client_register_arg); | |||
| client->client_register_arg); | |||
| } | |||
| break; | |||
| @@ -1377,25 +1377,25 @@ jack_client_process_events (jack_client_t* client) | |||
| case BufferSizeChange: | |||
| jack_client_invalidate_port_buffers (client); | |||
| if (control->bufsize) { | |||
| status = control->bufsize | |||
| if (control->bufsize_cbset) { | |||
| status = client->bufsize | |||
| (control->nframes, | |||
| control->bufsize_arg); | |||
| client->bufsize_arg); | |||
| } | |||
| break; | |||
| case SampleRateChange: | |||
| if (control->srate) { | |||
| status = control->srate | |||
| if (control->srate_cbset) { | |||
| status = client->srate | |||
| (control->nframes, | |||
| control->srate_arg); | |||
| client->srate_arg); | |||
| } | |||
| break; | |||
| case XRun: | |||
| if (control->xrun) { | |||
| status = control->xrun | |||
| (control->xrun_arg); | |||
| if (control->xrun_cbset) { | |||
| status = client->xrun | |||
| (client->xrun_arg); | |||
| } | |||
| break; | |||
| @@ -1583,7 +1583,7 @@ jack_thread_wait (jack_client_t* client, int status) | |||
| /* housekeeping/cleanup after data processing */ | |||
| if (status == 0 && client->control->timebase_cb) { | |||
| if (status == 0 && client->control->timebase_cb_cbset) { | |||
| jack_call_timebase_master (client); | |||
| } | |||
| @@ -1621,7 +1621,7 @@ jack_thread_wait (jack_client_t* client, int status) | |||
| /* begin preemption checking */ | |||
| CHECK_PREEMPTION (client->engine, TRUE); | |||
| if (client->control->sync_cb) | |||
| if (client->control->sync_cb_cbset) | |||
| jack_call_sync_client (client); | |||
| return client->control->nframes; | |||
| @@ -1644,7 +1644,7 @@ jack_nframes_t jack_cycle_wait (jack_client_t* client) | |||
| /* begin preemption checking */ | |||
| CHECK_PREEMPTION (client->engine, TRUE); | |||
| if (client->control->sync_cb) | |||
| if (client->control->sync_cb_cbset) | |||
| jack_call_sync_client (client); | |||
| return client->control->nframes; | |||
| @@ -1658,7 +1658,7 @@ void jack_cycle_signal(jack_client_t* client, int status) | |||
| /* housekeeping/cleanup after data processing */ | |||
| if (status == 0 && client->control->timebase_cb) { | |||
| if (status == 0 && client->control->timebase_cb_cbset) { | |||
| jack_call_timebase_master (client); | |||
| } | |||
| @@ -1701,9 +1701,9 @@ jack_client_thread_aux (void *arg) | |||
| DEBUG ("client thread is now running"); | |||
| if (control->thread_init) { | |||
| if (control->thread_init_cbset) { | |||
| DEBUG ("calling client thread init callback"); | |||
| control->thread_init (control->thread_init_arg); | |||
| client->thread_init (client->thread_init_arg); | |||
| } | |||
| /* wait for first wakeup from server */ | |||
| @@ -1712,14 +1712,14 @@ jack_client_thread_aux (void *arg) | |||
| /* now run till we're done */ | |||
| if (control->process) { | |||
| if (control->process_cbset) { | |||
| /* run process callback, then wait... ad-infinitum */ | |||
| while (1) { | |||
| DEBUG("client calls process()"); | |||
| int status = (control->process (control->nframes, | |||
| control->process_arg) == | |||
| int status = (client->process (control->nframes, | |||
| client->process_arg) == | |||
| control->nframes); | |||
| control->state = Finished; | |||
| DEBUG("client leaves process(), re-enters wait"); | |||
| @@ -1745,7 +1745,7 @@ jack_client_thread (void *arg) | |||
| jack_client_t *client = (jack_client_t *) arg; | |||
| jack_client_control_t *control = client->control; | |||
| if (client->control->thread_cb) { | |||
| if (client->control->thread_cb_cbset) { | |||
| pthread_mutex_lock (&client_lock); | |||
| client->thread_ok = TRUE; | |||
| @@ -1756,7 +1756,7 @@ jack_client_thread (void *arg) | |||
| control->pid = getpid(); | |||
| control->pgrp = getpgrp(); | |||
| client->control->thread_cb(client->control->thread_cb_arg); | |||
| client->thread_cb(client->thread_cb_arg); | |||
| jack_client_thread_suicide(client); | |||
| } else { | |||
| jack_client_thread_aux(arg); | |||
| @@ -2232,8 +2232,9 @@ jack_set_graph_order_callback (jack_client_t *client, | |||
| jack_error ("You cannot set callbacks on an active client."); | |||
| return -1; | |||
| } | |||
| client->control->graph_order = callback; | |||
| client->control->graph_order_arg = arg; | |||
| client->graph_order = callback; | |||
| client->graph_order_arg = arg; | |||
| client->control->graph_order_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2245,8 +2246,9 @@ int jack_set_xrun_callback (jack_client_t *client, | |||
| return -1; | |||
| } | |||
| client->control->xrun = callback; | |||
| client->control->xrun_arg = arg; | |||
| client->xrun = callback; | |||
| client->xrun_arg = arg; | |||
| client->control->xrun_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2260,13 +2262,14 @@ jack_set_process_callback (jack_client_t *client, | |||
| return -1; | |||
| } | |||
| if (client->control->thread_cb) { | |||
| if (client->control->thread_cb_cbset) { | |||
| jack_error ("A thread callback has already been setup, both models cannot be used at the same time!"); | |||
| return -1; | |||
| } | |||
| client->control->process_arg = arg; | |||
| client->control->process = callback; | |||
| client->process_arg = arg; | |||
| client->process = callback; | |||
| client->control->process_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2279,8 +2282,9 @@ jack_set_thread_init_callback (jack_client_t *client, | |||
| jack_error ("You cannot set callbacks on an active client."); | |||
| return -1; | |||
| } | |||
| client->control->thread_init_arg = arg; | |||
| client->control->thread_init = callback; | |||
| client->thread_init_arg = arg; | |||
| client->thread_init = callback; | |||
| client->control->thread_init_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2292,8 +2296,9 @@ jack_set_freewheel_callback (jack_client_t *client, | |||
| jack_error ("You cannot set callbacks on an active client."); | |||
| return -1; | |||
| } | |||
| client->control->freewheel_arg = arg; | |||
| client->control->freewheel_cb = callback; | |||
| client->freewheel_arg = arg; | |||
| client->freewheel_cb = callback; | |||
| client->control->freewheel_cb_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2301,8 +2306,9 @@ int | |||
| jack_set_buffer_size_callback (jack_client_t *client, | |||
| JackBufferSizeCallback callback, void *arg) | |||
| { | |||
| client->control->bufsize_arg = arg; | |||
| client->control->bufsize = callback; | |||
| client->bufsize_arg = arg; | |||
| client->bufsize = callback; | |||
| client->control->bufsize_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2315,8 +2321,9 @@ jack_set_port_registration_callback(jack_client_t *client, | |||
| jack_error ("You cannot set callbacks on an active client."); | |||
| return -1; | |||
| } | |||
| client->control->port_register_arg = arg; | |||
| client->control->port_register = callback; | |||
| client->port_register_arg = arg; | |||
| client->port_register = callback; | |||
| client->control->port_register_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2329,8 +2336,9 @@ jack_set_port_connect_callback(jack_client_t *client, | |||
| jack_error ("You cannot set callbacks on an active client."); | |||
| return -1; | |||
| } | |||
| client->control->port_connect_arg = arg; | |||
| client->control->port_connect = callback; | |||
| client->port_connect_arg = arg; | |||
| client->port_connect = callback; | |||
| client->control->port_connect_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2343,8 +2351,9 @@ jack_set_client_registration_callback(jack_client_t *client, | |||
| jack_error ("You cannot set callbacks on an active client."); | |||
| return -1; | |||
| } | |||
| client->control->client_register_arg = arg; | |||
| client->control->client_register = callback; | |||
| client->client_register_arg = arg; | |||
| client->client_register = callback; | |||
| client->control->client_register_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -2356,13 +2365,14 @@ jack_set_process_thread(jack_client_t* client, JackThreadCallback callback, void | |||
| return -1; | |||
| } | |||
| if (client->control->process) { | |||
| if (client->control->process_cbset) { | |||
| jack_error ("A process callback has already been setup, both models cannot be used at the same time!"); | |||
| return -1; | |||
| } | |||
| client->control->thread_cb_arg = arg; | |||
| client->control->thread_cb = callback; | |||
| client->thread_cb_arg = arg; | |||
| client->thread_cb = callback; | |||
| client->control->thread_cb_cbset = (callback != NULL); | |||
| return 0; | |||
| } | |||
| @@ -42,6 +42,40 @@ struct _jack_client { | |||
| char rt_thread_ok : 1; | |||
| #endif | |||
| /* callbacks | |||
| */ | |||
| JackProcessCallback process; | |||
| void *process_arg; | |||
| JackThreadInitCallback thread_init; | |||
| void *thread_init_arg; | |||
| JackBufferSizeCallback bufsize; | |||
| void *bufsize_arg; | |||
| JackSampleRateCallback srate; | |||
| void *srate_arg; | |||
| JackPortRegistrationCallback port_register; | |||
| void *port_register_arg; | |||
| JackPortConnectCallback port_connect; | |||
| void *port_connect_arg; | |||
| JackGraphOrderCallback graph_order; | |||
| void *graph_order_arg; | |||
| JackXRunCallback xrun; | |||
| void *xrun_arg; | |||
| JackSyncCallback sync_cb; | |||
| void *sync_arg; | |||
| JackTimebaseCallback timebase_cb; | |||
| void *timebase_arg; | |||
| JackFreewheelCallback freewheel_cb; | |||
| void *freewheel_arg; | |||
| JackClientRegistrationCallback client_register; | |||
| void *client_register_arg; | |||
| JackThreadCallback thread_cb; | |||
| void *thread_cb_arg; | |||
| /* external clients: set by libjack | |||
| * internal clients: set by engine */ | |||
| int (*deliver_request)(void*, jack_request_t*); /* JOQ: 64/32 bug! */ | |||
| void *deliver_arg; | |||
| }; | |||
| extern int jack_client_deliver_request (const jack_client_t *client, | |||
| @@ -135,9 +135,9 @@ jack_call_sync_client (jack_client_t *client) | |||
| if ((ectl->new_pos || control->sync_poll || control->sync_new) && | |||
| control->active_slowsync) { | |||
| if (control->sync_cb (ectl->transport_state, | |||
| if (client->sync_cb (ectl->transport_state, | |||
| &ectl->current_time, | |||
| control->sync_arg)) { | |||
| client->sync_arg)) { | |||
| if (control->sync_poll) { | |||
| control->sync_poll = 0; | |||
| @@ -169,18 +169,19 @@ jack_call_timebase_master (jack_client_t *client) | |||
| if ((ectl->transport_state == JackTransportRolling) || | |||
| new_pos) { | |||
| control->timebase_cb (ectl->transport_state, | |||
| client->timebase_cb (ectl->transport_state, | |||
| control->nframes, | |||
| &ectl->pending_time, | |||
| new_pos, | |||
| control->timebase_arg); | |||
| client->timebase_arg); | |||
| } | |||
| } else { | |||
| /* another master took over, so resign */ | |||
| control->timebase_cb = NULL; | |||
| control->timebase_arg = NULL; | |||
| client->timebase_cb = NULL; | |||
| client->timebase_arg = NULL; | |||
| control->timebase_cb_cbset = FALSE; | |||
| } | |||
| } | |||
| @@ -309,8 +310,9 @@ jack_set_sample_rate_callback (jack_client_t *client, | |||
| jack_error ("You cannot set callbacks on an active client."); | |||
| return -1; | |||
| } | |||
| client->control->srate_arg = arg; | |||
| client->control->srate = callback; | |||
| client->srate_arg = arg; | |||
| client->srate = callback; | |||
| client->control->srate_cbset = (callback != NULL); | |||
| /* Now invoke it */ | |||
| @@ -331,9 +333,11 @@ jack_release_timebase (jack_client_t *client) | |||
| rc = jack_client_deliver_request (client, &req); | |||
| if (rc == 0) { | |||
| ctl->timebase_cb = NULL; | |||
| ctl->timebase_arg = NULL; | |||
| client->timebase_cb = NULL; | |||
| client->timebase_arg = NULL; | |||
| ctl->timebase_cb_cbset = NULL; | |||
| } | |||
| return rc; | |||
| } | |||
| @@ -353,8 +357,9 @@ jack_set_sync_callback (jack_client_t *client, | |||
| rc = jack_client_deliver_request (client, &req); | |||
| if (rc == 0) { | |||
| ctl->sync_cb = sync_callback; | |||
| ctl->sync_arg = arg; | |||
| client->sync_cb = sync_callback; | |||
| client->sync_arg = arg; | |||
| ctl->sync_cb_cbset = TRUE; | |||
| } | |||
| return rc; | |||
| } | |||
| @@ -384,8 +389,9 @@ jack_set_timebase_callback (jack_client_t *client, int conditional, | |||
| rc = jack_client_deliver_request (client, &req); | |||
| if (rc == 0) { | |||
| ctl->timebase_arg = arg; | |||
| ctl->timebase_cb = timebase_cb; | |||
| client->timebase_arg = arg; | |||
| client->timebase_cb = timebase_cb; | |||
| ctl->timebase_cb_cbset = TRUE; | |||
| } | |||
| return rc; | |||
| } | |||