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;
62 fPropertyChange = NULL;
65 fGraphOrderArg = NULL;
68 fInfoShutdownArg = NULL;
70 fBufferSizeArg = NULL;
72 fClientRegistrationArg = NULL;
73 fPortRegistrationArg = NULL;
74 fPortConnectArg = NULL;
75 fPortRenameArg = NULL;
81 fPropertyChangeArg = NULL;
83 fSessionReply = kPendingSessionReply;
86 JackClient::~JackClient()
89 void JackClient::ShutDown(jack_status_t code,
const char* message)
95 fInfoShutdown(code, message, fInfoShutdownArg);
98 }
else if (fShutdown) {
99 fShutdown(fShutdownArg);
104 int JackClient::Close()
106 jack_log(
"JackClient::Close ref = %ld", GetClientControl()->fRefNum);
114 fChannel->ClientClose(GetClientControl()->fRefNum, &result);
117 assert(JackGlobals::fSynchroMutex);
118 JackGlobals::fSynchroMutex->Lock();
119 fSynchroTable[GetClientControl()->fRefNum].Disconnect();
120 JackGlobals::fSynchroMutex->Unlock();
121 JackGlobals::fClientTable[GetClientControl()->fRefNum] = NULL;
125 bool JackClient::IsActive()
127 return (GetClientControl()) ? GetClientControl()->fActive :
false;
130 jack_native_thread_t JackClient::GetThreadID()
132 return fThread.GetThreadID();
142 if (!freewheel && !GetEngineControl()->fSyncMode) {
143 jack_log(
"JackClient::SetupDriverSync driver sem in flush mode");
144 for (
int i = 0; i < GetEngineControl()->fDriverNum; i++) {
145 fSynchroTable[i].SetFlush(
true);
148 jack_log(
"JackClient::SetupDriverSync driver sem in normal mode");
149 for (
int i = 0; i < GetEngineControl()->fDriverNum; i++) {
150 fSynchroTable[i].SetFlush(
false);
164 int JackClient::ClientNotify(
int refnum,
const char* name,
int notify,
int sync,
const char* message,
int value1,
int value2)
168 jack_log(
"JackClient::ClientNotify ref = %ld name = %s notify = %ld", refnum, name, notify);
174 res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
178 res = ClientNotifyImp(refnum, name, notify, sync, message, value1, value2);
181 case kActivateClient:
182 jack_log(
"JackClient::kActivateClient name = %s ref = %ld ", name, refnum);
196 jack_log(
"JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName, name);
197 if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) {
198 fClientRegistration(name, 1, fClientRegistrationArg);
203 jack_log(
"JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName, name);
204 if (fClientRegistration && strcmp(GetClientControl()->fName, name) != 0) {
205 fClientRegistration(name, 0, fClientRegistrationArg);
209 case kBufferSizeCallback:
210 jack_log(
"JackClient::kBufferSizeCallback buffer_size = %ld", value1);
212 res = fBufferSize(value1, fBufferSizeArg);
216 case kSampleRateCallback:
217 jack_log(
"JackClient::kSampleRateCallback sample_rate = %ld", value1);
219 res = fSampleRate(value1, fSampleRateArg);
223 case kGraphOrderCallback:
224 jack_log(
"JackClient::kGraphOrderCallback");
226 res = fGraphOrder(fGraphOrderArg);
230 case kStartFreewheelCallback:
231 jack_log(
"JackClient::kStartFreewheel");
232 SetupDriverSync(
true);
234 if (fThread.GetStatus() == JackThread::kRunning) {
235 fThread.DropRealTime();
238 fFreewheel(1, fFreewheelArg);
242 case kStopFreewheelCallback:
243 jack_log(
"JackClient::kStopFreewheel");
244 SetupDriverSync(
false);
246 fFreewheel(0, fFreewheelArg);
249 if (GetEngineControl()->fRealTime && fThread.GetStatus() == JackThread::kRunning) {
250 if (fThread.AcquireRealTime(GetEngineControl()->fClientPriority) < 0) {
251 jack_error(
"JackClient::AcquireRealTime error");
256 case kPortRegistrationOnCallback:
257 jack_log(
"JackClient::kPortRegistrationOn port_index = %ld", value1);
258 if (fPortRegistration) {
259 fPortRegistration(value1, 1, fPortRegistrationArg);
263 case kPortRegistrationOffCallback:
264 jack_log(
"JackClient::kPortRegistrationOff port_index = %ld ", value1);
265 if (fPortRegistration) {
266 fPortRegistration(value1, 0, fPortRegistrationArg);
270 case kPortConnectCallback:
271 jack_log(
"JackClient::kPortConnectCallback src = %ld dst = %ld", value1, value2);
273 fPortConnect(value1, value2, 1, fPortConnectArg);
277 case kPortDisconnectCallback:
278 jack_log(
"JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1, value2);
280 fPortConnect(value1, value2, 0, fPortConnectArg);
284 case kPortRenameCallback:
285 jack_log(
"JackClient::kPortRenameCallback port = %ld", value1);
287 fPortRename(value1, message, GetGraphManager()->GetPort(value1)->GetName(), fPortRenameArg);
292 jack_log(
"JackClient::kXRunCallback");
294 res = fXrun(fXrunArg);
298 case kShutDownCallback:
299 jack_log(
"JackClient::kShutDownCallback");
300 ShutDown(jack_status_t(value1), message);
303 case kSessionCallback:
304 jack_log(
"JackClient::kSessionCallback");
307 char uuid_buf[JACK_UUID_STRING_SIZE];
308 event->
type = (jack_session_event_type_t)value1;
309 event->session_dir = strdup(message);
310 event->command_line = NULL;
312 jack_uuid_unparse(GetClientControl()->fSessionID, uuid_buf);
313 event->client_uuid = strdup(uuid_buf);
314 fSessionReply = kPendingSessionReply;
316 fSession(event, fSessionArg);
321 case kLatencyCallback:
322 res = HandleLatencyCallback(value1);
325 case kPropertyChangeCallback: {
327 jack_uuid_parse(name, &subject);
328 const char* key = message;
329 jack_property_change_t change = (jack_property_change_t)value1;
330 jack_log(
"JackClient::kPropertyChangeCallback subject = %x key = %s change = %x", subject, key, change);
332 fPropertyChange(subject, key, change, fPropertyChangeArg);
341 int JackClient::HandleLatencyCallback(
int status)
343 jack_latency_callback_mode_t mode = (status == 0) ? JackCaptureLatency : JackPlaybackLatency;
349 list<jack_port_id_t>::iterator it;
351 for (it = fPortList.begin(); it != fPortList.end(); it++) {
352 JackPort* port = GetGraphManager()->GetPort(*it);
353 if ((port->GetFlags() & JackPortIsOutput) && (mode == JackPlaybackLatency)) {
354 GetGraphManager()->RecalculateLatency(*it, mode);
356 if ((port->GetFlags() & JackPortIsInput) && (mode == JackCaptureLatency)) {
357 GetGraphManager()->RecalculateLatency(*it, mode);
367 if (mode == JackPlaybackLatency) {
370 for (it = fPortList.begin(); it != fPortList.end(); it++) {
371 JackPort* port = GetGraphManager()->GetPort(*it);
372 if (port->GetFlags() & JackPortIsOutput) {
374 port->GetLatencyRange(mode, &other_latency);
375 if (other_latency.
max > latency.
max) {
376 latency.
max = other_latency.
max;
378 if (other_latency.
min < latency.
min) {
379 latency.
min = other_latency.
min;
384 if (latency.
min == UINT32_MAX) {
390 for (it = fPortList.begin(); it != fPortList.end(); it++) {
391 JackPort* port = GetGraphManager()->GetPort(*it);
392 if (port->GetFlags() & JackPortIsInput) {
393 port->SetLatencyRange(mode, &latency);
397 if (mode == JackCaptureLatency) {
400 for (it = fPortList.begin(); it != fPortList.end(); it++) {
401 JackPort* port = GetGraphManager()->GetPort(*it);
402 if (port->GetFlags() & JackPortIsInput) {
404 port->GetLatencyRange(mode, &other_latency);
405 if (other_latency.
max > latency.
max) {
406 latency.
max = other_latency.
max;
408 if (other_latency.
min < latency.
min) {
409 latency.
min = other_latency.
min;
414 if (latency.
min == UINT32_MAX) {
420 for (it = fPortList.begin(); it != fPortList.end(); it++) {
421 JackPort* port = GetGraphManager()->GetPort(*it);
422 if (port->GetFlags() & JackPortIsOutput) {
423 port->SetLatencyRange(mode, &latency);
433 fLatency(mode, fLatencyArg);
450 if (StartThread() < 0) {
459 GetClientControl()->fActive =
true;
462 GetClientControl()->fTransportSync =
true;
463 GetClientControl()->fTransportTimebase =
true;
466 GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime();
467 fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result);
481 GetClientControl()->fActive =
false;
484 GetClientControl()->fTransportSync =
false;
485 GetClientControl()->fTransportTimebase =
false;
489 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
490 jack_log(
"JackClient::Deactivate res = %ld", result);
503 void JackClient::InitAux()
506 jack_log(
"JackClient::Init calling client thread init callback");
523 jack_log(
"JackClient::kBufferSizeCallback buffer_size = %ld", GetEngineControl()->fBufferSize);
525 fBufferSize(GetEngineControl()->fBufferSize, fBufferSizeArg);
532 if (!jack_tls_set(JackGlobals::fRealTimeThread,
this)) {
533 jack_error(
"Failed to set thread realtime key");
537 if (GetEngineControl()->fRealTime) {
538 set_threaded_log_function();
545 void JackClient::SetupRealTime()
547 jack_log(
"JackClient::Init : period = %ld computation = %ld constraint = %ld",
548 long(int64_t(GetEngineControl()->fPeriod) / 1000.0f),
549 long(int64_t(GetEngineControl()->fComputation) / 1000.0f),
550 long(int64_t(GetEngineControl()->fConstraint) / 1000.0f));
553 fThread.SetParams(GetEngineControl()->fPeriod, GetEngineControl()->fComputation, GetEngineControl()->fConstraint);
555 if (fThread.AcquireSelfRealTime(GetEngineControl()->fClientPriority) < 0) {
556 jack_error(
"JackClient::AcquireSelfRealTime error");
560 int JackClient::StartThread()
562 if (fThread.StartSync() < 0) {
580 fThreadFun(fThreadFunArg);
587 void JackClient::DummyCycle()
593 inline void JackClient::ExecuteThread()
597 CycleSignalAux(CallProcessCallback());
601 inline jack_nframes_t JackClient::CycleWaitAux()
606 CallSyncCallbackAux();
607 return GetEngineControl()->fBufferSize;
610 inline void JackClient::CycleSignalAux(
int status)
613 CallTimebaseCallbackAux();
621 jack_nframes_t JackClient::CycleWait()
623 return CycleWaitAux();
626 void JackClient::CycleSignal(
int status)
628 CycleSignalAux(status);
631 inline int JackClient::CallProcessCallback()
633 return (fProcess != NULL) ? fProcess(GetEngineControl()->fBufferSize, fProcessArg) : 0;
636 inline bool JackClient::WaitSync()
639 if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable, 0x7FFFFFFF) < 0) {
647 inline void JackClient::SignalSync()
650 if (GetGraphManager()->ResumeRefNum(GetClientControl(), fSynchroTable) < 0) {
655 inline void JackClient::End()
657 jack_log(
"JackClient::Execute end name = %s", GetClientControl()->fName);
660 fThread.DropSelfRealTime();
661 GetClientControl()->fActive =
false;
662 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
666 inline void JackClient::Error()
668 jack_error(
"JackClient::Execute error name = %s", GetClientControl()->fName);
671 fThread.DropSelfRealTime();
672 GetClientControl()->fActive =
false;
673 fChannel->ClientDeactivate(GetClientControl()->fRefNum, &result);
674 ShutDown(jack_status_t(JackFailure | JackServerError), JACK_SERVER_FAILURE);
682 int JackClient::PortRegister(
const char* port_name,
const char* port_type,
unsigned long flags,
unsigned long buffer_size)
685 string port_short_name_str = string(port_name);
686 if (port_short_name_str.size() == 0) {
692 string port_full_name_str = string(GetClientControl()->fName) + string(
":") + port_short_name_str;
693 if (port_full_name_str.size() >= REAL_JACK_PORT_NAME_SIZE) {
694 jack_error(
"\"%s:%s\" is too long to be used as a JACK port name.\n"
695 "Please use %lu characters or less",
696 GetClientControl()->fName,
698 JACK_PORT_NAME_SIZE - 1);
703 jack_port_id_t port_index = NO_PORT;
704 fChannel->PortRegister(GetClientControl()->fRefNum, port_full_name_str.c_str(), port_type, flags, buffer_size, &port_index, &result);
707 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);
708 fPortList.push_back(port_index);
715 int JackClient::PortUnRegister(jack_port_id_t port_index)
717 jack_log(
"JackClient::PortUnRegister port_index = %ld", port_index);
718 list<jack_port_id_t>::iterator it = find(fPortList.begin(), fPortList.end(), port_index);
720 if (it != fPortList.end()) {
723 fChannel->PortUnRegister(GetClientControl()->fRefNum, port_index, &result);
726 jack_error(
"unregistering a port %ld that is not own by the client", port_index);
731 int JackClient::PortConnect(
const char* src,
const char* dst)
733 jack_log(
"JackClient::Connect src = %s dst = %s", src, dst);
734 if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
735 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
738 if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
739 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", dst);
743 fChannel->PortConnect(GetClientControl()->fRefNum, src, dst, &result);
747 int JackClient::PortDisconnect(
const char* src,
const char* dst)
749 jack_log(
"JackClient::Disconnect src = %s dst = %s", src, dst);
750 if (strlen(src) >= REAL_JACK_PORT_NAME_SIZE) {
751 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", src);
754 if (strlen(dst) >= REAL_JACK_PORT_NAME_SIZE) {
755 jack_error(
"\"%s\" is too long to be used as a JACK port name.\n", dst);
759 fChannel->PortDisconnect(GetClientControl()->fRefNum, src, dst, &result);
763 int JackClient::PortDisconnect(jack_port_id_t src)
765 jack_log(
"JackClient::PortDisconnect src = %ld", src);
767 fChannel->PortDisconnect(GetClientControl()->fRefNum, src, ALL_PORTS, &result);
771 int JackClient::PortIsMine(jack_port_id_t port_index)
773 JackPort* port = GetGraphManager()->GetPort(port_index);
774 return GetClientControl()->fRefNum == port->GetRefNum();
777 int JackClient::PortRename(jack_port_id_t port_index,
const char* name)
780 fChannel->PortRename(GetClientControl()->fRefNum, port_index, name, &result);
788 int JackClient::SetBufferSize(jack_nframes_t buffer_size)
791 fChannel->SetBufferSize(buffer_size, &result);
795 int JackClient::SetFreeWheel(
int onoff)
798 fChannel->SetFreewheel(onoff, &result);
802 int JackClient::ComputeTotalLatencies()
805 fChannel->ComputeTotalLatencies(&result);
813 inline int JackClient::ActivateAux()
816 if (IsActive() && fThread.GetStatus() != JackThread::kRunning) {
818 jack_log(
"JackClient::ActivateAux");
821 if (StartThread() < 0) {
826 GetClientControl()->fCallback[kRealTimeCallback] = IsRealTime();
827 fChannel->ClientActivate(GetClientControl()->fRefNum, IsRealTime(), &result);
835 int JackClient::ReleaseTimebase()
838 fChannel->ReleaseTimebase(GetClientControl()->fRefNum, &result);
840 GetClientControl()->fTransportTimebase =
false;
848 int JackClient::SetSyncCallback(JackSyncCallback sync_callback,
void* arg)
850 GetClientControl()->fTransportSync = (fSync != NULL);
852 fSync = sync_callback;
853 return ActivateAux();
856 int JackClient::SetTimebaseCallback(
int conditional, JackTimebaseCallback timebase_callback,
void* arg)
859 fChannel->SetTimebaseCallback(GetClientControl()->fRefNum, conditional, &result);
862 GetClientControl()->fTransportTimebase =
true;
863 fTimebase = timebase_callback;
865 return ActivateAux();
873 int JackClient::SetSyncTimeout(jack_time_t timeout)
875 GetEngineControl()->fTransport.SetSyncTimeout(timeout);
881 void JackClient::TransportLocate(jack_nframes_t frame)
885 pos.
valid = (jack_position_bits_t)0;
886 jack_log(
"JackClient::TransportLocate pos = %ld", pos.
frame);
887 GetEngineControl()->fTransport.RequestNewPos(&pos);
893 jack_log(
"JackClient::TransportReposition pos = %ld", pos->
frame);
894 if (tmp.
valid & ~JACK_POSITION_MASK) {
897 GetEngineControl()->fTransport.RequestNewPos(&tmp);
902 jack_transport_state_t JackClient::TransportQuery(
jack_position_t* pos)
904 return GetEngineControl()->fTransport.Query(pos);
907 jack_nframes_t JackClient::GetCurrentTransportFrame()
909 return GetEngineControl()->fTransport.GetCurrentFrame();
913 void JackClient::TransportStart()
915 GetEngineControl()->fTransport.SetCommand(TransportCommandStart);
919 void JackClient::TransportStop()
921 GetEngineControl()->fTransport.SetCommand(TransportCommandStop);
927 void JackClient::CallSyncCallback()
929 CallSyncCallbackAux();
932 inline void JackClient::CallSyncCallbackAux()
934 if (GetClientControl()->fTransportSync) {
936 JackTransportEngine& transport = GetEngineControl()->fTransport;
938 jack_transport_state_t transport_state = transport.GetState();
941 if (fSync(transport_state, cur_pos, fSyncArg)) {
942 GetClientControl()->fTransportState = JackTransportRolling;
943 GetClientControl()->fTransportSync =
false;
946 GetClientControl()->fTransportState = JackTransportRolling;
947 GetClientControl()->fTransportSync =
false;
952 void JackClient::CallTimebaseCallback()
954 CallTimebaseCallbackAux();
957 inline void JackClient::CallTimebaseCallbackAux()
959 JackTransportEngine& transport = GetEngineControl()->fTransport;
963 transport.GetTimebaseMaster(master, unused);
965 if (GetClientControl()->fRefNum == master && fTimebase) {
967 jack_transport_state_t transport_state = transport.GetState();
970 if (GetClientControl()->fTransportTimebase) {
971 fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos,
true, fTimebaseArg);
972 GetClientControl()->fTransportTimebase =
false;
973 }
else if (transport_state == JackTransportRolling) {
974 fTimebase(transport_state, GetEngineControl()->fBufferSize, cur_pos,
false, fTimebaseArg);
977 transport.WriteNextStateStop(1);
985 void JackClient::OnShutdown(JackShutdownCallback callback,
void *arg)
988 jack_error(
"You cannot set callbacks on an active client");
991 GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
993 fShutdown = callback;
997 void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback,
void *arg)
1000 jack_error(
"You cannot set callbacks on an active client");
1003 GetClientControl()->fCallback[kShutDownCallback] = (callback != NULL);
1004 fInfoShutdownArg = arg;
1005 fInfoShutdown = callback;
1009 int JackClient::SetProcessCallback(JackProcessCallback callback,
void *arg)
1012 jack_error(
"You cannot set callbacks on an active client");
1014 }
else if (fThreadFun) {
1015 jack_error (
"A thread callback has already been setup, both models cannot be used at the same time!");
1019 fProcess = callback;
1024 int JackClient::SetXRunCallback(JackXRunCallback callback,
void *arg)
1027 jack_error(
"You cannot set callbacks on an active client");
1030 GetClientControl()->fCallback[kXRunCallback] = (callback != NULL);
1037 int JackClient::SetInitCallback(JackThreadInitCallback callback,
void *arg)
1040 jack_error(
"You cannot set callbacks on an active client");
1046 return JackMessageBuffer::fInstance->SetInitCallback(callback, arg);
1050 int JackClient::SetGraphOrderCallback(JackGraphOrderCallback callback,
void *arg)
1053 jack_error(
"You cannot set callbacks on an active client");
1056 GetClientControl()->fCallback[kGraphOrderCallback] = (callback != NULL);
1057 fGraphOrder = callback;
1058 fGraphOrderArg = arg;
1063 int JackClient::SetBufferSizeCallback(JackBufferSizeCallback callback,
void *arg)
1066 jack_error(
"You cannot set callbacks on an active client");
1069 GetClientControl()->fCallback[kBufferSizeCallback] = (callback != NULL);
1070 fBufferSizeArg = arg;
1071 fBufferSize = callback;
1076 int JackClient::SetSampleRateCallback(JackSampleRateCallback callback,
void *arg)
1079 jack_error(
"You cannot set callbacks on an active client");
1082 GetClientControl()->fCallback[kSampleRateCallback] = (callback != NULL);
1083 fSampleRateArg = arg;
1084 fSampleRate = callback;
1087 callback(GetEngineControl()->fSampleRate, arg);
1093 int JackClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback,
void* arg)
1096 jack_error(
"You cannot set callbacks on an active client");
1100 fClientRegistrationArg = arg;
1101 fClientRegistration = callback;
1106 int JackClient::SetFreewheelCallback(JackFreewheelCallback callback,
void *arg)
1109 jack_error(
"You cannot set callbacks on an active client");
1112 GetClientControl()->fCallback[kStartFreewheelCallback] = (callback != NULL);
1113 GetClientControl()->fCallback[kStopFreewheelCallback] = (callback != NULL);
1114 fFreewheelArg = arg;
1115 fFreewheel = callback;
1120 int JackClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback,
void *arg)
1123 jack_error(
"You cannot set callbacks on an active client");
1126 GetClientControl()->fCallback[kPortRegistrationOnCallback] = (callback != NULL);
1127 GetClientControl()->fCallback[kPortRegistrationOffCallback] = (callback != NULL);
1128 fPortRegistrationArg = arg;
1129 fPortRegistration = callback;
1134 int JackClient::SetPortConnectCallback(JackPortConnectCallback callback,
void *arg)
1137 jack_error(
"You cannot set callbacks on an active client");
1140 GetClientControl()->fCallback[kPortConnectCallback] = (callback != NULL);
1141 GetClientControl()->fCallback[kPortDisconnectCallback] = (callback != NULL);
1142 fPortConnectArg = arg;
1143 fPortConnect = callback;
1148 int JackClient::SetPortRenameCallback(JackPortRenameCallback callback,
void *arg)
1151 jack_error(
"You cannot set callbacks on an active client");
1154 GetClientControl()->fCallback[kPortRenameCallback] = (callback != NULL);
1155 fPortRenameArg = arg;
1156 fPortRename = callback;
1161 int JackClient::SetProcessThread(JackThreadCallback fun,
void *arg)
1164 jack_error(
"You cannot set callbacks on an active client");
1166 }
else if (fProcess) {
1167 jack_error(
"A process callback has already been setup, both models cannot be used at the same time!");
1171 fThreadFunArg = arg;
1179 jack_error(
"You cannot set callbacks on an active client");
1182 GetClientControl()->fCallback[kSessionCallback] = (callback != NULL);
1184 fSession = callback;
1189 int JackClient::SetLatencyCallback(JackLatencyCallback callback,
void *arg)
1192 jack_error(
"You cannot set callbacks on an active client");
1197 fLatency = callback;
1205 jack_error(
"You cannot set callbacks on an active client");
1208 fPropertyChangeArg = arg;
1209 fPropertyChange = callback;
1218 char* JackClient::GetInternalClientName(
int ref)
1220 char name_res[JACK_CLIENT_NAME_SIZE+1];
1222 fChannel->GetInternalClientName(GetClientControl()->fRefNum, ref, name_res, &result);
1223 return (result < 0) ? NULL : strdup(name_res);
1226 int JackClient::InternalClientHandle(
const char* client_name, jack_status_t* status)
1228 int int_ref, result = -1;
1229 fChannel->InternalClientHandle(GetClientControl()->fRefNum, client_name, (
int*)status, &int_ref, &result);
1233 int JackClient::InternalClientLoad(
const char* client_name, jack_options_t options, jack_status_t* status,
jack_varargs_t* va)
1235 if (strlen(client_name) >= JACK_CLIENT_NAME_SIZE) {
1236 jack_error (
"\"%s\" is too long for a JACK client name.\n"
1237 "Please use %lu characters or less.",
1238 client_name, JACK_CLIENT_NAME_SIZE);
1242 if (va->load_name && (strlen(va->load_name) >= JACK_PATH_MAX)) {
1243 jack_error(
"\"%s\" is too long for a shared object name.\n"
1244 "Please use %lu characters or less.",
1245 va->load_name, JACK_PATH_MAX);
1246 int my_status1 = *status | (JackFailure | JackInvalidOption);
1247 *status = (jack_status_t)my_status1;
1251 if (va->load_init && (strlen(va->load_init) >= JACK_LOAD_INIT_LIMIT)) {
1252 jack_error (
"\"%s\" is too long for internal client init "
1253 "string.\nPlease use %lu characters or less.",
1254 va->load_init, JACK_LOAD_INIT_LIMIT);
1255 int my_status1 = *status | (JackFailure | JackInvalidOption);
1256 *status = (jack_status_t)my_status1;
1260 int int_ref, result = -1;
1261 fChannel->InternalClientLoad(GetClientControl()->fRefNum, client_name, va->load_name, va->load_init, options, (
int*)status, &int_ref, -1, &result);
1265 void JackClient::InternalClientUnload(
int ref, jack_status_t* status)
1268 fChannel->InternalClientUnload(GetClientControl()->fRefNum, ref, (
int*)status, &result);
1275 jack_session_command_t* JackClient::SessionNotify(
const char* target, jack_session_event_type_t type,
const char* path)
1278 fChannel->SessionNotify(GetClientControl()->fRefNum, target, type, path, &res);
1285 strncpy(GetClientControl()->fSessionCommand, ev->
command_line,
sizeof(GetClientControl()->fSessionCommand));
1287 GetClientControl()->fSessionCommand[0] =
'\0';
1290 GetClientControl()->fSessionFlags = ev->
flags;
1292 jack_log(
"JackClient::SessionReply... we are here");
1293 if (fChannel->IsChannelThread()) {
1294 jack_log(
"JackClient::SessionReply... in callback reply");
1296 fSessionReply = kImmediateSessionReply;
1300 jack_log(
"JackClient::SessionReply... out of cb");
1303 fChannel->SessionReply(GetClientControl()->fRefNum, &result);
1307 char* JackClient::GetUUIDForClientName(
const char* client_name)
1309 char uuid_res[JACK_UUID_STRING_SIZE];
1311 fChannel->GetUUIDForClientName(GetClientControl()->fRefNum, client_name, uuid_res, &result);
1312 return (result) ? NULL : strdup(uuid_res);
1315 char* JackClient::GetClientNameByUUID(
const char* uuid)
1317 char name_res[JACK_CLIENT_NAME_SIZE + 1];
1319 fChannel->GetClientNameForUUID(GetClientControl()->fRefNum, uuid, name_res, &result);
1320 return (result) ? NULL : strdup(name_res);
1323 int JackClient::ReserveClientName(
const char* client_name,
const char* uuid)
1326 fChannel->ReserveClientName( GetClientControl()->fRefNum, client_name, uuid, &result);
1330 int JackClient::ClientHasSessionCallback(
const char* client_name)
1333 fChannel->ClientHasSessionCallback(client_name, &result);
1341 int JackClient::PropertyChangeNotify(jack_uuid_t subject,
const char* key, jack_property_change_t change)
1344 fChannel->PropertyChangeNotify(subject, key, change, &result);
jack_session_flags_t flags
virtual int Deactivate()
Need to stop thread after deactivating in the server.
virtual int ClientNotifyImp(int refnum, const char *name, int notify, int sync, const char *message, int value1, int value)
Notification received from the server.
SERVER_EXPORT void jack_error(const char *fmt,...)
jack_position_bits_t valid
virtual int Activate()
We need to start thread before activating in the server, otherwise the FW driver connected to the cli...
void SetupDriverSync(bool freewheel)
bool Init()
Called once when the thread starts.
enum JackSessionFlags jack_session_flags_t
jack_session_event_type_t type
SERVER_EXPORT void jack_log(const char *fmt,...)
void(* JackSessionCallback)(jack_session_event_t *event, void *arg)