21 #include "JackSystemDeps.h"
22 #include "JackGraphManager.h"
23 #include "JackClientControl.h"
24 #include "JackEngineControl.h"
25 #include "JackGlobals.h"
26 #include "JackChannel.h"
27 #include "JackTransportEngine.h"
28 #include "driver_interface.h"
29 #include "JackLibGlobals.h"
40 #define IsRealTime() ((fProcess != NULL) | (fThreadFun != NULL) | (fSync != NULL) | (fTimebase != NULL))
42 JackClient::JackClient(JackSynchro* table):fThread(this)
44 fSynchroTable = table;
52 fClientRegistration = NULL;
54 fPortRegistration = NULL;
64 fGraphOrderArg = NULL;
67 fInfoShutdownArg = NULL;
69 fBufferSizeArg = NULL;
71 fClientRegistrationArg = NULL;
72 fPortRegistrationArg = NULL;
73 fPortConnectArg = NULL;
74 fPortRenameArg = NULL;
81 fSessionReply = kPendingSessionReply;
84 JackClient::~JackClient()
87 void JackClient::ShutDown(jack_status_t code,
const char* message)
93 fInfoShutdown(code, message, fInfoShutdownArg);
96 }
else if (fShutdown) {
97 fShutdown(fShutdownArg);
102 int JackClient::Close()
104 jack_log(
"JackClient::Close ref = %ld", GetClientControl()->fRefNum);
112 fChannel->ClientClose(GetClientControl()->fRefNum, &result);
115 assert(JackGlobals::fSynchroMutex);
116 JackGlobals::fSynchroMutex->Lock();
117 fSynchroTable[GetClientControl()->fRefNum].Disconnect();
118 JackGlobals::fSynchroMutex->Unlock();
119 JackGlobals::fClientTable[GetClientControl()->fRefNum] = NULL;
123 bool JackClient::IsActive()
125 return (GetClientControl()) ? GetClientControl()->fActive :
false;
128 jack_native_thread_t JackClient::GetThreadID()
130 return fThread.GetThreadID();
140 if (!freewheel && !GetEngineControl()->fSyncMode) {
141 jack_log(
"JackClient::SetupDriverSync driver sem in flush mode");
142 for (
int i = 0; i < GetEngineControl()->fDriverNum; i++) {
143 fSynchroTable[i].SetFlush(
true);
146 jack_log(
"JackClient::SetupDriverSync driver sem in normal mode");
147 for (
int i = 0; i < GetEngineControl()->fDriverNum; i++) {
148 fSynchroTable[i].SetFlush(
false);
162 int JackClient::ClientNotify(
int refnum,
const char* name,
int notify,
int sync,
const char* message,
int value1,
int value2)
166 jack_log(
"JackClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify);
172 res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
176 res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
179 case kActivateClient:
180 jack_log(
"JackClient::kActivateClient name = %s ref = %ld ", name, refnum);
194 jack_log(
"JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name);
195 if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) {
196 fClientRegistration(name, 1, fClientRegistrationArg);
201 jack_log(
"JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName, name);
202 if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) {
203 fClientRegistration(name, 0, fClientRegistrationArg);
207 case kBufferSizeCallback:
208 jack_log(
"JackClient::kBufferSizeCallback buffer_size = %ld", value1);
210 res = fBufferSize(value1, fBufferSizeArg);
214 case kSampleRateCallback:
215 jack_log(
"JackClient::kSampleRateCallback sample_rate = %ld", value1);
217 res = fSampleRate(value1, fSampleRateArg);
221 case kGraphOrderCallback:
222 jack_log(
"JackClient::kGraphOrderCallback");
224 res = fGraphOrder(fGraphOrderArg);
228 case kStartFreewheelCallback:
229 jack_log(
"JackClient::kStartFreewheel");
230 SetupDriverSync(
true);
232 if (fThread.GetStatus() == JackThread::kRunning) {
233 fThread.DropRealTime();
236 fFreewheel(1, fFreewheelArg);
240 case kStopFreewheelCallback:
241 jack_log(
"JackClient::kStopFreewheel");
242 SetupDriverSync(
false);
244 fFreewheel(0, fFreewheelArg);
247 if (GetEngineControl()->fRealTime && fThread.GetStatus() == JackThread::kRunning) {
248 if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) {
249 jack_error(
"JackClient::AcquireRealTime error");
254 case kPortRegistrationOnCallback:
255 jack_log(
"JackClient::kPortRegistrationOn port_index = %ld", value1);
256 if (fPortRegistration) {
257 fPortRegistration(value1, 1, fPortRegistrationArg);
261 case kPortRegistrationOffCallback:
262 jack_log(
"JackClient::kPortRegistrationOff port_index = %ld ", value1);
263 if (fPortRegistration) {
264 fPortRegistration(value1, 0, fPortRegistrationArg);
268 case kPortConnectCallback:
269 jack_log(
"JackClient::kPortConnectCallback src = %ld dst = %ld", value1, value2);
271 fPortConnect(value1, value2, 1, fPortConnectArg);
275 case kPortDisconnectCallback:
276 jack_log(
"JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1, value2);
278 fPortConnect(value1, value2, 0, fPortConnectArg);
282 case kPortRenameCallback:
283 jack_log(
"JackClient::kPortRenameCallback port = %ld", value1);
285 fPortRename(value1, message, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg);
290 jack_log(
"JackClient::kXRunCallback");
292 res = fXrun(fXrunArg);
296 case kShutDownCallback:
297 jack_log(
"JackClient::kShutDownCallback");
298 ShutDown(jack_status_t(value1), message);
301 case kSessionCallback:
302 jack_log(
"JackClient::kSessionCallback");
305 char uuid_buf[JACK_UUID_SIZE];
306 event->
type = (jack_session_event_type_t)value1;
307 event->session_dir = strdup(message);
308 event->command_line = NULL;
310 snprintf(uuid_buf,
sizeof(uuid_buf),
"%d", GetClientControl()->fSessionID);
311 event->client_uuid = strdup(uuid_buf);
312 fSessionReply = kPendingSessionReply;
314 fSession(event, fSessionArg);
319 case kLatencyCallback:
320 res = HandleLatencyCallback(value1);
328 int JackClient::HandleLatencyCallback(
int status)
330 jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency;
336 list<jack_port_id_t>::iterator it;
338 for (it = fPortList.begin(); it != fPortList.end(); it++) {
339 JackPort* port = GetGraphManager()->GetPort(*it);
340 if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) {
341 GetGraphManager()->RecalculateLatency(*it, mode);
343 if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) {
344 GetGraphManager()->RecalculateLatency(*it, mode);
354 if (mode == JackPlaybackLatency) {
357 for (it = fPortList.begin(); it != fPortList.end(); it++) {
358 JackPort* port = GetGraphManager()->GetPort(*it);
359 if (port->GetFlags() & JackPortIsOutput) {
361 port->GetLatencyRange(mode, &other_latency);
362 if (other_latency.
max > latency.
max) {
363 latency.
max = other_latency.
max;
365 if (other_latency.
min < latency.
min) {
366 latency.
min = other_latency.
min;
371 if (latency.
min == UINT32_MAX) {
377 for (it = fPortList.begin(); it != fPortList.end(); it++) {
378 JackPort* port = GetGraphManager()->GetPort(*it);
379 if (port->GetFlags() & JackPortIsInput) {
380 port->SetLatencyRange(mode, &latency);
384 if (mode == JackCaptureLatency) {
387 for (it = fPortList.begin(); it != fPortList.end(); it++) {
388 JackPort* port = GetGraphManager()->GetPort(*it);
389 if (port->GetFlags() & JackPortIsInput) {
391 port->GetLatencyRange(mode, &other_latency);
392 if (other_latency.
max > latency.
max) {
393 latency.
max = other_latency.
max;
395 if (other_latency.
min < latency.
min) {
396 latency.
min = other_latency.
min;
401 if (latency.
min == UINT32_MAX) {
407 for (it = fPortList.begin(); it != fPortList.end(); it++) {
408 JackPort* port = GetGraphManager()->GetPort(*it);
409 if (port->GetFlags() & JackPortIsOutput) {
410 port->SetLatencyRange(mode, &latency);
420 fLatency(mode, fLatencyArg);
437 if (StartThread() < 0) {
446 GetClientControl()->fActive =
true;
449 GetClientControl()->fTransportSync =
true;
450 GetClientControl()->fTransportTimebase =
true;
453 GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime();
454 fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result);
468 GetClientControl()->fActive =
false;
471 GetClientControl()->fTransportSync =
false;
472 GetClientControl()->fTransportTimebase =
false;
476 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
477 jack_log(
"JackClient::Deactivate res = %ld", result);
490 void JackClient::InitAux()
493 jack_log(
"JackClient::Init calling client thread init callback");
510 jack_log(
"JackClient::kBufferSizeCallback buffer_size = %ld", GetEngineControl()->fBufferSize);
512 fBufferSize(GetEngineControl()->fBufferSize, fBufferSizeArg);
519 if (!jack_tls_set(JackGlobals::fRealTimeThread,
this)) {
520 jack_error(
"Failed to set thread realtime key");
524 if (GetEngineControl()->fRealTime) {
525 set_threaded_log_function();
532 void JackClient::SetupRealTime()
534 jack_log(
"JackClient::Init : period = %ld computation = %ld constraint = %ld",
535 long(int64_t(GetEngineControl()->fPeriod) / 1000.0f),
536 long(int64_t(GetEngineControl()->fComputation) / 1000.0f),
537 long(int64_t(GetEngineControl()->fConstraint) / 1000.0f));
540 fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
542 if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) {
543 jack_error(
"JackClient::AcquireSelfRealTime error");
547 int JackClient::StartThread()
549 if (fThread.StartSync() < 0) {
567 fThreadFun(fThreadFunArg);
574 void JackClient::DummyCycle()
580 inline void JackClient::ExecuteThread()
584 CycleSignalAux(CallProcessCallback());
588 inline jack_nframes_t JackClient::CycleWaitAux()
593 CallSyncCallbackAux();
594 return GetEngineControl()->fBufferSize;
597 inline void JackClient::CycleSignalAux(
int status)
600 CallTimebaseCallbackAux();
608 jack_nframes_t JackClient::CycleWait()
610 return CycleWaitAux();
613 void JackClient::CycleSignal(
int status)
615 CycleSignalAux(status);
618 inline int JackClient::CallProcessCallback()
620 return (fProcess != NULL) ? fProcess(GetEngineControl()->fBufferSize, fProcessArg) : 0;
623 inline bool JackClient::WaitSync()
626 if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable, 0x7FFFFFFF) < 0) {
634 inline void JackClient::SignalSync()
637 if (GetGraphManager()->ResumeRefNum(GetClientControl(), fSynchroTable) < 0) {
642 inline void JackClient::End()
644 jack_log(
"JackClient::Execute end name = %s", GetClientControl()->fName);
647 fThread.DropSelfRealTime();
648 GetClientControl()->fActive =
false;
649 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
653 inline void JackClient::Error()
655 jack_error(
"JackClient::Execute error name = %s", GetClientControl()->fName);
658 fThread.DropSelfRealTime();
659 GetClientControl()->fActive =
false;
660 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
661 ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE);
669 int JackClient::PortRegister(
const char* port_name,
const char* port_type,
unsigned long flags,
unsigned long buffer_size)
672 string port_short_name_str = string(port_name);
673 if (port_short_name_str.size() == 0) {
679 string port_full_name_str = string(GetClientControl()->fName) + string(
":") + port_short_name_str;
680 if (port_full_name_str.size() >= REAL_JACK_PORT_NAME_SIZE) {
681 jack_error(
"\"%s:%s\" is too long to be used as a JACK port name.\n"
682 "Please use %lu characters or less",
683 GetClientControl()->fName,
685 JACK_PORT_NAME_SIZE - 1);
690 jack_port_id_t port_index = NO_PORT;
691 fChannel->PortRegister(GetClientControl()->fRefNum, port_full_name_str.c_str(), port_type, flags, buffer_size, &port_index, &result);
694 jack_log(
"JackClient::PortRegister ref = %ld name = %s type = %s port_index = %ld", GetClientControl()->fRefNum, port_full_name_str.c_str(), port_type, port_index);
695 fPortList.push_back(port_index);
702 int JackClient::PortUnRegister(jack_port_id_t port_index)
704 jack_log(
"JackClient::PortUnRegister port_index = %ld", port_index);
705 list<jack_port_id_t>::iterator it = find(fPortList.begin(), fPortList.end(), port_index);
707 if (it != fPortList.end()) {
710 fChannel->PortUnRegister(GetClientControl()->fRefNum, port_index, &result);
713 jack_error(
"unregistering a port %ld that is not own by the client", port_index);
718 int JackClient::PortConnect(
const char* src,
const char* dst)
720 jack_log(
"JackClient::Connect src = %s dst = %s", src, dst);
721 if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
722 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
725 if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
726 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
730 fChannel->PortConnect(GetClientControl()->fRefNum, src, dst, &result);
734 int JackClient::PortDisconnect(
const char* src,
const char* dst)
736 jack_log(
"JackClient::Disconnect src = %s dst = %s", src, dst);
737 if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
738 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
741 if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
742 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
746 fChannel->PortDisconnect(GetClientControl()->fRefNum, src, dst, &result);
750 int JackClient::PortDisconnect(jack_port_id_t src)
752 jack_log(
"JackClient::PortDisconnect src = %ld", src);
754 fChannel->PortDisconnect(GetClientControl()->fRefNum, src, ALL_PORTS, &result);
758 int JackClient::PortIsMine(jack_port_id_t port_index)
760 JackPort* port = GetGraphManager()->GetPort(port_index);
761 return GetClientControl()->fRefNum == port->GetRefNum();
764 int JackClient::PortRename(jack_port_id_t port_index,
const char* name)
767 fChannel->PortRename(GetClientControl()->fRefNum, port_index, name, &result);
775 int JackClient::SetBufferSize(jack_nframes_t buffer_size)
778 fChannel->SetBufferSize(buffer_size, &result);
782 int JackClient::SetFreeWheel(
int onoff)
785 fChannel->SetFreewheel(onoff, &result);
789 int JackClient::ComputeTotalLatencies()
792 fChannel->ComputeTotalLatencies(&result);
800 inline int JackClient::ActivateAux()
803 if (IsActive() && fThread.GetStatus() != JackThread::kRunning) {
805 jack_log(
"JackClient::ActivateAux");
808 if (StartThread() < 0) {
813 GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime();
814 fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result);
822 int JackClient::ReleaseTimebase()
825 fChannel->ReleaseTimebase(GetClientControl()->fRefNum, &result);
827 GetClientControl()->fTransportTimebase =
false;
835 int JackClient::SetSyncCallback(JackSyncCallback sync_callback,
void* arg)
837 GetClientControl()->fTransportSync = (fSync != NULL);
839 fSync = sync_callback;
840 return ActivateAux();
843 int JackClient::SetTimebaseCallback(
int conditional, JackTimebaseCallback timebase_callback,
void* arg)
846 fChannel->SetTimebaseCallback(GetClientControl()->fRefNum, conditional, &result);
849 GetClientControl()->fTransportTimebase =
true;
850 fTimebase = timebase_callback;
852 return ActivateAux();
860 int JackClient::SetSyncTimeout(jack_time_t timeout)
862 GetEngineControl()->fTransport.SetSyncTimeout(timeout);
868 void JackClient::TransportLocate(jack_nframes_t frame)
872 pos.
valid = (jack_position_bits_t)0;
873 jack_log(
"JackClient::TransportLocate pos = %ld", pos.
frame);
874 GetEngineControl()->fTransport.RequestNewPos(&pos);
880 jack_log(
"JackClient::TransportReposition pos = %ld", pos->
frame);
881 if (tmp.
valid & ~JACK_POSITION_MASK) {
884 GetEngineControl()->fTransport.RequestNewPos(&tmp);
889 jack_transport_state_t JackClient::TransportQuery(
jack_position_t* pos)
891 return GetEngineControl()->fTransport.Query(pos);
894 jack_nframes_t JackClient::GetCurrentTransportFrame()
896 return GetEngineControl()->fTransport.GetCurrentFrame();
900 void JackClient::TransportStart()
902 GetEngineControl()->fTransport.SetCommand(TransportCommandStart);
906 void JackClient::TransportStop()
908 GetEngineControl()->fTransport.SetCommand(TransportCommandStop);
914 void JackClient::CallSyncCallback()
916 CallSyncCallbackAux();
919 inline void JackClient::CallSyncCallbackAux()
921 if (GetClientControl()->fTransportSync) {
923 JackTransportEngine& transport = GetEngineControl()->fTransport;
925 jack_transport_state_t transport_state = transport.GetState();
928 if (fSync(transport_state, cur_pos, fSyncArg)) {
929 GetClientControl()->fTransportState = JackTransportRolling;
930 GetClientControl()->fTransportSync =
false;
933 GetClientControl()->fTransportState = JackTransportRolling;
934 GetClientControl()->fTransportSync =
false;
939 void JackClient::CallTimebaseCallback()
941 CallTimebaseCallbackAux();
944 inline void JackClient::CallTimebaseCallbackAux()
946 JackTransportEngine& transport = GetEngineControl()->fTransport;
950 transport.GetTimebaseMaster(master, unused);
952 if (GetClientControl()->fRefNum == master && fTimebase) {
954 jack_transport_state_t transport_state = transport.GetState();
957 if (GetClientControl()->fTransportTimebase) {
958 fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos,
true, fTimebaseArg);
959 GetClientControl()->fTransportTimebase =
false;
960 }
else if (transport_state == JackTransportRolling) {
961 fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos,
false, fTimebaseArg);
964 transport.WriteNextStateStop(1);
972 void JackClient::OnShutdown(JackShutdownCallback callback,
void *arg)
975 jack_error(
"You cannot set callbacks on an active client");
978 GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
980 fShutdown = callback;
984 void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback,
void *arg)
987 jack_error(
"You cannot set callbacks on an active client");
990 GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
991 fInfoShutdownArg = arg;
992 fInfoShutdown = callback;
996 int JackClient::SetProcessCallback(JackProcessCallback callback,
void *arg)
999 jack_error(
"You cannot set callbacks on an active client");
1001 }
else if (fThreadFun) {
1002 jack_error (
"A thread callback has already been setup, both models cannot be used at the same time!");
1006 fProcess = callback;
1011 int JackClient::SetXRunCallback(JackXRunCallback callback,
void *arg)
1014 jack_error(
"You cannot set callbacks on an active client");
1017 GetClientControl()->fCallback[kXRunCallback] = (callback != NULL);
1024 int JackClient::SetInitCallback(JackThreadInitCallback callback,
void *arg)
1027 jack_error(
"You cannot set callbacks on an active client");
1033 return JackMessageBuffer::fInstance->SetInitCallback(callback, arg);
1037 int JackClient::SetGraphOrderCallback(JackGraphOrderCallback callback,
void *arg)
1040 jack_error(
"You cannot set callbacks on an active client");
1043 GetClientControl()->fCallback[kGraphOrderCallback] = (callback != NULL);
1044 fGraphOrder = callback;
1045 fGraphOrderArg = arg;
1050 int JackClient::SetBufferSizeCallback(JackBufferSizeCallback callback,
void *arg)
1053 jack_error(
"You cannot set callbacks on an active client");
1056 GetClientControl()->fCallback[kBufferSizeCallback] = (callback != NULL);
1057 fBufferSizeArg = arg;
1058 fBufferSize = callback;
1063 int JackClient::SetSampleRateCallback(JackSampleRateCallback callback,
void *arg)
1066 jack_error(
"You cannot set callbacks on an active client");
1069 GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL);
1070 fSampleRateArg = arg;
1071 fSampleRate = callback;
1074 callback(GetEngineControl()->fSampleRate, arg);
1080 int JackClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback,
void* arg)
1083 jack_error(
"You cannot set callbacks on an active client");
1087 fClientRegistrationArg = arg;
1088 fClientRegistration = callback;
1093 int JackClient::SetFreewheelCallback(JackFreewheelCallback callback,
void *arg)
1096 jack_error(
"You cannot set callbacks on an active client");
1099 GetClientControl()->fCallback[kStartFreewheelCallback] = (callback != NULL);
1100 GetClientControl()->fCallback[kStopFreewheelCallback] = (callback != NULL);
1101 fFreewheelArg = arg;
1102 fFreewheel = callback;
1107 int JackClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback,
void *arg)
1110 jack_error(
"You cannot set callbacks on an active client");
1113 GetClientControl()->fCallback[kPortRegistrationOnCallback] = (callback != NULL);
1114 GetClientControl()->fCallback[kPortRegistrationOffCallback] = (callback != NULL);
1115 fPortRegistrationArg = arg;
1116 fPortRegistration = callback;
1121 int JackClient::SetPortConnectCallback(JackPortConnectCallback callback,
void *arg)
1124 jack_error(
"You cannot set callbacks on an active client");
1127 GetClientControl()->fCallback[kPortConnectCallback] = (callback != NULL);
1128 GetClientControl()->fCallback[kPortDisconnectCallback] = (callback != NULL);
1129 fPortConnectArg = arg;
1130 fPortConnect = callback;
1135 int JackClient::SetPortRenameCallback(JackPortRenameCallback callback,
void *arg)
1138 jack_error(
"You cannot set callbacks on an active client");
1141 GetClientControl()->fCallback[kPortRenameCallback] = (callback != NULL);
1142 fPortRenameArg = arg;
1143 fPortRename = callback;
1148 int JackClient::SetProcessThread(JackThreadCallback fun,
void *arg)
1151 jack_error(
"You cannot set callbacks on an active client");
1153 }
else if (fProcess) {
1154 jack_error(
"A process callback has already been setup, both models cannot be used at the same time!");
1158 fThreadFunArg = arg;
1166 jack_error(
"You cannot set callbacks on an active client");
1169 GetClientControl()->fCallback[kSessionCallback] = (callback != NULL);
1171 fSession = callback;
1176 int JackClient::SetLatencyCallback(JackLatencyCallback callback,
void *arg)
1179 jack_error(
"You cannot set callbacks on an active client");
1184 fLatency = callback;
1193 char* JackClient::GetInternalClientName(
int ref)
1195 char name_res[JACK_CLIENT_NAME_SIZE+1];
1197 fChannel->GetInternalClientName(GetClientControl()->fRefNum, ref, name_res, &result);
1198 return (result < 0) ? NULL : strdup(name_res);
1201 int JackClient::InternalClientHandle(
const char* client_name, jack_status_t* status)
1203 int int_ref, result = -1;
1204 fChannel->InternalClientHandle(GetClientControl()->fRefNum, client_name, (
int*)status, &int_ref, &result);
1208 int JackClient::InternalClientLoad(
const char* client_name, jack_options_t options, jack_status_t* status,
jack_varargs_t* va)
1210 if (strlen(client_name) >= JACK_CLIENT_NAME_SIZE) {
1211 jack_error (
"\"%s\" is too long for a JACK client name.\n"
1212 "Please use %lu characters or less.",
1213 client_name, JACK_CLIENT_NAME_SIZE);
1217 if (va->load_name && (strlen(va->load_name) >= JACK_PATH_MAX)) {
1218 jack_error(
"\"%s\" is too long for a shared object name.\n"
1219 "Please use %lu characters or less.",
1220 va->load_name, JACK_PATH_MAX);
1221 int my_status1 = *status | (JackFailure | JackInvalidOption);
1222 *status = (jack_status_t)my_status1;
1226 if (va->load_init && (strlen(va->load_init) >= JACK_LOAD_INIT_LIMIT)) {
1227 jack_error (
"\"%s\" is too long for internal client init "
1228 "string.\nPlease use %lu characters or less.",
1229 va->load_init, JACK_LOAD_INIT_LIMIT);
1230 int my_status1 = *status | (JackFailure | JackInvalidOption);
1231 *status = (jack_status_t)my_status1;
1235 int int_ref, result = -1;
1236 fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (
int*)status, &int_ref, -1, &result);
1240 void JackClient::InternalClientUnload(
int ref, jack_status_t* status)
1243 fChannel->InternalClientUnload(GetClientControl()->fRefNum, ref, (
int*)status, &result);
1250 jack_session_command_t* JackClient::SessionNotify(
const char* target, jack_session_event_type_t type,
const char* path)
1253 fChannel->SessionNotify(GetClientControl()->fRefNum, target, type, path, &res);
1260 strncpy(GetClientControl()->fSessionCommand, ev->
command_line,
sizeof(GetClientControl()->fSessionCommand));
1262 GetClientControl()->fSessionCommand[0] =
'\0';
1265 GetClientControl()->fSessionFlags = ev->
flags;
1267 jack_log(
"JackClient::SessionReply... we are here");
1268 if (fChannel->IsChannelThread()) {
1269 jack_log(
"JackClient::SessionReply... in callback reply");
1271 fSessionReply = kImmediateSessionReply;
1275 jack_log(
"JackClient::SessionReply... out of cb");
1278 fChannel->SessionReply(GetClientControl()->fRefNum, &result);
1282 char* JackClient::GetUUIDForClientName(
const char* client_name)
1284 char uuid_res[JACK_UUID_SIZE];
1286 fChannel->GetUUIDForClientName(GetClientControl()->fRefNum, client_name, uuid_res, &result);
1287 return (result) ? NULL : strdup(uuid_res);
1290 char* JackClient::GetClientNameByUUID(
const char* uuid)
1292 char name_res[JACK_CLIENT_NAME_SIZE + 1];
1294 fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result);
1295 return (result) ? NULL : strdup(name_res);
1298 int JackClient::ReserveClientName(
const char* client_name,
const char* uuid)
1301 fChannel->ReserveClientName( GetClientControl()->fRefNum, client_name, uuid, &result);
1305 int JackClient::ClientHasSessionCallback(
const char* client_name)
1308 fChannel->ClientHasSessionCallback(client_name, &result);