Commit 4828d0c8 authored by sletz's avatar sletz
Browse files

rebase from trunk 4041:4083

git-svn-id: http://subversion.jackaudio.org/jack/jack2/branches/libjacknet@4084 0c269be4-1314-0410-8aa9-9f06e86f4224
parent 7a2863cf
......@@ -26,11 +26,42 @@ Josh Green
Mario Lang
Arnold Krille
Jan Engelhardt
Adrian Knoth
Adrian Knoth
David Garcia Garzon
---------------------------
Jackdmp changes log
---------------------------
---------------------------
2010-11-05 Stephane Letz <letz@grame.fr>
* In jackdmp.cpp, jackctl_setup_signals moved before jackctl_server_start.
* Correct symbols export in backends.
2010-11-03 Stephane Letz <letz@grame.fr>
* Improve backend error handling: fatal error returned by Read/Write now cause a Process failure (so a thread exit for blocking backends). Recoverable ones (XRuns..) are now treated internally in ALSA, FreeBob and FFADO backends.
2010-10-30 Stephane Letz <letz@grame.fr>
* Correct JackServer::Open to avoid a race when control API is used on OSX.
2010-10-29 Stephane Letz <letz@grame.fr>
* Correct lsp.c code.
* Add note about unique port-name requirement.
2010-09-08 Stephane Letz <letz@grame.fr>
* Sync JackAlsaDriver::alsa_driver_check_card_type with JACK1 backend.
2010-08-30 Stephane Letz <letz@grame.fr>
* Version 1.9.7 started.
2010-08-25 Stephane Letz <letz@grame.fr>
* In JackCoreAudioDriver, fix an issue when no value is given for input.
2010-08-23 Stephane Letz <letz@grame.fr>
......
......@@ -214,7 +214,8 @@ Note : To experiment with the -S option, jackdmp must be launched in a console.
1.9.2 : Solaris version. New "profiling" tools. Rework the mutex/signal classes. Support for BIG_ENDIAN machines in NetJack2. D-BUS based device reservation to better coexist with PulseAudio on Linux. Add auto_connect parameter in netmanager and netadapter. Use Torben Hohn PI controler code for adapters. Client incorrect re-naming fixed : now done at socket and fifo level. Virtualize and allow overriding of thread creation function, to allow Wine support (from JACK1).
1.9.3 : New JackBoomerDriver class for Boomer driver on Solaris. Add mixed 32/64 bits mode (off by default). Native MIDI backend (JackCoreMidiDriver, JackWinMMEDriver). In ALSA audio card reservation code, tries to open the card even if reservation fails. Clock source setting on Linux. Add jackctl_server_switch_master API. Fix transport callback (timebase master, sync) issue when used after jack_activate (RT thread was not running). D-Bus access for jackctl_server_add_slave/jackctl_server_remove_slave API. Cleanup "loopback" stuff in server. Torben Hohn fix for InitTime and GetMicroSeconds in JackWinTime.c. New jack_free function added in jack.h. Reworked Torben Hohn fix for server restart issue on Windows. Correct jack_set_error_function, jack_set_info_function and jack_set_thread_creator functions. Correct JackFifo::TimedWait for EINTR handling. Move DBus based audio device reservation code in ALSA backend compilation. Correct JackTransportEngine::MakeAllLocating, sync callback has to be called in this case also. NetJack2 code : better error checkout, method renaming. Tim Bechmann patch : hammerfall, only release monitor thread, if it has been created. Tim Bechmann memops.c optimization patches. In combined --dbus and --classic compilation code, use PulseAudio acquire/release code. Big rewrite of Solaris boomer driver, seems to work in duplex mode at least. Loopback backend reborn as a dynamically loadable separated backend.
1.9.4 : Solaris boomer backend now working in capture or playback only mode. Add a -G parameter in CoreAudio backend (the computation value in RT thread expressed as percent of period). Use SNDCTL_DSP_SYNCGROUP/SNDCTL_DSP_SYNCSTART API to synchronize input and output in Solaris boomer backend. Big endian bug fix in memops.c. Fix issues in JackNetDriver::DecodeTransportData and JackNetDriver::Initialize. Correct CPU timing in JackNetDriver, now take cycle begin time after Read. Simplify transport in NetJack2: master only can control transport. Change CoreAudio notification thread setup for OSX Snow Leopard. Correct server temporary mode : now set a global and quit after server/client message handling is finished. Add a string parameter to server ==> client notification, add a new JackInfoShutdownCallback type. CoreAudio backend now issue a JackInfoShutdownCallback when an unrecoverable error is detected (sampling rate change, stream configuration changeÉ). Correct jackdmp.cpp (failures case were not correct..). Improve JackCoreAudioDriver code. Raise default port number to 2048. Correct JackProcessSync::LockedTimedWait. Correct JACK_MESSAGE_SIZE value, particularly in OSX RPC code. Now start server channel thread only when backend has been started (so in JackServer::Start). Should solve race conditions at start time. jack_verbose moved to JackGlobals class. Improve aggregate device management in JackCoreAudioDriver : now a "private" device only and cleanup properly. Aggregate device code added to JackCoreAudioAdapter. Implement "hog mode" (exclusive access of the audio device) in JackCoreAudioDriver. Fix jack_set_sample_rate_callback to have he same behavior as in JACK1. Dynamic system version detection in JackCoreAudioDriver to either create public or private aggregate device. In JackCoreAudioDriver, force the SR value to the wanted one *before* creating aggregate device (otherwise creation will fail). In JackCoreAudioDriver, better cleanup of AD when intermediate open failure. In JackCoreAudioDriver::Start, wait for the audio driver to effectively start (use the MeasureCallback). In JackCoreAudioDriver, improve management of input/output channels: -1 is now used internally to indicate a wanted max value. In JackCoreAudioDriver::OpenAUHAL, correct stream format setup and cleanup. Correct crash bug in JackAudioAdapterInterface when not input is used in adapter (temporary fixÉ). Sync JackCoreAudioAdapter code on JackCoreAudioDriver one. JACK_SCHED_POLICY switched to SCHED_FIFO. Now can aggregate device that are themselves AD. No reason to make jack_on_shutdown deprecated, so revert the incorrect change. Thread AcquireRealTime and DropRealTime were (incorrectly) using fThread field. Use pthread_self()) (or GetCurrentThread() on Windows) to get the calling thread. Correctly save and restore RT mode state in freewheel mode. Correct freewheel code on client side. Fix AcquireRealTime and DropRealTime: now distinguish when called from another thread (AcquireRealTime/DropRealTime) and from the thread itself (AcquireSelfRealTime/DropSelfRealTime). Correct JackPosixThread::StartImp : thread priority setting now done in the RT case only. Correct JackGraphManager::GetBuffer for the "client loop with one connection" case : buffer must be copied. Correct JackInfoShutdownCallback prototype, two new JackClientProcessFailure and JackClientZombie JackStatus code. Correct JackCoreAudio driver when empty strings are given as -C, -P or -d parameter. Better memory allocation error checking on client (library) side. Better memory allocation error checking in ringbuffer.c, weak import improvements. Memory allocation error checking for jack_client_new and jack_client_open (server and client side). Memory allocation error checking in server for RPC. Simplify server temporary mode : now use a JackTemporaryException. Lock/Unlock shared memory segments (to test...). Sync with JACK1 : -r parameter now used for no-realtime, realtime (-R) is now default, usable backend given vie platform. In JackCoreAudio driver, (possibly) clock drift compensation when needed in aggregated devices. In JackCoreAudio driver, clock drift compensation in aggregated devices working. In JackCoreAudio driver, clock drift compensation semantic changed a bit : when on, does not activate if not needed (same clock domain). Sync JackCoreAudioAdapter code with JackCoreAudioDriver.
1.9.5 : Dynamic choice of maximum port number. More robust sample rate change handling code in JackCoreAudioDriver. Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). Fix port_rename callback : now both old name and new name are given as parameters. Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). Check dynamic port-max value. Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). Josh Green ALSA driver capture only patch. When threads are cancelled, the exception has to be rethrown. Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. Mario Lang alsa_io time calculation overflow patch. Shared memory manager was calling abort in case of fatal error, now return an error in caller. Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF.
1.9.5 : Dynamic choice of maximum port number. More robust sample rate change handling code in JackCoreAudioDriver. Devin Anderson patch for Jack FFADO driver issues with lost MIDI bytes between periods (and more). Fix port_rename callback : now both old name and new name are given as parameters. Special code in JackCoreAudio driver to handle completely buggy Digidesign CoreAudio user-land driver. Ensure that client-side message buffer thread calls thread_init callback if/when it is set by the client (backport of JACK1 rev 3838). Check dynamic port-max value. Fix JackCoreMidiDriver::ReadProcAux when ring buffer is full (thanks Devin Anderson). Josh Green ALSA driver capture only patch. When threads are cancelled, the exception has to be rethrown. Use a QUIT notification to properly quit the server channel, the server channel thread can then be 'stopped' instead of 'canceled'. Mario Lang alsa_io time calculation overflow patch. Shared memory manager was calling abort in case of fatal error, now return an error in caller. Change JackEngineProfiling and JackAudioAdapterInterface gnuplot scripts to output SVG instead of PDF.
1.9.6 : Improve JackCoreAudioDriver and JackCoreAudioAdapter : when no devices are described, takes default input and output and aggregate them.Correct JackGraphManager::DeactivatePort. Correct JackMachServerChannel::Execute : keep running even in error cases. Raise JACK_PROTOCOL_VERSION number. Arnold Krille firewire patch. Raise JACK_DRIVER_PARAM_STRING_MAX and JACK_PARAM_STRING_MAX to 127 otherwise some audio drivers cannot be loaded on OSX. Fix some file header to have library side code use LGPL. On Windows, now use TRE library for regexp (BSD license instead of GPL license). ffado-portname-sync.patch from ticket #163 applied. Remove call to exit in library code. Make jack_connect/jack_disconnect wait for effective port connection/disconnection. Add tests to validate intclient.h API. On Linux, inter-process synchronization primitive switched to POSIX semaphore. In JackCoreAudioDriver, move code called in MeasureCallback to be called once in IO thread. David Garcia Garzon netone patch. Fix from Fernando Lopez-Lezcano for compilation on fc13. Fix JackPosixSemaphore::TimedWait : same behavior as JackPosixSemaphore::Wait regarding EINTR. David Garcia Garzon unused_pkt_buf_field_jack2 netone patch. Arnold Krille firewire snooping patch. Jan Engelhardt patch for get_cycles on SPARC. Adrian Knoth hurd.patch, kfreebsd-fix.patch and alpha_ia64-sigsegv.patch from ticket 177. Adrian Knoth fix for linux cycle.h (ticket 188). In JackCoreAudioDriver, fix an issue when no value is given for input.
This is a work in progress but the implementation is now stable enough to be tested. jackdmp has been used successfully with the following applications : Ardour, Hydrogen, Jamin, Qjackctl, Jack-Rack, SooperLooper, AlsaPlayer...
......
......@@ -108,8 +108,8 @@ extern "C"
JackPortConnectCallback
connect_callback, void *arg);
EXPORT int jack_set_port_rename_callback (jack_client_t *,
JackPortRenameCallback
rename_callback, void *arg);
JackPortRenameCallback
rename_callback, void *arg);
EXPORT int jack_set_graph_order_callback (jack_client_t *,
JackGraphOrderCallback graph_callback,
void *);
......@@ -217,7 +217,7 @@ extern "C"
EXPORT int jack_client_create_thread (jack_client_t* client,
pthread_t *thread,
int priority,
int realtime, // boolean
int realtime, // boolean
thread_routine routine,
void *arg);
EXPORT int jack_drop_real_time_scheduling (pthread_t thread);
......@@ -1686,7 +1686,7 @@ EXPORT int jack_acquire_real_time_scheduling(pthread_t thread, int priority)
EXPORT int jack_client_create_thread(jack_client_t* client,
pthread_t *thread,
int priority,
int realtime, /* boolean */
int realtime, /* boolean */
thread_routine routine,
void *arg)
{
......@@ -1766,8 +1766,8 @@ EXPORT jack_intclient_t jack_internal_client_handle(jack_client_t* ext_client, c
return 0;
} else {
jack_status_t my_status;
if (status == NULL) /* no status from caller? */
status = &my_status; /* use local status word */
if (status == NULL) /* no status from caller? */
status = &my_status; /* use local status word */
*status = (jack_status_t)0;
return client->InternalClientHandle(client_name, status);
}
......@@ -1786,8 +1786,8 @@ EXPORT jack_intclient_t jack_internal_client_load_aux(jack_client_t* ext_client,
jack_varargs_t va;
jack_status_t my_status;
if (status == NULL) /* no status from caller? */
status = &my_status; /* use local status word */
if (status == NULL) /* no status from caller? */
status = &my_status; /* use local status word */
*status = (jack_status_t)0;
/* validate parameters */
......@@ -1859,3 +1859,129 @@ EXPORT void jack_free(void* ptr)
free(ptr);
}
}
// session.h
EXPORT int jack_set_session_callback(jack_client_t* ext_client, JackSessionCallback session_callback, void* arg)
{
#ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_set_session_callback");
#endif
JackClient* client = (JackClient*)ext_client;
jack_log("jack_set_session_callback ext_client %x client %x ", ext_client, client);
if (client == NULL) {
jack_error("jack_set_session_callback called with a NULL client");
return -1;
} else {
return client->SetSessionCallback(session_callback, arg);
}
}
EXPORT jack_session_command_t *jack_session_notify(jack_client_t* ext_client, const char* target, jack_session_event_type_t ev_type, const char *path)
{
#ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_session_notify");
#endif
JackClient* client = (JackClient*)ext_client;
jack_log("jack_session_notify ext_client %x client %x ", ext_client, client);
if (client == NULL) {
jack_error("jack_session_notify called with a NULL client");
return NULL;
} else {
return client->SessionNotify(target, ev_type, path);
}
}
EXPORT int jack_session_reply(jack_client_t *ext_client, jack_session_event_t *event)
{
#ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_session_reply");
#endif
JackClient* client = (JackClient*)ext_client;
jack_log("jack_session_reply ext_client %x client %x ", ext_client, client);
if (client == NULL) {
jack_error("jack_session_reply called with a NULL client");
return -1;
} else {
return client->SessionReply(event);
}
}
EXPORT void jack_session_event_free(jack_session_event_t* ev)
{
if (ev) {
if (ev->session_dir)
free((void *)ev->session_dir);
if (ev->client_uuid)
free((void *)ev->client_uuid);
if (ev->command_line)
free(ev->command_line);
free(ev);
}
}
EXPORT char *jack_get_uuid_for_client_name( jack_client_t *ext_client, const char *client_name )
{
#ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_get_uuid_for_client_name");
#endif
JackClient* client = (JackClient*)ext_client;
jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
if (client == NULL) {
jack_error("jack_get_uuid_for_client_name called with a NULL client");
return NULL;
} else {
return client->GetUUIDForClientName(client_name);
}
}
EXPORT char *jack_get_client_name_by_uuid( jack_client_t *ext_client, const char *client_uuid )
{
#ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_get_client_name_by_uuid");
#endif
JackClient* client = (JackClient*)ext_client;
jack_log("jack_get_uuid_for_client_name ext_client %x client %x ", ext_client, client);
if (client == NULL) {
jack_error("jack_get_client_name_by_uuid called with a NULL client");
return NULL;
} else {
return client->GetClientNameForUUID(client_uuid);
}
}
EXPORT int jack_reserve_client_name( jack_client_t *ext_client, const char *name, const char *uuid )
{
#ifdef __CLIENTDEBUG__
JackGlobals::CheckContext("jack_reserve_client_name");
#endif
JackClient* client = (JackClient*)ext_client;
jack_log("jack_reserve_client_name ext_client %x client %x ", ext_client, client);
if (client == NULL) {
jack_error("jack_reserve_client_name called with a NULL client");
return -1;
} else {
return client->ReserveClientName(name, uuid);
}
}
EXPORT void jack_session_commands_free( jack_session_command_t *cmds )
{
if (!cmds)
return;
int i=0;
while(1) {
if (cmds[i].client_name)
free ((char *)cmds[i].client_name);
if (cmds[i].command)
free ((char *)cmds[i].command);
if (cmds[i].uuid)
free ((char *)cmds[i].uuid);
else
break;
i += 1;
}
free(cmds);
}
......@@ -195,7 +195,7 @@ int JackAudioDriver::ProcessNull()
ProcessGraphAsync();
}
// Keep end cycle time
// Keep end cycle time
JackDriver::CycleTakeEndTime();
WaitUntilNextCycle();
return 0;
......@@ -215,14 +215,14 @@ int JackAudioDriver::ProcessAsync()
{
// Read input buffers for the current cycle
if (Read() < 0) {
jack_error("JackAudioDriver::ProcessAsync: read error, skip cycle");
return 0; // Skip cycle, but continue processing...
jack_error("JackAudioDriver::ProcessAsync: read error, stopping...");
return -1;
}
// Write output buffers from the previous cycle
if (Write() < 0) {
jack_error("JackAudioDriver::ProcessAsync: write error, skip cycle");
return 0; // Skip cycle, but continue processing...
jack_error("JackAudioDriver::ProcessAsync: write error, stopping...");
return -1;
}
if (fIsMaster) {
......@@ -244,9 +244,9 @@ output buffers computed at the *current cycle* are used.
int JackAudioDriver::ProcessSync()
{
// Read input buffers for the current cycle
if (Read() < 0) {
jack_error("JackAudioDriver::ProcessSync: read error, skip cycle");
return 0; // Skip cycle, but continue processing...
if (Read() < 0) {
jack_error("JackAudioDriver::ProcessSync: read error, stopping...");
return -1;
}
if (fIsMaster) {
......@@ -255,10 +255,10 @@ int JackAudioDriver::ProcessSync()
fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable);
}
// Write output buffers for the current cycle
if (Write() < 0) {
jack_error("JackAudioDriver::ProcessSync: write error, skip cycle");
return 0; // Skip cycle, but continue processing...
// Write output buffers from the current cycle
if (Write() < 0) {
jack_error("JackAudioDriver::ProcessSync: write error, stopping...");
return -1;
}
// Keep end cycle time
......@@ -270,10 +270,10 @@ void JackAudioDriver::ProcessGraphAsync()
{
// fBeginDateUst is set in the "low level" layer, fEndDateUst is from previous cycle
if (!fEngine->Process(fBeginDateUst, fEndDateUst))
jack_error("JackAudioDriver::ProcessAsync Process error");
jack_error("JackAudioDriver::ProcessGraphAsync: Process error");
fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable);
if (ProcessSlaves() < 0)
jack_error("JackAudioDriver::ProcessAsync ProcessSlaves error");
jack_error("JackAudioDriver::ProcessGraphAsync: ProcessSlaves error");
}
void JackAudioDriver::ProcessGraphSync()
......@@ -282,11 +282,11 @@ void JackAudioDriver::ProcessGraphSync()
if (fEngine->Process(fBeginDateUst, fEndDateUst)) {
fGraphManager->ResumeRefNum(&fClientControl, fSynchroTable);
if (ProcessSlaves() < 0)
jack_error("JackAudioDriver::ProcessSync ProcessSlaves error, engine may now behave abnormally!!");
jack_error("JackAudioDriver::ProcessGraphSync: ProcessSlaves error, engine may now behave abnormally!!");
if (fGraphManager->SuspendRefNum(&fClientControl, fSynchroTable, DRIVER_TIMEOUT_FACTOR * fEngineControl->fTimeOutUsecs) < 0)
jack_error("JackAudioDriver::ProcessSync SuspendRefNum error, engine may now behave abnormally!!");
jack_error("JackAudioDriver::ProcessGraphSync: SuspendRefNum error, engine may now behave abnormally!!");
} else { // Graph not finished: do not activate it
jack_error("JackAudioDriver::ProcessSync: error");
jack_error("JackAudioDriver::ProcessGraphSync: Process error");
}
}
......
......@@ -21,6 +21,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#define __JackChannel__
#include "types.h"
#include "session.h"
namespace Jack
{
......@@ -49,7 +50,7 @@ class JackClientChannelInterface
{}
// Open the Server/Client connection
virtual int Open(const char* server_name, const char* name, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status)
virtual int Open(const char* server_name, const char* name, int uuid, char* name_res, JackClient* obj, jack_options_t options, jack_status_t* status)
{
return 0;
}
......@@ -73,9 +74,9 @@ class JackClientChannelInterface
return -1;
}
virtual void ClientCheck(const char* name, char* name_res, int protocol, int options, int* status, int* result)
virtual void ClientCheck(const char* name, int uuid, char* name_res, int protocol, int options, int* status, int* result)
{}
virtual void ClientOpen(const char* name, int pid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
virtual void ClientOpen(const char* name, int pid, int uuid, int* shared_engine, int* shared_client, int* shared_graph, int* result)
{}
virtual void ClientOpen(const char* name, int* ref, JackEngineControl** shared_engine, JackGraphManager** shared_manager, JackClientInterface* client, int* result)
{}
......@@ -120,12 +121,31 @@ class JackClientChannelInterface
virtual void InternalClientHandle(int refnum, const char* client_name, int* status, int* int_ref, int* result)
{}
virtual void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int* result)
virtual void InternalClientLoad(int refnum, const char* client_name, const char* so_name, const char* objet_data, int options, int* status, int* int_ref, int uuid, int* result)
{}
virtual void InternalClientUnload(int refnum, int int_ref, int* status, int* result)
{}
virtual void SessionNotify(int refnum, const char* target, jack_session_event_type_t type, const char *path, jack_session_command_t **result)
{}
virtual void SessionReply(int refnum, int *result)
{}
virtual void GetUUIDForClientName(int refnum, const char *client_name, char *uuid_res, int *result)
{}
virtual void GetClientNameForUUID(int refnum, const char *uuid, char *name_res, int *result)
{}
virtual void ReserveClientName(int refnum, const char *client_name, const char *uuid, int *result)
{}
virtual bool IsChannelThread()
{
return false;
}
};
}
......
......@@ -112,9 +112,9 @@ pthread_t JackClient::GetThreadID()
}
/*!
In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations.
The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations.
Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel.
In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations.
The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations.
Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel.
*/
void JackClient::SetupDriverSync(bool freewheel)
{
......@@ -170,7 +170,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync,
case kAddClient:
jack_log("JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name);
if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself
if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) { // Don't call the callback for the registering client itself
fClientRegistration(name, 1, fClientRegistrationArg);
}
break;
......@@ -272,6 +272,23 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync,
fInfoShutdown = NULL;
}
break;
case kSessionCallback:
jack_log("JackClient::kSessionCallback");
if (fSession) {
jack_session_event_t *event = (jack_session_event_t *) malloc( sizeof(jack_session_event_t) );
char uuid_buf[JACK_UUID_SIZE];
event->type = (jack_session_event_type_t) value1;
event->session_dir = strdup( message );
event->command_line = NULL;
event->flags = (jack_session_flags_t) 0;
snprintf( uuid_buf, sizeof(uuid_buf), "%d", GetClientControl()->fSessionID );
event->client_uuid = strdup( uuid_buf );
fImmediateSessionReply = false;
fSession(event, fSessionArg);
res = (fImmediateSessionReply) ? 1 : 2;
}
break;
}
}
......@@ -280,7 +297,7 @@ int JackClient::ClientNotify(int refnum, const char* name, int notify, int sync,
/*!
\brief We need to start thread before activating in the server, otherwise the FW driver
connected to the client may not be activated.
connected to the client may not be activated.
*/
int JackClient::Activate()
{
......@@ -410,7 +427,7 @@ inline void JackClient::ExecuteThread()
while (true) {
CycleWaitAux();
CycleSignalAux(CallProcessCallback());
}
}
}
inline jack_nframes_t JackClient::CycleWaitAux()
......@@ -981,6 +998,19 @@ int JackClient::SetProcessThread(JackThreadCallback fun, void *arg)
}
}
int JackClient::SetSessionCallback(JackSessionCallback callback, void *arg)
{
if (IsActive()) {
jack_error("You cannot set callbacks on an active client");
return -1;
} else {
GetClientControl()->fCallback[kSessionCallback] = (callback != NULL);
fSessionArg = arg;
fSession = callback;
return 0;
}
}
//------------------
// Internal clients
//------------------
......@@ -1027,9 +1057,8 @@ int JackClient::InternalClientLoad(const char* client_name, jack_options_t optio
return 0;
}
int int_ref = 0;
int result = -1;
fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (int*)status, &int_ref, &result);
int int_ref, result = -1;
fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (int*)status, &int_ref, -1, &result);
return int_ref;
}
......@@ -1039,6 +1068,71 @@ void JackClient::InternalClientUnload(int ref, jack_status_t* status)
fChannel->InternalClientUnload(GetClientControl()->fRefNum, ref, (int*)status, &result);
}
//------------------
// Session API
//------------------
jack_session_command_t *JackClient::SessionNotify( const char* target, jack_session_event_type_t type, const char* path )
{
jack_session_command_t *res;
fChannel->SessionNotify( GetClientControl()->fRefNum, target, type, path, &res );
return res;
}
int JackClient::SessionReply( jack_session_event_t *ev )
{
if (ev->command_line) {
strncpy( GetClientControl()->fSessionCommand, ev->command_line, sizeof(GetClientControl()->fSessionCommand) );
} else {
GetClientControl()->fSessionCommand[0] = '\0';
}
GetClientControl()->fSessionFlags = ev->flags;
jack_log( "JackClient::SessionReply... we are here" );
if (fChannel->IsChannelThread()) {
jack_log( "JackClient::SessionReply... in callback reply" );
fImmediateSessionReply = true;
return 0;
}
jack_log( "JackClient::SessionReply... out of cb" );
int res;
fChannel->SessionReply( GetClientControl()->fRefNum, &res);
return res;
}
char* JackClient::GetUUIDForClientName(const char* client_name)
{
char uuid_res[JACK_UUID_SIZE];
int result = -1;
fChannel->GetUUIDForClientName( GetClientControl()->fRefNum, client_name, uuid_res, &result);
if (result)
return NULL;
return strdup(uuid_res);
}
char* JackClient::GetClientNameForUUID(const char* uuid)
{
char name_res[JACK_CLIENT_NAME_SIZE + 1];
int result = -1;
fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result);
if (result)
return NULL;
return strdup(name_res);
}
int JackClient::ReserveClientName(const char *name, const char* uuid)
{
int result = -1;
fChannel->ReserveClientName( GetClientControl()->fRefNum, name, uuid, &result);
return result;
}
} // end of namespace
......@@ -28,6 +28,7 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "JackPlatformPlug.h"
#include "JackChannel.h"
#include "types.h"
#include "session.h"
#include "varargs.h"
#include <list>
......@@ -66,6 +67,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
JackTimebaseCallback fTimebase;
JackSyncCallback fSync;
JackThreadCallback fThreadFun;
JackSessionCallback fSession;
void* fProcessArg;
void* fGraphOrderArg;
......@@ -83,12 +85,15 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
void* fTimebaseArg;
void* fSyncArg;
void* fThreadFunArg;
void* fSessionArg;
char fServerName[64];
JackThread fThread; /*! Thread to execute the Process function */
detail::JackClientChannelInterface* fChannel;
JackSynchro* fSynchroTable;
std::list<jack_port_id_t> fPortList;
bool fImmediateSessionReply;
int StartThread();
void SetupDriverSync(bool freewheel);
......@@ -118,7 +123,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
JackClient(JackSynchro* table);
virtual ~JackClient();
virtual int Open(const char* server_name, const char* name, jack_options_t options, jack_status_t* status) = 0;
virtual int Open(const char* server_name, const char* name, int uuid, jack_options_t options, jack_status_t* status) = 0;
virtual int Close();
virtual JackGraphManager* GetGraphManager() const = 0;
......@@ -173,6 +178,7 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
virtual int SetPortRegistrationCallback(JackPortRegistrationCallback callback, void* arg);
virtual int SetPortConnectCallback(JackPortConnectCallback callback, void *arg);
virtual int SetPortRenameCallback(JackPortRenameCallback callback, void *arg);
virtual int SetSessionCallback(JackSessionCallback callback, void *arg);
// Internal clients
virtual char* GetInternalClientName(int ref);
......@@ -184,6 +190,13 @@ class JackClient : public JackClientInterface, public JackRunnableInterface
void CycleSignal(int status);
int SetProcessThread(JackThreadCallback fun, void *arg);
// Session api
virtual jack_session_command_t *SessionNotify(const char *target, jack_session_event_type_t type, const char *path);
virtual int SessionReply(jack_session_event_t *ev);
char* GetUUIDForClientName(const char* client_name);
char* GetClientNameForUUID(const char* uuid);
int ReserveClientName(const char *name, const char* uuid);
// JackRunnableInterface interface
bool Init();
bool Execute();
......
......@@ -26,6 +26,8 @@ Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
#include "JackSynchro.h"
#include "JackNotification.h"
#include "jack/session.h"