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);
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)