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():fThread(this)
45 JackClient::JackClient(JackSynchro* table):fThread(this)
47 fSynchroTable = table;
55 fClientRegistration = NULL;
57 fPortRegistration = NULL;
67 fGraphOrderArg = NULL;
70 fInfoShutdownArg = NULL;
72 fBufferSizeArg = NULL;
74 fClientRegistrationArg = NULL;
75 fPortRegistrationArg = NULL;
76 fPortConnectArg = NULL;
77 fPortRenameArg = NULL;
84 fSessionReply = kPendingSessionReply;
87 JackClient::~JackClient()
90 void JackClient::ShutDown(jack_status_t code,
const char* message)
96 fInfoShutdown(code, message, fInfoShutdownArg);
99 }
else if (fShutdown) {
100 fShutdown(fShutdownArg);
105 int JackClient::Close()
107 jack_log(
"JackClient::Close ref = %ld", GetClientControl()->fRefNum);
115 fChannel->ClientClose(GetClientControl()->fRefNum, &result);
118 assert(JackGlobals::fSynchroMutex);
119 JackGlobals::fSynchroMutex->Lock();
120 fSynchroTable[GetClientControl()->fRefNum].Disconnect();
121 JackGlobals::fSynchroMutex->Unlock();
122 JackGlobals::fClientTable[GetClientControl()->fRefNum] = NULL;
126 bool JackClient::IsActive()
128 return (GetClientControl()) ? GetClientControl()->fActive :
false;
131 jack_native_thread_t JackClient::GetThreadID()
133 return fThread.GetThreadID();
143 if (!freewheel && !GetEngineControl()->fSyncMode) {
144 jack_log(
"JackClient::SetupDriverSync driver sem in flush mode");
145 for (
int i = 0; i < GetEngineControl()->fDriverNum; i++) {
146 fSynchroTable[i].SetFlush(
true);
149 jack_log(
"JackClient::SetupDriverSync driver sem in normal mode");
150 for (
int i = 0; i < GetEngineControl()->fDriverNum; i++) {
151 fSynchroTable[i].SetFlush(
false);
165 int JackClient::ClientNotify(
int refnum,
const char* name,
int notify,
int sync,
const char* message,
int value1,
int value2)
169 jack_log(
"JackClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify);
175 res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
179 res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
182 case kActivateClient:
183 jack_log(
"JackClient::kActivateClient name = %s ref = %ld ", name, refnum);
197 jack_log(
"JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name);
198 if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) {
199 fClientRegistration(name, 1, fClientRegistrationArg);
204 jack_log(
"JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName, name);
205 if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) {
206 fClientRegistration(name, 0, fClientRegistrationArg);
210 case kBufferSizeCallback:
211 jack_log(
"JackClient::kBufferSizeCallback buffer_size = %ld", value1);
213 res = fBufferSize(value1, fBufferSizeArg);
217 case kSampleRateCallback:
218 jack_log(
"JackClient::kSampleRateCallback sample_rate = %ld", value1);
220 res = fSampleRate(value1, fSampleRateArg);
224 case kGraphOrderCallback:
225 jack_log(
"JackClient::kGraphOrderCallback");
227 res = fGraphOrder(fGraphOrderArg);
231 case kStartFreewheelCallback:
232 jack_log(
"JackClient::kStartFreewheel");
233 SetupDriverSync(
true);
235 if (fThread.GetStatus() == JackThread::kRunning) {
236 fThread.DropRealTime();
239 fFreewheel(1, fFreewheelArg);
243 case kStopFreewheelCallback:
244 jack_log(
"JackClient::kStopFreewheel");
245 SetupDriverSync(
false);
247 fFreewheel(0, fFreewheelArg);
250 if (GetEngineControl()->fRealTime && fThread.GetStatus() == JackThread::kRunning) {
251 if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) {
252 jack_error(
"JackClient::AcquireRealTime error");
257 case kPortRegistrationOnCallback:
258 jack_log(
"JackClient::kPortRegistrationOn port_index = %ld", value1);
259 if (fPortRegistration) {
260 fPortRegistration(value1, 1, fPortRegistrationArg);
264 case kPortRegistrationOffCallback:
265 jack_log(
"JackClient::kPortRegistrationOff port_index = %ld ", value1);
266 if (fPortRegistration) {
267 fPortRegistration(value1, 0, fPortRegistrationArg);
271 case kPortConnectCallback:
272 jack_log(
"JackClient::kPortConnectCallback src = %ld dst = %ld", value1, value2);
274 fPortConnect(value1, value2, 1, fPortConnectArg);
278 case kPortDisconnectCallback:
279 jack_log(
"JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1, value2);
281 fPortConnect(value1, value2, 0, fPortConnectArg);
285 case kPortRenameCallback:
286 jack_log(
"JackClient::kPortRenameCallback port = %ld", value1);
288 fPortRename(value1, message, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg);
293 jack_log(
"JackClient::kXRunCallback");
295 res = fXrun(fXrunArg);
299 case kShutDownCallback:
300 jack_log(
"JackClient::kShutDownCallback");
301 ShutDown(jack_status_t(value1), message);
304 case kSessionCallback:
305 jack_log(
"JackClient::kSessionCallback");
308 char uuid_buf[JACK_UUID_SIZE];
309 event->
type = (jack_session_event_type_t)value1;
310 event->session_dir = strdup(message);
311 event->command_line = NULL;
313 snprintf(uuid_buf,
sizeof(uuid_buf),
"%d", GetClientControl()->fSessionID);
314 event->client_uuid = strdup(uuid_buf);
315 fSessionReply = kPendingSessionReply;
317 fSession(event, fSessionArg);
322 case kLatencyCallback:
323 res = HandleLatencyCallback(value1);
331 int JackClient::HandleLatencyCallback(
int status)
333 jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency;
339 list<jack_port_id_t>::iterator it;
341 for (it = fPortList.begin(); it != fPortList.end(); it++) {
342 JackPort* port = GetGraphManager()->GetPort(*it);
343 if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) {
344 GetGraphManager()->RecalculateLatency(*it, mode);
346 if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) {
347 GetGraphManager()->RecalculateLatency(*it, mode);
357 if (mode == JackPlaybackLatency) {
360 for (it = fPortList.begin(); it != fPortList.end(); it++) {
361 JackPort* port = GetGraphManager()->GetPort(*it);
362 if (port->GetFlags() & JackPortIsOutput) {
364 port->GetLatencyRange(mode, &other_latency);
365 if (other_latency.
max > latency.
max) {
366 latency.
max = other_latency.
max;
368 if (other_latency.
min < latency.
min) {
369 latency.
min = other_latency.
min;
374 if (latency.
min == UINT32_MAX) {
380 for (it = fPortList.begin(); it != fPortList.end(); it++) {
381 JackPort* port = GetGraphManager()->GetPort(*it);
382 if (port->GetFlags() & JackPortIsInput) {
383 port->SetLatencyRange(mode, &latency);
387 if (mode == JackCaptureLatency) {
390 for (it = fPortList.begin(); it != fPortList.end(); it++) {
391 JackPort* port = GetGraphManager()->GetPort(*it);
392 if (port->GetFlags() & JackPortIsInput) {
394 port->GetLatencyRange(mode, &other_latency);
395 if (other_latency.
max > latency.
max) {
396 latency.
max = other_latency.
max;
398 if (other_latency.
min < latency.
min) {
399 latency.
min = other_latency.
min;
404 if (latency.
min == UINT32_MAX) {
410 for (it = fPortList.begin(); it != fPortList.end(); it++) {
411 JackPort* port = GetGraphManager()->GetPort(*it);
412 if (port->GetFlags() & JackPortIsOutput) {
413 port->SetLatencyRange(mode, &latency);
423 fLatency(mode, fLatencyArg);
440 if (StartThread() < 0) {
449 GetClientControl()->fActive =
true;
452 GetClientControl()->fTransportSync =
true;
453 GetClientControl()->fTransportTimebase =
true;
456 GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime();
457 fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result);
471 GetClientControl()->fActive =
false;
474 GetClientControl()->fTransportSync =
false;
475 GetClientControl()->fTransportTimebase =
false;
479 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
480 jack_log(
"JackClient::Deactivate res = %ld", result);
493 void JackClient::InitAux()
496 jack_log(
"JackClient::Init calling client thread init callback");
513 jack_log(
"JackClient::kBufferSizeCallback buffer_size = %ld", GetEngineControl()->fBufferSize);
515 fBufferSize(GetEngineControl()->fBufferSize, fBufferSizeArg);
522 if (!jack_tls_set(JackGlobals::fRealTimeThread,
this)) {
523 jack_error(
"Failed to set thread realtime key");
527 if (GetEngineControl()->fRealTime) {
528 set_threaded_log_function();
535 void JackClient::SetupRealTime()
537 jack_log(
"JackClient::Init : period = %ld computation = %ld constraint = %ld",
538 long(int64_t(GetEngineControl()->fPeriod) / 1000.0f),
539 long(int64_t(GetEngineControl()->fComputation) / 1000.0f),
540 long(int64_t(GetEngineControl()->fConstraint) / 1000.0f));
543 fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
545 if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) {
546 jack_error(
"JackClient::AcquireSelfRealTime error");
550 int JackClient::StartThread()
552 if (fThread.StartSync() < 0) {
570 fThreadFun(fThreadFunArg);
577 void JackClient::DummyCycle()
583 inline void JackClient::ExecuteThread()
587 CycleSignalAux(CallProcessCallback());
591 inline jack_nframes_t JackClient::CycleWaitAux()
596 CallSyncCallbackAux();
597 return GetEngineControl()->fBufferSize;
600 inline void JackClient::CycleSignalAux(
int status)
603 CallTimebaseCallbackAux();
611 jack_nframes_t JackClient::CycleWait()
613 return CycleWaitAux();
616 void JackClient::CycleSignal(
int status)
618 CycleSignalAux(status);
621 inline int JackClient::CallProcessCallback()
623 return (fProcess != NULL) ? fProcess(GetEngineControl()->fBufferSize, fProcessArg) : 0;
626 inline bool JackClient::WaitSync()
629 if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable, 0x7FFFFFFF) < 0) {
637 inline void JackClient::SignalSync()
640 if (GetGraphManager()->ResumeRefNum(GetClientControl(), fSynchroTable) < 0) {
645 inline void JackClient::End()
647 jack_log(
"JackClient::Execute end name = %s", GetClientControl()->fName);
650 fThread.DropSelfRealTime();
651 GetClientControl()->fActive =
false;
652 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
656 inline void JackClient::Error()
658 jack_error(
"JackClient::Execute error name = %s", GetClientControl()->fName);
661 fThread.DropSelfRealTime();
662 GetClientControl()->fActive =
false;
663 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
664 ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE);
672 int JackClient::PortRegister(
const char* port_name,
const char* port_type,
unsigned long flags,
unsigned long buffer_size)
675 string port_short_name_str = string(port_name);
676 if (port_short_name_str.size() == 0) {
682 string port_full_name_str = string(GetClientControl()->fName) + string(
":") + port_short_name_str;
683 if (port_full_name_str.size() >= REAL_JACK_PORT_NAME_SIZE) {
684 jack_error(
"\"%s:%s\" is too long to be used as a JACK port name.\n"
685 "Please use %lu characters or less",
686 GetClientControl()->fName,
688 JACK_PORT_NAME_SIZE - 1);
693 jack_port_id_t port_index = NO_PORT;
694 fChannel->PortRegister(GetClientControl()->fRefNum, port_full_name_str.c_str(), port_type, flags, buffer_size, &port_index, &result);
697 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);
698 fPortList.push_back(port_index);
705 int JackClient::PortUnRegister(jack_port_id_t port_index)
707 jack_log(
"JackClient::PortUnRegister port_index = %ld", port_index);
708 list<jack_port_id_t>::iterator it = find(fPortList.begin(), fPortList.end(), port_index);
710 if (it != fPortList.end()) {
713 fChannel->PortUnRegister(GetClientControl()->fRefNum, port_index, &result);
716 jack_error(
"unregistering a port %ld that is not own by the client", port_index);
721 int JackClient::PortConnect(
const char* src,
const char* dst)
723 jack_log(
"JackClient::Connect src = %s dst = %s", src, dst);
724 if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
725 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
728 if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
729 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
733 fChannel->PortConnect(GetClientControl()->fRefNum, src, dst, &result);
737 int JackClient::PortDisconnect(
const char* src,
const char* dst)
739 jack_log(
"JackClient::Disconnect src = %s dst = %s", src, dst);
740 if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
741 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
744 if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
745 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
749 fChannel->PortDisconnect(GetClientControl()->fRefNum, src, dst, &result);
753 int JackClient::PortDisconnect(jack_port_id_t src)
755 jack_log(
"JackClient::PortDisconnect src = %ld", src);
757 fChannel->PortDisconnect(GetClientControl()->fRefNum, src, ALL_PORTS, &result);
761 int JackClient::PortIsMine(jack_port_id_t port_index)
763 JackPort* port = GetGraphManager()->GetPort(port_index);
764 return GetClientControl()->fRefNum == port->GetRefNum();
767 int JackClient::PortRename(jack_port_id_t port_index,
const char* name)
770 fChannel->PortRename(GetClientControl()->fRefNum, port_index, name, &result);
778 int JackClient::SetBufferSize(jack_nframes_t buffer_size)
781 fChannel->SetBufferSize(buffer_size, &result);
785 int JackClient::SetFreeWheel(
int onoff)
788 fChannel->SetFreewheel(onoff, &result);
792 int JackClient::ComputeTotalLatencies()
795 fChannel->ComputeTotalLatencies(&result);
803 inline int JackClient::ActivateAux()
806 if (IsActive() && fThread.GetStatus() != JackThread::kRunning) {
808 jack_log(
"JackClient::ActivateAux");
811 if (StartThread() < 0) {
816 GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime();
817 fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result);
825 int JackClient::ReleaseTimebase()
828 fChannel->ReleaseTimebase(GetClientControl()->fRefNum, &result);
830 GetClientControl()->fTransportTimebase =
false;
838 int JackClient::SetSyncCallback(JackSyncCallback sync_callback,
void* arg)
840 GetClientControl()->fTransportSync = (fSync != NULL);
842 fSync = sync_callback;
843 return ActivateAux();
846 int JackClient::SetTimebaseCallback(
int conditional, JackTimebaseCallback timebase_callback,
void* arg)
849 fChannel->SetTimebaseCallback(GetClientControl()->fRefNum, conditional, &result);
852 GetClientControl()->fTransportTimebase =
true;
853 fTimebase = timebase_callback;
855 return ActivateAux();
863 int JackClient::SetSyncTimeout(jack_time_t timeout)
865 GetEngineControl()->fTransport.SetSyncTimeout(timeout);
871 void JackClient::TransportLocate(jack_nframes_t frame)
875 pos.
valid = (jack_position_bits_t)0;
876 jack_log(
"JackClient::TransportLocate pos = %ld", pos.
frame);
877 GetEngineControl()->fTransport.RequestNewPos(&pos);
883 jack_log(
"JackClient::TransportReposition pos = %ld", pos->
frame);
884 if (tmp.
valid & ~JACK_POSITION_MASK) {
887 GetEngineControl()->fTransport.RequestNewPos(&tmp);
892 jack_transport_state_t JackClient::TransportQuery(
jack_position_t* pos)
894 return GetEngineControl()->fTransport.Query(pos);
897 jack_nframes_t JackClient::GetCurrentTransportFrame()
899 return GetEngineControl()->fTransport.GetCurrentFrame();
903 void JackClient::TransportStart()
905 GetEngineControl()->fTransport.SetCommand(TransportCommandStart);
909 void JackClient::TransportStop()
911 GetEngineControl()->fTransport.SetCommand(TransportCommandStop);
917 void JackClient::CallSyncCallback()
919 CallSyncCallbackAux();
922 inline void JackClient::CallSyncCallbackAux()
924 if (GetClientControl()->fTransportSync) {
926 JackTransportEngine& transport = GetEngineControl()->fTransport;
928 jack_transport_state_t transport_state = transport.GetState();
931 if (fSync(transport_state, cur_pos, fSyncArg)) {
932 GetClientControl()->fTransportState = JackTransportRolling;
933 GetClientControl()->fTransportSync =
false;
936 GetClientControl()->fTransportState = JackTransportRolling;
937 GetClientControl()->fTransportSync =
false;
942 void JackClient::CallTimebaseCallback()
944 CallTimebaseCallbackAux();
947 inline void JackClient::CallTimebaseCallbackAux()
949 JackTransportEngine& transport = GetEngineControl()->fTransport;
953 transport.GetTimebaseMaster(master, unused);
955 if (GetClientControl()->fRefNum == master && fTimebase) {
957 jack_transport_state_t transport_state = transport.GetState();
960 if (GetClientControl()->fTransportTimebase) {
961 fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos,
true, fTimebaseArg);
962 GetClientControl()->fTransportTimebase =
false;
963 }
else if (transport_state == JackTransportRolling) {
964 fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos,
false, fTimebaseArg);
967 transport.WriteNextStateStop(1);
975 void JackClient::OnShutdown(JackShutdownCallback callback,
void *arg)
978 jack_error(
"You cannot set callbacks on an active client");
981 GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
983 fShutdown = callback;
987 void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback,
void *arg)
990 jack_error(
"You cannot set callbacks on an active client");
993 GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
994 fInfoShutdownArg = arg;
995 fInfoShutdown = callback;
999 int JackClient::SetProcessCallback(JackProcessCallback callback,
void *arg)
1002 jack_error(
"You cannot set callbacks on an active client");
1004 }
else if (fThreadFun) {
1005 jack_error (
"A thread callback has already been setup, both models cannot be used at the same time!");
1009 fProcess = callback;
1014 int JackClient::SetXRunCallback(JackXRunCallback callback,
void *arg)
1017 jack_error(
"You cannot set callbacks on an active client");
1020 GetClientControl()->fCallback[kXRunCallback] = (callback != NULL);
1027 int JackClient::SetInitCallback(JackThreadInitCallback callback,
void *arg)
1030 jack_error(
"You cannot set callbacks on an active client");
1036 return JackMessageBuffer::fInstance->SetInitCallback(callback, arg);
1040 int JackClient::SetGraphOrderCallback(JackGraphOrderCallback callback,
void *arg)
1043 jack_error(
"You cannot set callbacks on an active client");
1046 GetClientControl()->fCallback[kGraphOrderCallback] = (callback != NULL);
1047 fGraphOrder = callback;
1048 fGraphOrderArg = arg;
1053 int JackClient::SetBufferSizeCallback(JackBufferSizeCallback callback,
void *arg)
1056 jack_error(
"You cannot set callbacks on an active client");
1059 GetClientControl()->fCallback[kBufferSizeCallback] = (callback != NULL);
1060 fBufferSizeArg = arg;
1061 fBufferSize = callback;
1066 int JackClient::SetSampleRateCallback(JackSampleRateCallback callback,
void *arg)
1069 jack_error(
"You cannot set callbacks on an active client");
1072 GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL);
1073 fSampleRateArg = arg;
1074 fSampleRate = callback;
1077 callback(GetEngineControl()->fSampleRate, arg);
1083 int JackClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback,
void* arg)
1086 jack_error(
"You cannot set callbacks on an active client");
1090 fClientRegistrationArg = arg;
1091 fClientRegistration = callback;
1096 int JackClient::SetFreewheelCallback(JackFreewheelCallback callback,
void *arg)
1099 jack_error(
"You cannot set callbacks on an active client");
1102 GetClientControl()->fCallback[kStartFreewheelCallback] = (callback != NULL);
1103 GetClientControl()->fCallback[kStopFreewheelCallback] = (callback != NULL);
1104 fFreewheelArg = arg;
1105 fFreewheel = callback;
1110 int JackClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback,
void *arg)
1113 jack_error(
"You cannot set callbacks on an active client");
1116 GetClientControl()->fCallback[kPortRegistrationOnCallback] = (callback != NULL);
1117 GetClientControl()->fCallback[kPortRegistrationOffCallback] = (callback != NULL);
1118 fPortRegistrationArg = arg;
1119 fPortRegistration = callback;
1124 int JackClient::SetPortConnectCallback(JackPortConnectCallback callback,
void *arg)
1127 jack_error(
"You cannot set callbacks on an active client");
1130 GetClientControl()->fCallback[kPortConnectCallback] = (callback != NULL);
1131 GetClientControl()->fCallback[kPortDisconnectCallback] = (callback != NULL);
1132 fPortConnectArg = arg;
1133 fPortConnect = callback;
1138 int JackClient::SetPortRenameCallback(JackPortRenameCallback callback,
void *arg)
1141 jack_error(
"You cannot set callbacks on an active client");
1144 GetClientControl()->fCallback[kPortRenameCallback] = (callback != NULL);
1145 fPortRenameArg = arg;
1146 fPortRename = callback;
1151 int JackClient::SetProcessThread(JackThreadCallback fun,
void *arg)
1154 jack_error(
"You cannot set callbacks on an active client");
1156 }
else if (fProcess) {
1157 jack_error(
"A process callback has already been setup, both models cannot be used at the same time!");
1161 fThreadFunArg = arg;
1169 jack_error(
"You cannot set callbacks on an active client");
1172 GetClientControl()->fCallback[kSessionCallback] = (callback != NULL);
1174 fSession = callback;
1179 int JackClient::SetLatencyCallback(JackLatencyCallback callback,
void *arg)
1182 jack_error(
"You cannot set callbacks on an active client");
1187 fLatency = callback;
1196 char* JackClient::GetInternalClientName(
int ref)
1198 char name_res[JACK_CLIENT_NAME_SIZE + 1];
1200 fChannel->GetInternalClientName(GetClientControl()->fRefNum, ref, name_res, &result);
1201 return (result < 0) ? NULL : strdup(name_res);
1204 int JackClient::InternalClientHandle(
const char* client_name, jack_status_t* status)
1206 int int_ref, result = -1;
1207 fChannel->InternalClientHandle(GetClientControl()->fRefNum, client_name, (
int*)status, &int_ref, &result);
1211 int JackClient::InternalClientLoad(
const char* client_name, jack_options_t options, jack_status_t* status,
jack_varargs_t* va)
1213 if (strlen(client_name) >= JACK_CLIENT_NAME_SIZE) {
1214 jack_error (
"\"%s\" is too long for a JACK client name.\n"
1215 "Please use %lu characters or less.",
1216 client_name, JACK_CLIENT_NAME_SIZE);
1220 if (va->load_name && (strlen(va->load_name) >= JACK_PATH_MAX)) {
1221 jack_error(
"\"%s\" is too long for a shared object name.\n"
1222 "Please use %lu characters or less.",
1223 va->load_name, JACK_PATH_MAX);
1224 int my_status1 = *status | (JackFailure | JackInvalidOption);
1225 *status = (jack_status_t)my_status1;
1229 if (va->load_init && (strlen(va->load_init) >= JACK_LOAD_INIT_LIMIT)) {
1230 jack_error (
"\"%s\" is too long for internal client init "
1231 "string.\nPlease use %lu characters or less.",
1232 va->load_init, JACK_LOAD_INIT_LIMIT);
1233 int my_status1 = *status | (JackFailure | JackInvalidOption);
1234 *status = (jack_status_t)my_status1;
1238 int int_ref, result = -1;
1239 fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (
int*)status, &int_ref, -1, &result);
1243 void JackClient::InternalClientUnload(
int ref, jack_status_t* status)
1246 fChannel->InternalClientUnload(GetClientControl()->fRefNum, ref, (
int*)status, &result);
1253 jack_session_command_t* JackClient::SessionNotify(
const char* target, jack_session_event_type_t type,
const char* path)
1256 fChannel->SessionNotify(GetClientControl()->fRefNum, target, type, path, &res);
1263 strncpy(GetClientControl()->fSessionCommand, ev->
command_line,
sizeof(GetClientControl()->fSessionCommand));
1265 GetClientControl()->fSessionCommand[0] =
'\0';
1268 GetClientControl()->fSessionFlags = ev->
flags;
1270 jack_log(
"JackClient::SessionReply... we are here");
1271 if (fChannel->IsChannelThread()) {
1272 jack_log(
"JackClient::SessionReply... in callback reply");
1274 fSessionReply = kImmediateSessionReply;
1278 jack_log(
"JackClient::SessionReply... out of cb");
1281 fChannel->SessionReply(GetClientControl()->fRefNum, &result);
1285 char* JackClient::GetUUIDForClientName(
const char* client_name)
1287 char uuid_res[JACK_UUID_SIZE];
1289 fChannel->GetUUIDForClientName(GetClientControl()->fRefNum, client_name, uuid_res, &result);
1290 return (result) ? NULL : strdup(uuid_res);
1293 char* JackClient::GetClientNameByUUID(
const char* uuid)
1295 char name_res[JACK_CLIENT_NAME_SIZE + 1];
1297 fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result);
1298 return (result) ? NULL : strdup(name_res);
1301 int JackClient::ReserveClientName(
const char* client_name,
const char* uuid)
1304 fChannel->ReserveClientName( GetClientControl()->fRefNum, client_name, uuid, &result);
1308 int JackClient::ClientHasSessionCallback(
const char* client_name)
1311 fChannel->ClientHasSessionCallback(client_name, &result);