2 Copyright (C) 2001 Paul Davis
3 Copyright (C) 2004-2008 Grame
5 This program is free software; you can redistribute it and/or modify
6 it under the terms of the GNU Lesser General Public License as published by
7 the Free Software Foundation; either version 2.1 of the License, or
8 (at your option) any later version.
10 This program is distributed in the hope that it will be useful,
11 but WITHOUT ANY WARRANTY; without even the implied warranty of
12 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
13 GNU Lesser General Public License for more details.
15 You should have received a copy of the GNU Lesser General Public License
16 along with this program; if not, write to the Free Software
17 Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
21 #include "JackClient.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
;
64 fGraphOrderArg
= NULL
;
67 fInfoShutdownArg
= NULL
;
69 fBufferSizeArg
= NULL
;
71 fClientRegistrationArg
= NULL
;
72 fPortRegistrationArg
= NULL
;
73 fPortConnectArg
= NULL
;
74 fPortRenameArg
= NULL
;
80 JackClient::~JackClient()
83 int JackClient::Close()
85 jack_log("JackClient::Close ref = %ld", GetClientControl()->fRefNum
);
89 fChannel
->Stop(); // Channels is stopped first to avoid receiving notifications while closing
91 // Request close only if server is still running
92 if (JackGlobals::fServerRunning
) {
93 fChannel
->ClientClose(GetClientControl()->fRefNum
, &result
);
95 jack_log("JackClient::Close server is shutdown");
99 fSynchroTable
[GetClientControl()->fRefNum
].Disconnect();
100 JackGlobals::fClientTable
[GetClientControl()->fRefNum
] = NULL
;
104 bool JackClient::IsActive()
106 return (GetClientControl()) ? GetClientControl()->fActive
: false;
109 pthread_t
JackClient::GetThreadID()
111 return fThread
.GetThreadID();
115 In "async" mode, the server does not synchronize itself on the output drivers, thus it would never "consume" the activations.
116 The synchronization primitives for drivers are setup in "flush" mode that to not keep unneeded activations.
117 Drivers synchro are setup in "flush" mode if server is "async" and NOT freewheel.
119 void JackClient::SetupDriverSync(bool freewheel
)
121 if (!freewheel
&& !GetEngineControl()->fSyncMode
) {
122 jack_log("JackClient::SetupDriverSync driver sem in flush mode");
123 for (int i
= 0; i
< GetEngineControl()->fDriverNum
; i
++) {
124 fSynchroTable
[i
].SetFlush(true);
127 jack_log("JackClient::SetupDriverSync driver sem in normal mode");
128 for (int i
= 0; i
< GetEngineControl()->fDriverNum
; i
++)
129 fSynchroTable
[i
].SetFlush(false);
134 \brief Notification received from the server.
137 int JackClient::ClientNotifyImp(int refnum
, const char* name
, int notify
, int sync
, const char* message
, int value1
, int value2
)
142 int JackClient::ClientNotify(int refnum
, const char* name
, int notify
, int sync
, const char* message
, int value1
, int value2
)
146 // Done all time: redirected on subclass implementation JackLibClient and JackInternalClient
150 res
= ClientNotifyImp(refnum
, name
, notify
, sync
, message
, value1
, value2
);
154 res
= ClientNotifyImp(refnum
, name
, notify
, sync
, message
, value1
, value2
);
157 case kActivateClient
:
158 jack_log("JackClient::kActivateClient name = %s ref = %ld ", name
, refnum
);
164 The current semantic is that notifications can only be received when the client has been activated,
165 although is this implementation, one could imagine calling notifications as soon as the client has be opened.
172 jack_log("JackClient::kAddClient fName = %s name = %s", GetClientControl()->fName
, name
);
173 if (fClientRegistration
&& strcmp(GetClientControl()->fName
, name
) != 0) // Don't call the callback for the registering client itself
174 fClientRegistration(name
, 1, fClientRegistrationArg
);
178 jack_log("JackClient::kRemoveClient fName = %s name = %s", GetClientControl()->fName
, name
);
179 if (fClientRegistration
&& strcmp(GetClientControl()->fName
, name
) != 0) // Don't call the callback for the registering client itself
180 fClientRegistration(name
, 0, fClientRegistrationArg
);
183 case kBufferSizeCallback
:
184 jack_log("JackClient::kBufferSizeCallback buffer_size = %ld", value1
);
186 res
= fBufferSize(value1
, fBufferSizeArg
);
189 case kSampleRateCallback
:
190 jack_log("JackClient::kSampleRateCallback sample_rate = %ld", value1
);
192 res
= fSampleRate(value1
, fSampleRateArg
);
195 case kGraphOrderCallback
:
196 jack_log("JackClient::kGraphOrderCallback");
198 res
= fGraphOrder(fGraphOrderArg
);
201 case kStartFreewheelCallback
:
202 jack_log("JackClient::kStartFreewheel");
203 SetupDriverSync(true);
204 fThread
.DropRealTime();
206 fFreewheel(1, fFreewheelArg
);
209 case kStopFreewheelCallback
:
210 jack_log("JackClient::kStopFreewheel");
211 SetupDriverSync(false);
213 fFreewheel(0, fFreewheelArg
);
214 fThread
.AcquireRealTime();
217 case kPortRegistrationOnCallback
:
218 jack_log("JackClient::kPortRegistrationOn port_index = %ld", value1
);
219 if (fPortRegistration
)
220 fPortRegistration(value1
, 1, fPortRegistrationArg
);
223 case kPortRegistrationOffCallback
:
224 jack_log("JackClient::kPortRegistrationOff port_index = %ld ", value1
);
225 if (fPortRegistration
)
226 fPortRegistration(value1
, 0, fPortRegistrationArg
);
229 case kPortConnectCallback
:
230 jack_log("JackClient::kPortConnectCallback src = %ld dst = %ld", value1
, value2
);
232 fPortConnect(value1
, value2
, 1, fPortConnectArg
);
235 case kPortDisconnectCallback
:
236 jack_log("JackClient::kPortDisconnectCallback src = %ld dst = %ld", value1
, value2
);
238 fPortConnect(value1
, value2
, 0, fPortConnectArg
);
241 case kPortRenameCallback
:
242 jack_log("JackClient::kPortRenameCallback port = %ld");
244 fPortRename(value1
, GetGraphManager()->GetPort(value1
)->GetName(), fPortRenameArg
);
248 jack_log("JackClient::kXRunCallback");
250 res
= fXrun(fXrunArg
);
253 case kShutDownCallback
:
254 jack_log("JackClient::kShutDownCallback");
256 fInfoShutdown(message
, fInfoShutdownArg
);
265 \brief We need to start thread before activating in the server, otherwise the FW driver
266 connected to the client may not be activated.
268 int JackClient::Activate()
270 jack_log("JackClient::Activate");
274 // RT thread is started only when needed...
276 if (StartThread() < 0)
281 Insertion of client in the graph will cause a kGraphOrderCallback notification
282 to be delivered by the server, the client wants to receive it.
284 GetClientControl()->fActive
= true;
286 // Transport related callback become "active"
287 GetClientControl()->fTransportSync
= true;
288 GetClientControl()->fTransportTimebase
= true;
291 GetClientControl()->fCallback
[kRealTimeCallback
] = IsRealTime();
292 fChannel
->ClientActivate(GetClientControl()->fRefNum
, IsRealTime(), &result
);
297 \brief Need to stop thread after deactivating in the server.
299 int JackClient::Deactivate()
301 jack_log("JackClient::Deactivate");
305 GetClientControl()->fActive
= false;
307 // Transport related callback become "unactive"
308 GetClientControl()->fTransportSync
= false;
309 GetClientControl()->fTransportTimebase
= false;
311 // We need to wait for the new engine cycle before stopping the RT thread, but this is done by ClientDeactivate
313 fChannel
->ClientDeactivate(GetClientControl()->fRefNum
, &result
);
314 jack_log("JackClient::Deactivate res = %ld", result
);
316 // RT thread is stopped only when needed...
322 //----------------------
323 // RT thread management
324 //----------------------
327 \brief Called once when the thread starts.
329 bool JackClient::Init()
332 jack_log("JackClient::Init calling client thread init callback");
338 int JackClient::StartThread()
340 jack_log("JackClient::StartThread : period = %ld computation = %ld constraint = %ld",
341 long(int64_t(GetEngineControl()->fPeriod
) / 1000.0f
),
342 long(int64_t(GetEngineControl()->fComputation
) / 1000.0f
),
343 long(int64_t(GetEngineControl()->fConstraint
) / 1000.0f
));
345 // Will do "something" on OSX only...
346 fThread
.SetParams(GetEngineControl()->fPeriod
, GetEngineControl()->fComputation
, GetEngineControl()->fConstraint
);
348 if (fThread
.StartSync() < 0) {
349 jack_error("Start thread error");
353 if (GetEngineControl()->fRealTime
) {
354 if (fThread
.AcquireRealTime(GetEngineControl()->fClientPriority
) < 0) {
355 jack_error("AcquireRealTime error");
366 bool JackClient::Execute()
368 if (!jack_tls_set(JackGlobals::fRealTime
, this))
369 jack_error("failed to set thread realtime key");
371 if (GetEngineControl()->fRealTime
)
372 set_threaded_log_function();
374 // Execute a dummy cycle to be sure thread has the correct properties
378 fThreadFun(fThreadFunArg
);
385 void JackClient::DummyCycle()
391 inline void JackClient::ExecuteThread()
395 CycleSignalAux(CallProcessCallback());
399 inline jack_nframes_t
JackClient::CycleWaitAux()
402 Error(); // Terminates the thread
403 CallSyncCallbackAux();
404 return GetEngineControl()->fBufferSize
;
407 inline void JackClient::CycleSignalAux(int status
)
410 CallTimebaseCallbackAux();
413 End(); // Terminates the thread
416 jack_nframes_t
JackClient::CycleWait()
418 return CycleWaitAux();
421 void JackClient::CycleSignal(int status
)
423 CycleSignalAux(status
);
426 inline int JackClient::CallProcessCallback()
428 return (fProcess
!= NULL
) ? fProcess(GetEngineControl()->fBufferSize
, fProcessArg
) : 0;
431 inline bool JackClient::WaitSync()
433 // Suspend itself: wait on the input synchro
434 if (GetGraphManager()->SuspendRefNum(GetClientControl(), fSynchroTable
, 0x7FFFFFFF) < 0) {
435 jack_error("SuspendRefNum error");
442 inline void JackClient::SignalSync()
444 // Resume: signal output clients connected to the running client
445 if (GetGraphManager()->ResumeRefNum(GetClientControl(), fSynchroTable
) < 0) {
446 jack_error("ResumeRefNum error");
450 inline void JackClient::End()
452 jack_log("JackClient::Execute end name = %s", GetClientControl()->fName
);
453 // Hum... not sure about this, the following "close" code is called in the RT thread...
455 fThread
.DropRealTime();
456 GetClientControl()->fActive
= false;
457 fChannel
->ClientDeactivate(GetClientControl()->fRefNum
, &result
);
461 inline void JackClient::Error()
463 jack_error("JackClient::Execute error name = %s", GetClientControl()->fName
);
464 // Hum... not sure about this, the following "close" code is called in the RT thread...
466 fThread
.DropRealTime();
467 GetClientControl()->fActive
= false;
468 fChannel
->ClientDeactivate(GetClientControl()->fRefNum
, &result
);
477 int JackClient::PortRegister(const char* port_name
, const char* port_type
, unsigned long flags
, unsigned long buffer_size
)
479 // Check if port name is empty
480 string port_name_str
= string(port_name
);
481 if (port_name_str
.size() == 0) {
482 jack_error("port_name is empty");
483 return 0; // Means failure here...
486 // Check port name length
487 string name
= string(GetClientControl()->fName
) + string(":") + port_name_str
;
488 if (name
.size() >= JACK_PORT_NAME_SIZE
) {
489 jack_error("\"%s:%s\" is too long to be used as a JACK port name.\n"
490 "Please use %lu characters or less",
491 GetClientControl()->fName
,
493 JACK_PORT_NAME_SIZE
- 1);
494 return 0; // Means failure here...
498 jack_port_id_t port_index
= NO_PORT
;
499 fChannel
->PortRegister(GetClientControl()->fRefNum
, name
.c_str(), port_type
, flags
, buffer_size
, &port_index
, &result
);
502 jack_log("JackClient::PortRegister ref = %ld name = %s type = %s port_index = %ld", GetClientControl()->fRefNum
, name
.c_str(), port_type
, port_index
);
503 fPortList
.push_back(port_index
);
510 int JackClient::PortUnRegister(jack_port_id_t port_index
)
512 jack_log("JackClient::PortUnRegister port_index = %ld", port_index
);
513 list
<jack_port_id_t
>::iterator it
= find(fPortList
.begin(), fPortList
.end(), port_index
);
515 if (it
!= fPortList
.end()) {
518 fChannel
->PortUnRegister(GetClientControl()->fRefNum
, port_index
, &result
);
521 jack_error("unregistering a port %ld that is not own by the client", port_index
);
526 int JackClient::PortConnect(const char* src
, const char* dst
)
528 jack_log("JackClient::Connect src = %s dst = %s", src
, dst
);
530 fChannel
->PortConnect(GetClientControl()->fRefNum
, src
, dst
, &result
);
534 int JackClient::PortDisconnect(const char* src
, const char* dst
)
536 jack_log("JackClient::Disconnect src = %s dst = %s", src
, dst
);
538 fChannel
->PortDisconnect(GetClientControl()->fRefNum
, src
, dst
, &result
);
542 int JackClient::PortDisconnect(jack_port_id_t src
)
544 jack_log("JackClient::PortDisconnect src = %ld", src
);
546 fChannel
->PortDisconnect(GetClientControl()->fRefNum
, src
, ALL_PORTS
, &result
);
550 int JackClient::PortIsMine(jack_port_id_t port_index
)
552 JackPort
* port
= GetGraphManager()->GetPort(port_index
);
553 return GetClientControl()->fRefNum
== port
->GetRefNum();
556 int JackClient::PortRename(jack_port_id_t port_index
, const char* name
)
559 fChannel
->PortRename(GetClientControl()->fRefNum
, port_index
, name
, &result
);
563 //--------------------
564 // Context management
565 //--------------------
567 int JackClient::SetBufferSize(jack_nframes_t buffer_size
)
570 fChannel
->SetBufferSize(buffer_size
, &result
);
574 int JackClient::SetFreeWheel(int onoff
)
577 fChannel
->SetFreewheel(onoff
, &result
);
583 - from the RT thread when Execute method fails
584 - possibly from a "closed" notification channel
585 (Not needed since the synch object used (Sema of Fifo will fails when server quits... see ShutDown))
588 void JackClient::ShutDown()
590 jack_log("ShutDown");
591 JackGlobals::fServerRunning
= false;
594 fInfoShutdown("JACK server has been closed", fInfoShutdownArg
);
595 fInfoShutdown
= NULL
;
596 } else if (fShutdown
) {
597 fShutdown(fShutdownArg
);
602 //----------------------
603 // Transport management
604 //----------------------
606 inline int JackClient::ActivateAux()
608 // If activated without RT thread...
609 if (IsActive() && fThread
.GetStatus() != JackThread::kRunning
) {
611 jack_log("ActivateAux");
613 // RT thread is started
614 if (StartThread() < 0)
618 GetClientControl()->fCallback
[kRealTimeCallback
] = IsRealTime();
619 fChannel
->ClientActivate(GetClientControl()->fRefNum
, IsRealTime(), &result
);
627 int JackClient::ReleaseTimebase()
630 fChannel
->ReleaseTimebase(GetClientControl()->fRefNum
, &result
);
632 GetClientControl()->fTransportTimebase
= false;
639 /* Call the server if the client is active, otherwise keeps the arguments */
640 int JackClient::SetSyncCallback(JackSyncCallback sync_callback
, void* arg
)
642 GetClientControl()->fTransportSync
= (fSync
!= NULL
);
644 fSync
= sync_callback
;
645 return ActivateAux();
648 int JackClient::SetTimebaseCallback(int conditional
, JackTimebaseCallback timebase_callback
, void* arg
)
651 fChannel
->SetTimebaseCallback(GetClientControl()->fRefNum
, conditional
, &result
);
654 GetClientControl()->fTransportTimebase
= true;
655 fTimebase
= timebase_callback
;
657 return ActivateAux();
665 int JackClient::SetSyncTimeout(jack_time_t timeout
)
667 GetEngineControl()->fTransport
.SetSyncTimeout(timeout
);
673 void JackClient::TransportLocate(jack_nframes_t frame
)
677 pos
.valid
= (jack_position_bits_t
)0;
678 jack_log("TransportLocate pos = %ld", pos
.frame
);
679 GetEngineControl()->fTransport
.RequestNewPos(&pos
);
682 int JackClient::TransportReposition(jack_position_t
* pos
)
684 jack_position_t tmp
= *pos
;
685 jack_log("TransportReposition pos = %ld", pos
->frame
);
686 if (tmp
.valid
& ~JACK_POSITION_MASK
) {
689 GetEngineControl()->fTransport
.RequestNewPos(pos
);
694 jack_transport_state_t
JackClient::TransportQuery(jack_position_t
* pos
)
696 return GetEngineControl()->fTransport
.Query(pos
);
699 jack_nframes_t
JackClient::GetCurrentTransportFrame()
701 return GetEngineControl()->fTransport
.GetCurrentFrame();
704 // Must be RT safe: directly write in the transport shared mem
705 void JackClient::TransportStart()
707 GetEngineControl()->fTransport
.SetCommand(TransportCommandStart
);
710 // Must be RT safe: directly write in the transport shared mem
711 void JackClient::TransportStop()
713 GetEngineControl()->fTransport
.SetCommand(TransportCommandStop
);
716 // Never called concurently with the server
717 // TODO check concurrency with SetSyncCallback
719 void JackClient::CallSyncCallback()
721 CallSyncCallbackAux();
724 inline void JackClient::CallSyncCallbackAux()
726 if (GetClientControl()->fTransportSync
) {
728 JackTransportEngine
& transport
= GetEngineControl()->fTransport
;
729 jack_position_t
* cur_pos
= transport
.ReadCurrentState();
730 jack_transport_state_t transport_state
= transport
.GetState();
733 if (fSync(transport_state
, cur_pos
, fSyncArg
)) {
734 GetClientControl()->fTransportState
= JackTransportRolling
;
735 GetClientControl()->fTransportSync
= false;
738 GetClientControl()->fTransportState
= JackTransportRolling
;
739 GetClientControl()->fTransportSync
= false;
744 void JackClient::CallTimebaseCallback()
746 CallTimebaseCallbackAux();
749 inline void JackClient::CallTimebaseCallbackAux()
751 JackTransportEngine
& transport
= GetEngineControl()->fTransport
;
755 transport
.GetTimebaseMaster(master
, unused
);
757 if (GetClientControl()->fRefNum
== master
&& fTimebase
) { // Client *is* timebase...
759 jack_transport_state_t transport_state
= transport
.GetState();
760 jack_position_t
* cur_pos
= transport
.WriteNextStateStart(1);
762 if (GetClientControl()->fTransportTimebase
) {
763 fTimebase(transport_state
, GetEngineControl()->fBufferSize
, cur_pos
, true, fTimebaseArg
);
764 GetClientControl()->fTransportTimebase
= false; // Callback is called only once with "new_pos" = true
765 } else if (transport_state
== JackTransportRolling
) {
766 fTimebase(transport_state
, GetEngineControl()->fBufferSize
, cur_pos
, false, fTimebaseArg
);
769 transport
.WriteNextStateStop(1);
773 //---------------------
774 // Callback management
775 //---------------------
777 void JackClient::OnShutdown(JackShutdownCallback callback
, void *arg
)
780 jack_error("You cannot set callbacks on an active client");
783 fShutdown
= callback
;
787 void JackClient::OnInfoShutdown(JackInfoShutdownCallback callback
, void *arg
)
790 jack_error("You cannot set callbacks on an active client");
792 fInfoShutdownArg
= arg
;
793 fInfoShutdown
= callback
;
797 int JackClient::SetProcessCallback(JackProcessCallback callback
, void *arg
)
800 jack_error("You cannot set callbacks on an active client");
802 } else if (fThreadFun
) {
803 jack_error ("A thread callback has already been setup, both models cannot be used at the same time!");
812 int JackClient::SetXRunCallback(JackXRunCallback callback
, void *arg
)
815 jack_error("You cannot set callbacks on an active client");
818 GetClientControl()->fCallback
[kXRunCallback
] = (callback
!= NULL
);
825 int JackClient::SetInitCallback(JackThreadInitCallback callback
, void *arg
)
828 jack_error("You cannot set callbacks on an active client");
837 int JackClient::SetGraphOrderCallback(JackGraphOrderCallback callback
, void *arg
)
839 jack_log("SetGraphOrderCallback ");
842 jack_error("You cannot set callbacks on an active client");
845 GetClientControl()->fCallback
[kGraphOrderCallback
] = (callback
!= NULL
);
846 fGraphOrder
= callback
;
847 fGraphOrderArg
= arg
;
852 int JackClient::SetBufferSizeCallback(JackBufferSizeCallback callback
, void *arg
)
855 jack_error("You cannot set callbacks on an active client");
858 GetClientControl()->fCallback
[kBufferSizeCallback
] = (callback
!= NULL
);
859 fBufferSizeArg
= arg
;
860 fBufferSize
= callback
;
865 int JackClient::SetSampleRateCallback(JackSampleRateCallback callback
, void *arg
)
868 jack_error("You cannot set callbacks on an active client");
871 GetClientControl()->fCallback
[kSampleRateCallback
] = (callback
!= NULL
);
872 fSampleRateArg
= arg
;
873 fSampleRate
= callback
;
878 int JackClient::SetClientRegistrationCallback(JackClientRegistrationCallback callback
, void* arg
)
881 jack_error("You cannot set callbacks on an active client");
884 // kAddClient and kRemoveClient notifications must be delivered by the server in any case
885 fClientRegistrationArg
= arg
;
886 fClientRegistration
= callback
;
891 int JackClient::SetFreewheelCallback(JackFreewheelCallback callback
, void *arg
)
894 jack_error("You cannot set callbacks on an active client");
897 GetClientControl()->fCallback
[kStartFreewheelCallback
] = (callback
!= NULL
);
898 GetClientControl()->fCallback
[kStopFreewheelCallback
] = (callback
!= NULL
);
900 fFreewheel
= callback
;
905 int JackClient::SetPortRegistrationCallback(JackPortRegistrationCallback callback
, void *arg
)
908 jack_error("You cannot set callbacks on an active client");
911 GetClientControl()->fCallback
[kPortRegistrationOnCallback
] = (callback
!= NULL
);
912 GetClientControl()->fCallback
[kPortRegistrationOffCallback
] = (callback
!= NULL
);
913 fPortRegistrationArg
= arg
;
914 fPortRegistration
= callback
;
919 int JackClient::SetPortConnectCallback(JackPortConnectCallback callback
, void *arg
)
922 jack_error("You cannot set callbacks on an active client");
925 GetClientControl()->fCallback
[kPortConnectCallback
] = (callback
!= NULL
);
926 GetClientControl()->fCallback
[kPortDisconnectCallback
] = (callback
!= NULL
);
927 fPortConnectArg
= arg
;
928 fPortConnect
= callback
;
933 int JackClient::SetPortRenameCallback(JackPortRenameCallback callback
, void *arg
)
936 jack_error("You cannot set callbacks on an active client");
939 GetClientControl()->fCallback
[kPortRenameCallback
] = (callback
!= NULL
);
940 fPortRenameArg
= arg
;
941 fPortRename
= callback
;
946 int JackClient::SetProcessThread(JackThreadCallback fun
, void *arg
)
949 jack_error("You cannot set callbacks on an active client");
951 } else if (fProcess
) {
952 jack_error ("A process callback has already been setup, both models cannot be used at the same time!");
965 char* JackClient::GetInternalClientName(int ref
)
967 char name_res
[JACK_CLIENT_NAME_SIZE
+ 1];
969 fChannel
->GetInternalClientName(GetClientControl()->fRefNum
, ref
, name_res
, &result
);
974 char* name
= (char*)malloc(strlen(name_res
));
975 strcpy(name
, name_res
);
980 int JackClient::InternalClientHandle(const char* client_name
, jack_status_t
* status
)
982 int int_ref
, result
= -1;
983 fChannel
->InternalClientHandle(GetClientControl()->fRefNum
, client_name
, (int*)status
, &int_ref
, &result
);
987 int JackClient::InternalClientLoad(const char* client_name
, jack_options_t options
, jack_status_t
* status
, jack_varargs_t
* va
)
989 if (strlen(client_name
) >= JACK_CLIENT_NAME_SIZE
) {
990 jack_error ("\"%s\" is too long for a JACK client name.\n"
991 "Please use %lu characters or less.",
992 client_name
, JACK_CLIENT_NAME_SIZE
);
996 if (va
->load_name
&& (strlen(va
->load_name
) >= JACK_PATH_MAX
)) {
997 jack_error("\"%s\" is too long for a shared object name.\n"
998 "Please use %lu characters or less.",
999 va
->load_name
, PATH_MAX
);
1000 int my_status1
= *status
| (JackFailure
| JackInvalidOption
);
1001 *status
= (jack_status_t
)my_status1
;
1005 if (va
->load_init
&& (strlen(va
->load_init
) >= JACK_LOAD_INIT_LIMIT
)) {
1006 jack_error ("\"%s\" is too long for internal client init "
1007 "string.\nPlease use %lu characters or less.",
1008 va
->load_init
, JACK_LOAD_INIT_LIMIT
);
1009 int my_status1
= *status
| (JackFailure
| JackInvalidOption
);
1010 *status
= (jack_status_t
)my_status1
;
1014 int int_ref
, result
= -1;
1015 fChannel
->InternalClientLoad(GetClientControl()->fRefNum
, client_name
, va
->load_name
, va
->load_init
, options
, (int*)status
, &int_ref
, &result
);
1019 void JackClient::InternalClientUnload(int ref
, jack_status_t
* status
)
1022 fChannel
->InternalClientUnload(GetClientControl()->fRefNum
, ref
, (int*)status
, &result
);
1026 } // end of namespace